*** empty log message ***
[luabind.git] / luabind / detail / call.hpp
blob9ec98049b909faabe7295b242874c4642b7400d9
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>
40 #include <luabind/config.hpp>
41 #include <luabind/detail/policy.hpp>
42 #include <luabind/yield_policy.hpp>
45 #define LUABIND_DECL(z, n, text) typedef typename detail::get_policy<n+1,Policies>::type BOOST_PP_CAT(a##n,_policy); \
46 typedef typename BOOST_PP_CAT(a##n,_policy)::head BOOST_PP_CAT(a##n,_converter_intermediate); \
47 typedef typename BOOST_PP_CAT(a##n,_converter_intermediate)::template generate_converter<A##n, lua_to_cpp>::type BOOST_PP_CAT(p##n,_conv);
48 #define LUABIND_PARAMS(z,n,text) BOOST_PP_CAT(p##n,_conv)::apply(L, LUABIND_DECORATE_TYPE(A##n), n + 2)
51 #define LUABIND_DECL(z, n, text) typedef typename find_conversion_policy<n + 1, Policies>::type BOOST_PP_CAT(converter_policy,n); \
52 typename BOOST_PP_CAT(converter_policy,n)::template generate_converter<A##n, lua_to_cpp>::type BOOST_PP_CAT(c,n);
53 //typedef typename BOOST_PP_CAT(converter_policy,n)::template generate_converter<A##n, lua_to_cpp>::type BOOST_PP_CAT(converter,n);
54 //#define LUABIND_PARAMS(z,n,text) BOOST_PP_CAT(converter,n)::apply(L, LUABIND_DECORATE_TYPE(A##n), n + 2)
55 #define LUABIND_ADD_INDEX(z,n,text) + BOOST_PP_CAT(converter_policy,n)::has_arg
56 #define LUABIND_INDEX_MAP(z,n,text) 2 BOOST_PP_REPEAT(n, LUABIND_ADD_INDEX, _)
57 #define LUABIND_PARAMS(z,n,text) BOOST_PP_CAT(c,n).apply(L, LUABIND_DECORATE_TYPE(A##n), LUABIND_INDEX_MAP(_,n,_))
58 #define LUABIND_POSTCALL(z,n,text) BOOST_PP_CAT(c,n).converter_postcall(L, LUABIND_DECORATE_TYPE(A##n), LUABIND_INDEX_MAP(_,n,_));
60 namespace luabind { namespace detail
62 template<class Policies>
63 struct maybe_yield
65 static inline int apply(lua_State* L, int nret)
67 return ret(L, nret, boost::mpl::bool_<has_yield<Policies>::value>());
70 static inline int ret(lua_State* L, int nret, boost::mpl::bool_<true>)
72 return lua_yield(L, nret);
75 static inline int ret(lua_State*, int nret, boost::mpl::bool_<false>)
77 return nret;
81 template<class T>
82 struct returns
84 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 1))
85 #include BOOST_PP_ITERATE()
88 template<>
89 struct returns<void>
91 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 2))
92 #include BOOST_PP_ITERATE()
95 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>, 3))
96 #include BOOST_PP_ITERATE()
99 #undef LUABIND_DECL
100 #undef LUABIND_PARAMS
101 #undef LUABIND_POSTCALL
102 #undef LUABIND_ADD_INDEX
103 #undef LUABIND_INDEX_MAP
105 #endif // LUABIND_CALL_HPP_INCLUDED
107 #elif BOOST_PP_ITERATION_FLAGS() == 1
109 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
110 static int call(T(C::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
112 int nargs = lua_gettop(L);
114 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
115 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
117 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
119 converter_ret.apply(L, (obj->*f)
121 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
124 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
126 int nret = lua_gettop(L) - nargs;
128 const int indices[] =
130 1 /* self */,
131 nargs + nret /* result */
132 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
135 policy_list_postcall<Policies>::apply(L, indices);
137 return maybe_yield<Policies>::apply(L, nret);
138 // return nret;
141 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
142 static int call(T(C::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, C* obj, lua_State* L, const Policies*)
144 int nargs = lua_gettop(L);
145 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
146 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
147 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
148 converter_ret.apply(L, (obj->*f)
150 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
153 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
154 int nret = lua_gettop(L) - nargs;
156 const int indices[] =
158 1 /* self */,
159 nargs + nret /* result */
160 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
163 policy_list_postcall<Policies>::apply(L, indices);
165 // return nret;
166 return maybe_yield<Policies>::apply(L, nret);
169 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
170 static int call(T(*f)(C* obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
172 int nargs = lua_gettop(L);
173 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
174 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
175 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
176 converter_ret.apply(L, f
178 obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
180 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
182 int nret = lua_gettop(L) - nargs;
184 const int indices[] =
186 1 /* self */,
187 nargs + nret /* result */
188 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
191 policy_list_postcall<Policies>::apply(L, indices);
193 // return nret;
194 return maybe_yield<Policies>::apply(L, nret);
197 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
198 static int call(T(*f)(const C* obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
200 int nargs = lua_gettop(L);
201 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
202 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
203 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
204 converter_ret.apply(L, f
206 *obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
208 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
210 int nret = lua_gettop(L) - nargs;
212 const int indices[] =
214 1 /* self */,
215 nargs + nret /* result */
216 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
219 policy_list_postcall<Policies>::apply(L, indices);
221 // return nret;
222 return maybe_yield<Policies>::apply(L, nret);
226 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
227 static int call(T(*f)(C& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
229 int nargs = lua_gettop(L);
230 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
231 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
232 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
233 converter_ret.apply(L, f
235 *obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
237 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
239 int nret = lua_gettop(L) - nargs;
241 const int indices[] =
243 1 /* self */,
244 nargs + nret /* result */
245 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
248 policy_list_postcall<Policies>::apply(L, indices);
250 // return nret;
251 return maybe_yield<Policies>::apply(L, nret);
254 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
255 static int call(T(*f)(const C& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
257 int nargs = lua_gettop(L);
258 typedef typename find_conversion_policy<0, Policies>::type converter_policy_ret;
259 typename converter_policy_ret::template generate_converter<T, cpp_to_lua>::type converter_ret;
260 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
261 converter_ret.apply(L, f
263 *obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
265 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
267 int nret = lua_gettop(L) - nargs;
269 const int indices[] =
271 1 /* self */,
272 nargs + nret /* result */
273 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
276 policy_list_postcall<Policies>::apply(L, indices);
278 // return nret;
279 return maybe_yield<Policies>::apply(L, nret);
282 #elif BOOST_PP_ITERATION_FLAGS() == 2
284 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
285 static int call(void(C::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
287 int nargs = lua_gettop(L);
288 L = L; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
289 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
290 (obj->*f)
292 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
294 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
296 int nret = lua_gettop(L) - nargs;
298 const int indices[] =
300 1 /* self */,
301 nargs + nret /* result */
302 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
305 policy_list_postcall<Policies>::apply(L, indices);
307 // return nret;
308 return maybe_yield<Policies>::apply(L, nret);
311 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
312 static int call(void(C::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, C* obj, lua_State* L, const Policies*)
314 int nargs = lua_gettop(L);
315 L = L; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
316 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
317 (obj->*f)
319 BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
321 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
323 int nret = lua_gettop(L) - nargs;
325 const int indices[] =
327 1 /* self */,
328 nargs + nret /* result */
329 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
332 policy_list_postcall<Policies>::apply(L, indices);
334 // return nret;
335 return maybe_yield<Policies>::apply(L, nret);
338 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
339 static int call(void(*f)(C* obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
341 int nargs = lua_gettop(L);
342 L = L; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
343 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
345 obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
348 int nret = lua_gettop(L) - nargs;
350 const int indices[] =
352 1 /* self */,
353 nargs + nret /* result */
354 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
356 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
358 policy_list_postcall<Policies>::apply(L, indices);
360 // return nret;
361 return maybe_yield<Policies>::apply(L, nret);
364 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
365 static int call(void(*f)(C& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
367 int nargs = lua_gettop(L);
368 L = L; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
369 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
371 *obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
374 int nret = lua_gettop(L) - nargs;
376 const int indices[] =
378 1 /* self */,
379 nargs + nret /* result */
380 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
382 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
384 policy_list_postcall<Policies>::apply(L, indices);
386 // return nret;
387 return maybe_yield<Policies>::apply(L, nret);
390 template<class C, class Policies BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
391 static int call(void(*f)(const C& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), C* obj, lua_State* L, const Policies*)
393 int nargs = lua_gettop(L);
394 L = L; // L is used, but metrowerks compiler seem to warn about it before expanding the macros
395 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_DECL, _)
397 *obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_PARAMS, _)
399 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_POSTCALL, _)
401 int nret = lua_gettop(L) - nargs;
403 const int indices[] =
405 1 /* self */,
406 nargs + nret /* result */
407 BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), LUABIND_INDEX_MAP, _)
410 policy_list_postcall<Policies>::apply(L, indices);
412 // return nret;
413 return maybe_yield<Policies>::apply(L, nret);
416 #elif BOOST_PP_ITERATION_FLAGS() == 3
418 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
419 int call(R(*f)(T& BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), T* obj, lua_State* L, const Policies* policies)
421 return returns<R>::call(f, obj, L, policies);
424 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
425 int call(R(*f)(const T& BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), T* obj, lua_State* L, const Policies* policies)
427 return returns<R>::call(f, obj, L, policies);
430 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
431 int call(R(*f)(T* BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), T* obj, lua_State* L, const Policies* policies)
433 return returns<R>::call(f, obj, L, policies);
436 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
437 int call(R(*f)(const T* BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), T* obj, lua_State* L, const Policies* policies)
439 return returns<R>::call(f, obj, L, policies);
442 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
443 int call(R(T::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), T* obj, lua_State* L, const Policies* policies)
445 return returns<R>::call(f, obj, L, policies);
448 template<class T, class Policies, class R BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
449 int call(R(T::*f)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)) const, T* obj, lua_State* L, const Policies* policies)
451 return returns<R>::call(f, obj, L, policies);
454 #endif