Made it work on VC6.5 again. This involves changing generate_converter
[luabind.git] / luabind / detail / signature_match.hpp
blobacae194435b141802327628959bbacf66bd0db63
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_SIGNATURE_MATCH_HPP_INCLUDED
27 #define LUABIND_SIGNATURE_MATCH_HPP_INCLUDED
29 #include <luabind/config.hpp>
31 #include <boost/config.hpp>
32 #include <boost/preprocessor/repeat.hpp>
33 #include <boost/preprocessor/iteration/iterate.hpp>
34 #include <boost/preprocessor/repetition/enum.hpp>
35 #include <boost/preprocessor/repetition/enum_params.hpp>
36 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
37 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
38 #include <boost/preprocessor/punctuation/comma_if.hpp>
39 #include <boost/preprocessor/cat.hpp>
41 #include <boost/mpl/vector.hpp>
42 #include <boost/mpl/for_each.hpp>
43 #include <boost/mpl/size.hpp>
44 #include <boost/mpl/int.hpp>
45 #include <boost/type_traits.hpp>
47 #include <luabind/detail/policy.hpp>
48 #include <luabind/detail/primitives.hpp>
49 #include <luabind/detail/object_rep.hpp>
50 #include <luabind/detail/class_rep.hpp>
51 #include <luabind/detail/most_derived.hpp>
53 namespace luabind
56 namespace detail
58 template<class A>
59 struct constructor_arity_helper
61 BOOST_STATIC_CONSTANT(int, value = 1);
64 template<>
65 struct constructor_arity_helper<luabind::detail::null_type>
67 BOOST_STATIC_CONSTANT(int, value = 0);
72 #define LUABIND_SUM(z, n, _) detail::constructor_arity_helper<A##n >::value +
74 template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(LUABIND_MAX_ARITY, class A, detail::null_type)>
75 struct constructor
77 BOOST_STATIC_CONSTANT(int, arity = BOOST_PP_REPEAT(LUABIND_MAX_ARITY, LUABIND_SUM, _) 0);
80 #undef LUABIND_SUM
83 namespace luabind { namespace detail
85 #define LUABIND_MATCH_DECL(Z, N,_) \
86 typedef typename find_conversion_policy< \
87 N + 1 \
88 , Policies \
89 >::type BOOST_PP_CAT(converter_policy, N); \
91 typedef typename mpl::apply_wrap2< \
92 BOOST_PP_CAT(converter_policy, N), BOOST_PP_CAT(A, N), lua_to_cpp \
93 >::type BOOST_PP_CAT(converter, N); \
95 int BOOST_PP_CAT(r, N) = BOOST_PP_CAT(converter, N)::match( \
96 L \
97 , LUABIND_DECORATE_TYPE(BOOST_PP_CAT(A, N)) \
98 , start_index + current_index \
99 ); \
101 current_index += BOOST_PP_CAT(converter_policy, N)::has_arg; \
103 if (BOOST_PP_CAT(r, N) < 0) return -1; \
104 else m += BOOST_PP_CAT(r, N);
106 template<int N> struct match_constructor;
108 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/signature_match.hpp>, 2))
109 #include BOOST_PP_ITERATE()
111 #undef LUABIND_MATCH_DECL
113 // this is a function that checks if the lua stack (starting at the given start_index) matches
114 // the types in the constructor type given as 3:rd parameter. It uses the Policies given as
115 // 4:th parameter to do the matching. It returns the total number of cast-steps that needs to
116 // be taken in order to match the parameters on the lua stack to the given parameter-list. Or,
117 // if the parameter doesn't match, it returns -1.
118 template<
119 BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)
120 , class Policies
122 int match_params(
123 lua_State* L
124 , int start_index
125 , const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>* c
126 , const Policies* p)
128 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig_t;
129 return match_constructor<sig_t::arity>::apply(
130 L, start_index, c, p);
133 template<class Sig, int StartIndex, class Policies>
134 struct constructor_match
136 inline static int apply(lua_State* L)
138 int top = lua_gettop(L) - StartIndex + 1;
139 if (top != Sig::arity) return -1;
141 return match_params(L, StartIndex, (Sig*)0, (Policies*)0);
144 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/detail/signature_match.hpp>, 1))
145 #include BOOST_PP_ITERATE()
149 #endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED
151 #elif BOOST_PP_ITERATION_FLAGS() == 1
153 #define N BOOST_PP_ITERATION()
155 // non-const non-member function this as a pointer
156 template<
157 class WrappedClass
158 , class Policies
159 , class R
160 BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
161 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)
163 int match(R(*)(
164 BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A))
165 , lua_State* L
166 , WrappedClass*
167 , Policies const*)
169 typedef constructor<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)> ParameterTypes;
170 return match_params(
171 L, 1, (ParameterTypes*)0, (Policies*)0);
174 # if (BOOST_PP_ITERATION() < (LUABIND_MAX_ARITY - 1))
176 // non-const member function
177 template<
178 class T
179 , class WrappedClass
180 , class Policies
181 , class R
182 BOOST_PP_COMMA_IF(N)
183 BOOST_PP_ENUM_PARAMS(N, class A)
185 int match(
186 R(T::*)(BOOST_PP_ENUM_PARAMS(N, A))
187 , lua_State* L
188 , WrappedClass*
189 , Policies const*)
191 typedef constructor<
192 BOOST_DEDUCED_TYPENAME most_derived<T,WrappedClass>::type&
193 BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
194 > params_t;
196 return match_params(
197 L, 1, (params_t*)0, (Policies*)0);
200 // const member function
201 template<
202 class T
203 , class WrappedClass
204 , class Policies
205 , class R
206 BOOST_PP_COMMA_IF(N)
207 BOOST_PP_ENUM_PARAMS(N, class A)
209 int match(
210 R(T::*)(BOOST_PP_ENUM_PARAMS(N, A)) const
211 , lua_State* L
212 , WrappedClass*
213 , Policies const* policies)
215 typedef constructor<
216 BOOST_DEDUCED_TYPENAME most_derived<T,WrappedClass>::type const&
217 BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
218 > params_t;
219 return match_params(
220 L, 1, (params_t*)0, (Policies*)0);
223 # endif
225 #undef N
227 #elif BOOST_PP_ITERATION_FLAGS() == 2
229 #define N BOOST_PP_ITERATION()
231 template<>
232 struct match_constructor<N>
234 template<
235 BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)
236 , class Policies
238 static int apply(
239 lua_State* L
240 , int start_index
241 , const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*
242 , const Policies*)
244 int m = 0;
245 #if N
246 int current_index = 0;
247 #endif
248 // Removes unreferenced local variable warning on VC7.
249 (void)start_index;
250 (void)L;
252 BOOST_PP_REPEAT(N, LUABIND_MATCH_DECL, _)
253 return m;
257 #undef N
259 #endif