1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
24 #if !BOOST_PP_IS_ITERATING
26 #ifndef LUABIND_CALL_HPP_INCLUDED
27 #define LUABIND_CALL_HPP_INCLUDED
29 #include <boost/config.hpp>
30 #include <boost/preprocessor/repeat.hpp>
31 #include <boost/preprocessor/iteration/iterate.hpp>
32 #include <boost/preprocessor/repetition/enum.hpp>
33 #include <boost/preprocessor/repetition/enum_params.hpp>
34 #include <boost/preprocessor/repetition/enum_trailing.hpp>
35 #include <boost/preprocessor/repetition/repeat.hpp>
36 #include <boost/preprocessor/punctuation/comma_if.hpp>
37 #include <boost/preprocessor/cat.hpp>
38 #include <boost/mpl/bool.hpp>
39 #include <boost/mpl/apply_wrap.hpp>
41 #include <luabind/config.hpp>
42 #include <luabind/detail/policy.hpp>
43 #include <luabind/yield_policy.hpp>
45 #include <luabind/detail/most_derived.hpp>
47 #define LUABIND_DECL(z, n, off) \
48 typedef typename find_conversion_policy< \
51 >::type BOOST_PP_CAT(converter_policy,n); \
53 typename mpl::apply_wrap2< \
54 BOOST_PP_CAT(converter_policy,n), BOOST_PP_CAT(A,n), lua_to_cpp \
55 >::type BOOST_PP_CAT(c,n);
57 #define LUABIND_ADD_INDEX(z,n,text) \
58 + BOOST_PP_CAT(converter_policy,n)::has_arg
60 #define LUABIND_INDEX_MAP(z,n,text) \
61 text BOOST_PP_REPEAT(n, LUABIND_ADD_INDEX, _)
63 #define LUABIND_PARAMS(z,n,text) \
64 BOOST_PP_CAT(c,n).apply( \
66 , LUABIND_DECORATE_TYPE(A##n) \
67 , LUABIND_INDEX_MAP(_,n,text) \
70 #define LUABIND_POSTCALL(z,n,text) \
71 BOOST_PP_CAT(c,n).converter_postcall( \
73 , LUABIND_DECORATE_TYPE(A##n) \
74 , LUABIND_INDEX_MAP(_,n,text) \
77 namespace luabind
{ namespace detail
80 namespace mpl
= boost::mpl
;
82 template<class Policies
>
85 static inline int apply(lua_State
* L
, int nret
)
87 return ret(L
, nret
, boost::mpl::bool_
<has_yield
<Policies
>::value
>());
90 static inline int ret(lua_State
* L
, int nret
, boost::mpl::bool_
<true>)
92 return lua_yield(L
, nret
);
95 static inline int ret(lua_State
*, int nret
, boost::mpl::bool_
<false>)
104 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 1))
105 #include BOOST_PP_ITERATE()
111 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 2))
112 #include BOOST_PP_ITERATE()
115 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 3))
116 #include BOOST_PP_ITERATE()
120 #undef LUABIND_PARAMS
121 #undef LUABIND_POSTCALL
122 #undef LUABIND_ADD_INDEX
123 #undef LUABIND_INDEX_MAP
125 #endif // LUABIND_CALL_HPP_INCLUDED
127 #elif BOOST_PP_ITERATION_FLAGS() == 1
133 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
134 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
137 T(C::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
142 int nargs
= lua_gettop(L
);
144 typedef typename most_derived
<C
, WrappedClass
>::type self_type
;
145 pointer_converter
<lua_to_cpp
> self_cv
;
147 typedef typename find_conversion_policy
<0, Policies
>::type converter_policy_ret
;
148 typename
mpl::apply_wrap2
<converter_policy_ret
,T
,cpp_to_lua
>::type converter_ret
;
150 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 2)
154 , (self_cv
.apply(L
, LUABIND_DECORATE_TYPE(self_type
*), 1)->*f
)
156 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 2)
159 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 2)
161 int nret
= lua_gettop(L
) - nargs
;
163 const int indices
[] =
165 nargs
+ nret
// result
167 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 2)
170 policy_list_postcall
<Policies
>::apply(L
, indices
);
172 return maybe_yield
<Policies
>::apply(L
, nret
);
179 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
180 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
183 T(C::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
)) const
188 int nargs
= lua_gettop(L
);
190 typedef typename most_derived
<C
, WrappedClass
>::type self_type
;
191 const_pointer_converter
<lua_to_cpp
> self_cv
;
193 typedef typename find_conversion_policy
<0, Policies
>::type converter_policy_ret
;
194 typename
mpl::apply_wrap2
<converter_policy_ret
,T
,cpp_to_lua
>::type converter_ret
;
196 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 2)
200 , (self_cv
.apply(L
, LUABIND_DECORATE_TYPE(self_type
const*), 1)->*f
)
202 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 2)
205 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 2)
206 int nret
= lua_gettop(L
) - nargs
;
208 const int indices
[] =
210 nargs
+ nret
// result
212 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 2)
215 policy_list_postcall
<Policies
>::apply(L
, indices
);
217 return maybe_yield
<Policies
>::apply(L
, nret
);
223 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
224 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
227 T(*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
232 int nargs
= lua_gettop(L
);
233 typedef typename find_conversion_policy
<0, Policies
>::type converter_policy_ret
;
234 typename
mpl::apply_wrap2
<converter_policy_ret
,T
,cpp_to_lua
>::type converter_ret
;
235 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 1)
236 converter_ret
.apply(L
, f
238 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 1)
241 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 1)
243 int nret
= lua_gettop(L
) - nargs
;
245 const int indices
[] =
247 nargs
+ nret
// result
248 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 1)
251 policy_list_postcall
<Policies
>::apply(L
, indices
);
253 return maybe_yield
<Policies
>::apply(L
, nret
);
256 #elif BOOST_PP_ITERATION_FLAGS() == 2
262 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
263 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
266 void(C::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
271 int nargs
= lua_gettop(L
);
272 L
= L
; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
274 typedef typename most_derived
<C
, WrappedClass
>::type self_type
;
275 pointer_converter
<lua_to_cpp
> self_cv
;
277 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 2)
278 (self_cv
.apply(L
, LUABIND_DECORATE_TYPE(self_type
*), 1)->*f
)
280 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 2)
282 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 2)
284 int nret
= lua_gettop(L
) - nargs
;
286 const int indices
[] =
288 nargs
+ nret
// result
290 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 2)
293 policy_list_postcall
<Policies
>::apply(L
, indices
);
295 return maybe_yield
<Policies
>::apply(L
, nret
);
302 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
303 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
306 void(C::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
)) const
311 int nargs
= lua_gettop(L
);
312 L
= L
; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
314 typedef typename most_derived
<C
, WrappedClass
>::type self_type
;
315 const_pointer_converter
<lua_to_cpp
> self_cv
;
317 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 2)
318 (self_cv
.apply(L
, LUABIND_DECORATE_TYPE(self_type
const*), 1)->*f
)
320 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 2)
322 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 2)
324 int nret
= lua_gettop(L
) - nargs
;
326 const int indices
[] =
328 nargs
+ nret
// result
330 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 2)
333 policy_list_postcall
<Policies
>::apply(L
, indices
);
335 return maybe_yield
<Policies
>::apply(L
, nret
);
341 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
342 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
345 void(*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
350 int nargs
= lua_gettop(L
);
351 L
= L
; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
352 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL
, 1)
354 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS
, 1)
357 int nret
= lua_gettop(L
) - nargs
;
359 const int indices
[] =
361 nargs
+ nret
/* result */
362 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP
, 1)
364 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL
, 1)
366 policy_list_postcall
<Policies
>::apply(L
, indices
);
368 return maybe_yield
<Policies
>::apply(L
, nret
);
371 #elif BOOST_PP_ITERATION_FLAGS() == 3
377 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
378 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
381 R(*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
386 return returns
<R
>::call(f
, (WrappedClass
*)0, L
, (Policies
*)0);
394 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
395 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
398 R(T::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
))
403 return returns
<R
>::call(f
, (WrappedClass
*)0, L
, (Policies
*)0);
411 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
412 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)
415 R(T::*f
)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A
)) const
420 return returns
<R
>::call(f
, (WrappedClass
*)0, L
, (Policies
*)0);