1 // Copyright Daniel Wallin 2008. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #if !BOOST_PP_IS_ITERATING
7 # ifndef LUABIND_CALL2_080911_HPP
8 # define LUABIND_CALL2_080911_HPP
10 # include <boost/mpl/apply_wrap.hpp>
11 # include <boost/mpl/begin_end.hpp>
12 # include <boost/mpl/deref.hpp>
13 # include <boost/mpl/front.hpp>
14 # include <boost/mpl/long.hpp>
15 # include <boost/mpl/size.hpp>
16 # include <boost/preprocessor/control/if.hpp>
17 # include <boost/preprocessor/iteration/iterate.hpp>
18 # include <boost/preprocessor/iteration/local.hpp>
19 # include <boost/preprocessor/repetition/enum.hpp>
20 # include <boost/preprocessor/repetition/enum_trailing_params.hpp>
21 # include <boost/type_traits/is_void.hpp>
23 # include <luabind/config.hpp>
24 # include <luabind/detail/policy.hpp>
25 # include <luabind/yield_policy.hpp>
27 namespace luabind { namespace detail {
29 template <class F, class Signature, class Policies, class IsVoid>
31 lua_State* L, F const& f, Signature
32 , Policies const& policies, IsVoid, mpl::true_)
35 L, f, Signature(), policies
36 , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
40 template <class F, class Signature, class Policies, class IsVoid>
42 lua_State* L, F const& f, Signature
43 , Policies const& policies, IsVoid, mpl::false_)
46 L, f, Signature(), policies
47 , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
51 template <class F, class Signature, class Policies>
52 int invoke(lua_State* L, F const& f, Signature, Policies const& policies)
55 L, f, Signature(), policies
56 , boost::is_void<typename mpl::front<Signature>::type>()
57 , boost::is_member_function_pointer<F>()
61 inline int maybe_yield_aux(lua_State*, int results, mpl::false_)
66 inline int maybe_yield_aux(lua_State* L, int results, mpl::true_)
68 return lua_yield(L, results);
71 template <class Policies>
72 int maybe_yield(lua_State* L, int results, Policies*)
74 return maybe_yield_aux(
75 L, results, mpl::bool_<has_yield<Policies>::value>());
78 # define LUABIND_INVOKE_NEXT_ITER(n) \
81 n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \
84 # define LUABIND_INVOKE_NEXT_INDEX(n) \
87 , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \
88 (BOOST_PP_CAT(p,BOOST_PP_DEC(n))::has_arg ? 1 : 0) \
92 # define LUABIND_INVOKE_DECLARE_CONVERTER(n) \
93 typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \
94 typedef typename mpl::deref<BOOST_PP_CAT(iter,n)>::type \
96 typedef typename find_conversion_policy<n + 1, Policies>::type \
98 typename mpl::apply_wrap2< \
99 BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \
100 int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n);
102 # define LUABIND_INVOKE_ARG(z, n, base) \
103 BOOST_PP_CAT(c,base(n)).apply( \
104 L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n)))
106 # define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \
107 BOOST_PP_CAT(c,n).converter_postcall( \
108 L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n));
110 # define BOOST_PP_ITERATION_PARAMS_1 \
111 (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
112 # include BOOST_PP_ITERATE()
114 # define LUABIND_INVOKE_VOID
115 # define BOOST_PP_ITERATION_PARAMS_1 \
116 (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
117 # include BOOST_PP_ITERATE()
119 # undef LUABIND_INVOKE_VOID
120 # define LUABIND_INVOKE_MEMBER
121 # define BOOST_PP_ITERATION_PARAMS_1 \
122 (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
123 # include BOOST_PP_ITERATE()
125 # define LUABIND_INVOKE_VOID
126 # define BOOST_PP_ITERATION_PARAMS_1 \
127 (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
128 # include BOOST_PP_ITERATE()
130 }} // namespace luabind::detail
132 # endif // LUABIND_CALL2_080911_HPP
134 #else // BOOST_PP_IS_ITERATING
136 # ifdef LUABIND_INVOKE_MEMBER
137 # define N BOOST_PP_INC(BOOST_PP_ITERATION())
139 # define N BOOST_PP_ITERATION()
142 template <class F, class Signature, class Policies>
144 # ifdef LUABIND_INVOKE_MEMBER
150 lua_State* L, F const& f, Signature, Policies const&, mpl::long_<N>
151 # ifdef LUABIND_INVOKE_VOID
158 typedef typename mpl::begin<Signature>::type first;
159 # ifndef LUABIND_INVOKE_VOID
160 typedef typename mpl::deref<first>::type result_type;
161 typedef typename find_conversion_policy<0, Policies>::type result_policy;
162 typename mpl::apply_wrap2<
163 result_policy, result_type, cpp_to_lua>::type result_converter;
167 # define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n)
168 # define BOOST_PP_LOCAL_LIMITS (0,N-1)
169 # include BOOST_PP_LOCAL_ITERATE()
172 int const arguments = lua_gettop(L);
174 # ifndef LUABIND_INVOKE_VOID
175 result_converter.apply(
178 # ifdef LUABIND_INVOKE_MEMBER
179 (c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)(
180 BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC)
183 # define LUABIND_INVOKE_IDENTITY(x) x
185 BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY)
187 # undef LUABIND_INVOKE_IDENTITY
189 # ifndef LUABIND_INVOKE_VOID
195 # define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n)
196 # define BOOST_PP_LOCAL_LIMITS (0,N-1)
197 # include BOOST_PP_LOCAL_ITERATE()
200 int const results = lua_gettop(L) - arguments;
202 int const indices[] = {
203 arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index)
206 policy_list_postcall<Policies>::apply(L, indices);
208 return maybe_yield(L, results, (Policies*)0);