OSDN Git Service

build moflib1.0 on cmake-base system
[moflib/moflib.git] / moflib-1.0 / extlib / luabind-0.8 / luabind / detail / call.hpp
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)
4
5 #if !BOOST_PP_IS_ITERATING
6
7 # ifndef LUABIND_CALL2_080911_HPP
8 #  define LUABIND_CALL2_080911_HPP
9
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>
22
23 #  include <luabind/config.hpp>
24 #  include <luabind/detail/policy.hpp>
25 #  include <luabind/yield_policy.hpp>
26
27 namespace luabind { namespace detail {
28
29 template <class F, class Signature, class Policies, class IsVoid>
30 int invoke0(
31     lua_State* L, F const& f, Signature
32   , Policies const& policies, IsVoid, mpl::true_)
33 {
34     return invoke_member(
35         L, f, Signature(), policies
36       , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
37     );
38 }
39
40 template <class F, class Signature, class Policies, class IsVoid>
41 int invoke0(
42     lua_State* L, F const& f, Signature
43   , Policies const& policies, IsVoid, mpl::false_)
44 {
45     return invoke_normal(
46         L, f, Signature(), policies
47       , mpl::long_<mpl::size<Signature>::value - 1>(), IsVoid()
48     );
49 }
50
51 template <class F, class Signature, class Policies>
52 int invoke(lua_State* L, F const& f, Signature, Policies const& policies)
53 {
54     return invoke0(
55         L, f, Signature(), policies
56       , boost::is_void<typename mpl::front<Signature>::type>()
57       , boost::is_member_function_pointer<F>()
58    );
59 }
60
61 inline int maybe_yield_aux(lua_State*, int results, mpl::false_)
62 {
63     return results;
64 }
65
66 inline int maybe_yield_aux(lua_State* L, int results, mpl::true_)
67 {
68     return lua_yield(L, results);
69 }
70
71 template <class Policies>
72 int maybe_yield(lua_State* L, int results, Policies*)
73 {
74     return maybe_yield_aux(
75         L, results, mpl::bool_<has_yield<Policies>::value>());
76 }
77
78 #  define LUABIND_INVOKE_NEXT_ITER(n) \
79     typename mpl::next< \
80         BOOST_PP_IF( \
81             n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \
82     >::type
83
84 #  define LUABIND_INVOKE_NEXT_INDEX(n) \
85     BOOST_PP_IF( \
86         n \
87       , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \
88             (BOOST_PP_CAT(p,BOOST_PP_DEC(n))::has_arg ? 1 : 0) \
89       , 1 \
90     )
91
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 \
95         BOOST_PP_CAT(a,n); \
96     typedef typename find_conversion_policy<n + 1, Policies>::type \
97         BOOST_PP_CAT(p,n); \
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);
101
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)))
105
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));
109
110 #  define BOOST_PP_ITERATION_PARAMS_1 \
111     (3, (0, LUABIND_MAX_ARITY, <luabind/detail/call.hpp>))
112 #  include BOOST_PP_ITERATE()
113
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()
118
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()
124
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()
129
130 }} // namespace luabind::detail
131
132 # endif // LUABIND_CALL2_080911_HPP
133
134 #else // BOOST_PP_IS_ITERATING
135
136 # ifdef LUABIND_INVOKE_MEMBER
137 #  define N BOOST_PP_INC(BOOST_PP_ITERATION())
138 # else
139 #  define N BOOST_PP_ITERATION()
140 # endif
141
142 template <class F, class Signature, class Policies>
143 int
144 # ifdef LUABIND_INVOKE_MEMBER
145 invoke_member
146 # else
147 invoke_normal
148 # endif
149 (
150     lua_State* L, F const& f, Signature, Policies const&, mpl::long_<N>
151 # ifdef LUABIND_INVOKE_VOID
152   , mpl::true_
153 # else
154   , mpl::false_
155 # endif
156 )
157 {
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;
164 # endif
165
166 # if N > 0
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()
170 # endif
171
172     int const arguments = lua_gettop(L);
173
174 # ifndef LUABIND_INVOKE_VOID
175     result_converter.apply(
176         L,
177 # endif
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)
181         )
182 # else
183 #  define LUABIND_INVOKE_IDENTITY(x) x
184         f(
185             BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY)
186         )
187 #  undef LUABIND_INVOKE_IDENTITY
188 # endif
189 # ifndef LUABIND_INVOKE_VOID
190     )
191 # endif
192     ;
193
194 # if N > 0
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()
198 # endif
199
200     int const results = lua_gettop(L) - arguments;
201
202     int const indices[] = {
203         arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index)
204     };
205
206     policy_list_postcall<Policies>::apply(L, indices);
207
208     return maybe_yield(L, results, (Policies*)0);
209 }
210
211 # undef N
212
213 #endif
214