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 #ifndef LUABIND_POLICY_HPP_INCLUDED
25 #define LUABIND_POLICY_HPP_INCLUDED
27 #include <luabind/config.hpp>
31 #include <boost/type_traits/is_enum.hpp>
32 #include <boost/type_traits/is_array.hpp>
33 #include <boost/mpl/bool.hpp>
34 #include <boost/mpl/integral_c.hpp>
35 #include <boost/mpl/equal_to.hpp>
36 #include <boost/mpl/apply_if.hpp>
37 #include <boost/mpl/or.hpp>
38 #include <boost/type_traits/add_reference.hpp>
39 #include <boost/type_traits/is_pointer.hpp>
40 #include <boost/type_traits/is_base_and_derived.hpp>
41 #include <boost/limits.hpp>
43 #include <luabind/detail/class_registry.hpp>
44 #include <luabind/detail/primitives.hpp>
45 #include <luabind/detail/object_rep.hpp>
46 #include <luabind/detail/typetraits.hpp>
47 #include <luabind/detail/class_cache.hpp>
48 #include <luabind/detail/debug.hpp>
50 #include <boost/type_traits/add_reference.hpp>
52 #include <luabind/detail/decorate_type.hpp>
53 #include <luabind/object.hpp>
54 //#include <luabind/detail/make_instance.hpp>
55 //#include <luabind/pointer_holder.hpp>
61 struct conversion_policy_base
{};
64 template<int N
, bool HasArg
= true>
65 struct conversion_policy
: detail::conversion_policy_base
67 BOOST_STATIC_CONSTANT(int, index
= N
);
68 BOOST_STATIC_CONSTANT(bool, has_arg
= HasArg
);
75 index_map(const int* m
): m_map(m
) {}
77 int operator[](int index
) const
79 return m_map
[index
+ 1];
89 using luabind::detail::yes_t
;
90 using luabind::detail::no_t
;
91 using luabind::detail::by_value
;
92 using luabind::detail::by_reference
;
93 using luabind::detail::by_const_reference
;
94 using luabind::detail::by_pointer
;
95 using luabind::detail::by_const_pointer
;
97 no_t
is_user_defined(...);
99 // template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
100 // template<> struct yes_no<false> : no_t { typedef no_t type; };
102 template<int N, class T>
105 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
107 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
109 return std::make_pair(-1,-1);
113 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
116 no_t is_implicit_conversion(...);
119 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
122 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
125 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
128 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
130 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
136 struct is_user_defined
138 BOOST_STATIC_CONSTANT(bool, value
=
139 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T
))) == sizeof(yes_t
));
143 struct is_implicit_conversion
145 BOOST_STATIC_CONSTANT(bool, value =
146 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
149 LUABIND_API
int implicit_cast(const class_rep
* crep
, LUABIND_TYPE_INFO
const&, int& pointer_offset
);
152 template<class T
> class functor
;
156 namespace luabind
{ namespace detail
162 yes_t
is_lua_functor_test(const functor
<T
>&);
164 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
165 no_t
is_lua_functor_test(...);
168 no_t
is_lua_functor_test(const T
&);
172 struct is_lua_functor
176 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_lua_functor_test(t
)) == sizeof(yes_t
));
181 static char msvc_fix
[64];
188 boost::mpl::if_
<is_primitive
<T
>
190 , typename
boost::mpl::apply_if
<boost::mpl::or_
<boost::is_reference
<T
>, boost::is_pointer
<T
> >
192 , boost::add_reference
<T
>
196 static inline result_type
get()
198 return reinterpret_cast<result_type
>(msvc_fix
);
202 template<class H
, class T
>
209 policy_cons
<U
, policy_cons
<H
,T
> > operator,(policy_cons
<U
,detail::null_type
>)
211 return policy_cons
<U
, policy_cons
<H
,T
> >();
215 policy_cons
<U
, policy_cons
<H
,T
> > operator+(policy_cons
<U
,detail::null_type
>)
217 return policy_cons
<U
, policy_cons
<H
,T
> >();
221 policy_cons
<U
, policy_cons
<H
,T
> > operator|(policy_cons
<U
,detail::null_type
>)
223 return policy_cons
<U
, policy_cons
<H
,T
> >();
227 struct indirection_layer
230 indirection_layer(const T
&);
233 template<class H
, class T
>
234 yes_t
is_policy_cons_test(const policy_cons
<H
,T
>&);
235 no_t
is_policy_cons_test(...);
238 struct is_policy_cons
242 BOOST_STATIC_CONSTANT(bool, value
=
243 sizeof(is_policy_cons_test(t
)) == sizeof(yes_t
));
247 struct is_string_literal
249 static no_t
helper(indirection_layer
);
250 static yes_t
helper(const char*);
254 struct is_string_literal
<false>
256 static no_t
helper(indirection_layer
);
261 struct is_primitive
/*: boost::mpl::bool_c<false>*/
265 BOOST_STATIC_CONSTANT(bool, value
=
266 sizeof(is_string_literal
<boost::is_array
<T
>::value
>::helper(t
)) == sizeof(yes_t
));
269 template<> struct is_primitive
<luabind::object
>: boost::mpl::bool_
<true> {};
270 template<> struct is_primitive
<const luabind::object
>: boost::mpl::bool_
<true> {};
271 template<> struct is_primitive
<const luabind::object
&>: boost::mpl::bool_
<true> {};
273 template<> struct is_primitive
<int>: boost::mpl::bool_
<true> {};
274 template<> struct is_primitive
<char>: boost::mpl::bool_
<true> {};
275 template<> struct is_primitive
<short>: boost::mpl::bool_
<true> {};
276 template<> struct is_primitive
<long>: boost::mpl::bool_
<true> {};
277 template<> struct is_primitive
<unsigned char>: boost::mpl::bool_
<true> {};
278 template<> struct is_primitive
<unsigned short>: boost::mpl::bool_
<true> {};
279 template<> struct is_primitive
<unsigned long>: boost::mpl::bool_
<true> {};
280 template<> struct is_primitive
<unsigned int>: boost::mpl::bool_
<true> {};
281 template<> struct is_primitive
<float>: boost::mpl::bool_
<true> {};
282 template<> struct is_primitive
<double>: boost::mpl::bool_
<true> {};
283 template<> struct is_primitive
<long double>: boost::mpl::bool_
<true> {};
284 template<> struct is_primitive
<char*>: boost::mpl::bool_
<true> {};
285 template<> struct is_primitive
<bool>: boost::mpl::bool_
<true> {};
287 template<> struct is_primitive
<const int>: boost::mpl::bool_
<true> {};
288 template<> struct is_primitive
<const char>: boost::mpl::bool_
<true> {};
289 template<> struct is_primitive
<const short>: boost::mpl::bool_
<true> {};
290 template<> struct is_primitive
<const long>: boost::mpl::bool_
<true> {};
291 template<> struct is_primitive
<const unsigned int>: boost::mpl::bool_
<true> {};
292 template<> struct is_primitive
<const unsigned char>: boost::mpl::bool_
<true> {};
293 template<> struct is_primitive
<const unsigned short>: boost::mpl::bool_
<true> {};
294 template<> struct is_primitive
<const unsigned long>: boost::mpl::bool_
<true> {};
295 template<> struct is_primitive
<const float>: boost::mpl::bool_
<true> {};
296 template<> struct is_primitive
<const double>: boost::mpl::bool_
<true> {};
297 template<> struct is_primitive
<const long double>: boost::mpl::bool_
<true> {};
298 template<> struct is_primitive
<const char*>: boost::mpl::bool_
<true> {};
299 template<> struct is_primitive
<const char* const>: boost::mpl::bool_
<true> {};
300 template<> struct is_primitive
<const bool>: boost::mpl::bool_
<true> {};
303 template<> struct is_primitive
<const int&>: boost::mpl::bool_
<true> {};
304 template<> struct is_primitive
<const char&>: boost::mpl::bool_
<true> {};
305 template<> struct is_primitive
<const short&>: boost::mpl::bool_
<true> {};
306 template<> struct is_primitive
<const long&>: boost::mpl::bool_
<true> {};
307 template<> struct is_primitive
<const unsigned int&>: boost::mpl::bool_
<true> {};
308 template<> struct is_primitive
<const unsigned char&>: boost::mpl::bool_
<true> {};
309 template<> struct is_primitive
<const unsigned short&>: boost::mpl::bool_
<true> {};
310 template<> struct is_primitive
<const unsigned long&>: boost::mpl::bool_
<true> {};
311 template<> struct is_primitive
<const float&>: boost::mpl::bool_
<true> {};
312 template<> struct is_primitive
<const double&>: boost::mpl::bool_
<true> {};
313 template<> struct is_primitive
<const long double&>: boost::mpl::bool_
<true> {};
314 template<> struct is_primitive
<const bool&>: boost::mpl::bool_
<true> {};
316 template<> struct is_primitive
<const std::string
&>: boost::mpl::bool_
<true> {};
317 template<> struct is_primitive
<std::string
>: boost::mpl::bool_
<true> {};
318 template<> struct is_primitive
<const std::string
>: boost::mpl::bool_
<true> {};
321 template<class Direction
> struct primitive_converter
;
324 struct primitive_converter
<cpp_to_lua
>
326 void apply(lua_State
* L
, const luabind::object
& v
)
328 // if the luabind::object is uninitialized
330 if (v
.lua_state() == 0)
335 // if you hit this assert you are trying to return a value from one state into another lua state
336 assert((v
.lua_state() == L
) && "you cannot return an uninitilized value "
337 "or a value from one lua state into another");
340 void apply(lua_State
* L
, int v
) { lua_pushnumber(L
, v
); }
341 void apply(lua_State
* L
, short v
) { lua_pushnumber(L
, v
); }
342 void apply(lua_State
* L
, char v
) { lua_pushnumber(L
, v
); }
343 void apply(lua_State
* L
, long v
) { lua_pushnumber(L
, v
); }
344 void apply(lua_State
* L
, unsigned int v
) { lua_pushnumber(L
, v
); }
345 void apply(lua_State
* L
, unsigned short v
) { lua_pushnumber(L
, v
); }
346 void apply(lua_State
* L
, unsigned char v
) { lua_pushnumber(L
, v
); }
347 void apply(lua_State
* L
, unsigned long v
) { lua_pushnumber(L
, v
); }
348 void apply(lua_State
* L
, float v
) { lua_pushnumber(L
, v
); }
349 void apply(lua_State
* L
, double v
) { lua_pushnumber(L
, v
); }
350 void apply(lua_State
* L
, long double v
) { lua_pushnumber(L
, v
); }
351 void apply(lua_State
* L
, const char* v
) { lua_pushstring(L
, v
); }
352 void apply(lua_State
* L
, const std::string
& v
)
353 { lua_pushlstring(L
, v
.data(), v
.size()); }
354 void apply(lua_State
* L
, bool b
) { lua_pushboolean(L
, b
); }
358 struct primitive_converter
<lua_to_cpp
>
360 #define PRIMITIVE_CONVERTER(prim) \
361 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
362 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
363 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
365 #define PRIMITIVE_MATCHER(prim) \
366 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
367 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
368 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
370 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L
, index
) == 1; }
371 PRIMITIVE_MATCHER(bool) { if (lua_type(L
, index
) == LUA_TBOOLEAN
) return 0; else return -1; }
373 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L
, index
)); }
374 PRIMITIVE_MATCHER(int) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
376 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L
, index
)); }
377 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
379 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L
, index
)); }
380 PRIMITIVE_MATCHER(char) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
382 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L
, index
)); }
383 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
385 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L
, index
)); }
386 PRIMITIVE_MATCHER(short) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
388 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L
, index
)); }
389 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
391 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L
, index
)); }
392 PRIMITIVE_MATCHER(long) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
394 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L
, index
)); }
395 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
397 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L
, index
)); }
398 PRIMITIVE_MATCHER(float) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
400 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L
, index
)); }
401 PRIMITIVE_MATCHER(double) { if (lua_type(L
, index
) == LUA_TNUMBER
) return 0; else return -1; }
403 PRIMITIVE_CONVERTER(std::string
)
404 { return std::string(lua_tostring(L
, index
), lua_strlen(L
, index
)); }
405 PRIMITIVE_MATCHER(std::string
) { if (lua_type(L
, index
) == LUA_TSTRING
) return 0; else return -1; }
407 PRIMITIVE_CONVERTER(luabind::object
)
409 LUABIND_CHECK_STACK(L
);
411 lua_pushvalue(L
, index
);
412 detail::lua_reference ref
;
414 return luabind::object(L
, ref
, true);
417 PRIMITIVE_MATCHER(luabind::object
) { return std::numeric_limits
<int>::max() - 1; }
419 const char* apply(lua_State
* L
, detail::by_const_pointer
<char>, int index
) { return static_cast<const char*>(lua_tostring(L
, index
)); }
420 const char* apply(lua_State
* L
, detail::by_const_pointer
<const char>, int index
) { return static_cast<const char*>(lua_tostring(L
, index
)); }
421 static int match(lua_State
* L
, by_const_pointer
<char>, int index
) { if (lua_type(L
, index
) == LUA_TSTRING
) return 0; else return -1;}
422 static int match(lua_State
* L
, by_const_pointer
<const char>, int index
) { if (lua_type(L
, index
) == LUA_TSTRING
) return 0; else return -1;}
425 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
428 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
429 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
430 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
431 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
432 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
433 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
434 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
435 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
436 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
437 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
438 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
439 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
441 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
442 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
443 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
444 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
445 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
446 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
447 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
449 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
450 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
451 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
452 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
454 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
455 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
456 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
457 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
459 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
461 lua_pushvalue(L, index);
462 return luabind::object(L, detail::ref(L), true);
465 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
467 lua_pushvalue(L, index);
468 return luabind::object(L, detail::ref(L), true);
473 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
476 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
477 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
478 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
479 static int match(lua_State* L, detail::by_value<long double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
480 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
481 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
482 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
483 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
484 static int match(lua_State* L, detail::by_value<unsigned int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
485 static int match(lua_State* L, detail::by_value<unsigned short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
486 static int match(lua_State* L, detail::by_value<unsigned char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
487 static int match(lua_State* L, detail::by_value<unsigned long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
488 static int match(lua_State* L, detail::by_value<std::string>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
489 static int match(lua_State* L, detail::by_value<const std::string>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
490 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
491 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
493 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
494 static int match(lua_State* L, by_const_pointer<const char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
497 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
501 void converter_postcall(lua_State
*, T
, int) {}
503 #undef PRIMITIVE_MATCHER
504 #undef PRIMITIVE_CONVERTER
509 // *********** default converters ***************
511 /* template<class> struct implicit_converter;
514 struct implicit_converter<lua_to_cpp>
519 T apply(lua_State* L, detail::by_value<T>, int index)
521 return converters::TO<T>::convert(L, detail::type<T>(), index);
525 static int match(lua_State* L, detail::by_value<T>, int index)
527 return converters::TO<T>::match(L, detail::type<T>(), index);
531 T apply(lua_State* L, detail::by_const_reference<T>, int index)
533 return converters::TO<T>::convert(L, detail::type<T>(), index);
537 static int match(lua_State* L, detail::by_const_reference<T>, int index)
539 return converters::TO<T>::match(L, detail::type<T>(), index);
543 T* apply(lua_State* L, detail::by_pointer<T>, int index)
545 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
549 static int match(lua_State* L, detail::by_pointer<T>, int index)
551 return converters::TO<T*>::match(L, detail::type<T*>(), index);
555 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
557 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
561 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
563 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
567 void converter_postcall(lua_State*, T, int) {}
571 // ********** user defined converter ***********
573 template<class Direction
> struct user_defined_converter
;
576 struct user_defined_converter
<lua_to_cpp
>
579 T
apply(lua_State
* L
, detail::by_value
<T
>, int index
)
581 // std::cerr << "user_defined_converter\n";
582 return converters::convert_lua_to_cpp(L
, detail::by_value
<T
>(), index
);
586 T
apply(lua_State
* L
, detail::by_reference
<T
>, int index
)
588 // std::cerr << "user_defined_converter\n";
589 return converters::convert_lua_to_cpp(L
, detail::by_reference
<T
>(), index
);
593 T
apply(lua_State
* L
, detail::by_const_reference
<T
>, int index
)
595 // std::cerr << "user_defined_converter\n";
596 return converters::convert_lua_to_cpp(L
, detail::by_const_reference
<T
>(), index
);
600 T
* apply(lua_State
* L
, detail::by_pointer
<T
>, int index
)
602 // std::cerr << "user_defined_converter\n";
603 return converters::convert_lua_to_cpp(L
, detail::by_pointer
<T
>(), index
);
607 const T
* apply(lua_State
* L
, detail::by_const_pointer
<T
>, int index
)
609 // std::cerr << "user_defined_converter\n";
610 return converters::convert_lua_to_cpp(L
, detail::by_pointer
<T
>(), index
);
614 static int match(lua_State
* L
, T
, int index
)
616 return converters::match_lua_to_cpp(L
, T(), index
);
620 void converter_postcall(lua_State
*, T
, int) {}
624 struct user_defined_converter
<cpp_to_lua
>
627 void apply(lua_State
* L
, const T
& v
)
629 converters::convert_cpp_to_lua(L
, v
);
633 // ********** pointer converter ***********
636 template<class Direction
> struct pointer_converter
;
639 struct pointer_converter
<cpp_to_lua
>
642 void apply(lua_State
* L
, T
* ptr
)
650 class_rep
* crep
= get_class_rep
<T
>(L
);
652 // class_registry* registry = class_registry::get_registry(L);
653 // class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
655 // if you get caught in this assert you are
656 // trying to use an unregistered type
657 assert(crep
&& "you are trying to use an unregistered type");
659 // create the struct to hold the object
660 void* obj
= lua_newuserdata(L
, sizeof(object_rep
));
661 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
662 new(obj
) object_rep(ptr
, crep
, 0, 0);
664 // set the meta table
665 detail::getref(L
, crep
->metatable_ref());
666 lua_setmetatable(L
, -2);
668 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
672 template<class T
> struct make_pointer
{ typedef T
* type
; };
674 struct pointer_converter
<lua_to_cpp
>
676 bool made_conversion
;
680 typename make_pointer
<T
>::type
apply(lua_State
* L
, by_pointer
<T
>, int index
)
683 // lua_isuserdata(L, index);
684 // getmetatable().__lua_class is true
685 // object_rep->flags() & object_rep::constant == 0
687 if (lua_isnil(L
, index
)) return 0;
689 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
690 assert((obj
!= 0) && "internal error, please report"); // internal error
691 const class_rep
* crep
= obj
->crep();
693 T
* ptr
= reinterpret_cast<T
*>(crep
->convert_to(LUABIND_TYPEID(T
), obj
, target
));
695 void* result = boost::langbinding::inheritance_graph::instance().find_dynamic_type(
700 made_conversion = false;
704 made_conversion
= (void*)ptr
== (char*)target
;
705 assert(!made_conversion
|| sizeof(T
) <= 32);
707 // std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
713 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
715 if (lua_isnil(L
, index
)) return 0;
716 object_rep
* obj
= is_class_object(L
, index
);
717 if (obj
== 0) return -1;
718 // cannot cast a constant object to nonconst
719 if (obj
->flags() & object_rep::constant
) return -1;
721 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->holder_type(), LUABIND_TYPEID(T
))))
722 return (obj
->flags() & object_rep::constant
)?-1:0;
723 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->const_holder_type(), LUABIND_TYPEID(T
))))
724 return (obj
->flags() & object_rep::constant
)?0:-1;
728 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
732 void converter_postcall(lua_State
*, by_pointer
<T
>, int)
735 reinterpret_cast<T
*>(target
)->~T();
739 // ******* value converter *******
741 template<class Direction
> struct value_converter
;
744 struct value_converter
<cpp_to_lua
>
747 void apply(lua_State
* L
, const T
& ref
)
749 //class_registry* registry = class_registry::get_registry(L);
750 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
751 class_rep
* crep
= get_class_rep
<T
>(L
);
753 // if you get caught in this assert you are
754 // trying to use an unregistered type
755 assert(crep
&& "you are trying to use an unregistered type");
760 boost::tie(obj_rep
,held
) = crep
->allocate(L
);
763 void(*destructor
)(void*);
764 destructor
= crep
->destructor();
765 int flags
= object_rep::owner
;
766 if (crep
->has_holder())
770 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T
), crep
->const_holder_type()))
772 flags
|= object_rep::constant
;
773 destructor
= crep
->const_holder_destructor();
778 object_ptr
= new T(ref
);
780 new(obj_rep
) object_rep(object_ptr
, crep
, flags
, destructor
);
782 // set the meta table
783 detail::getref(L
, crep
->metatable_ref());
784 lua_setmetatable(L
, -2);
789 template<class T
> struct make_const_reference
{ typedef const T
& type
; };
792 struct destruct_guard
796 destruct_guard(T
* p
): ptr(p
), dismiss(false) {}
806 struct value_converter
<lua_to_cpp
>
809 /*typename make_const_reference<T>::type*/T
apply(lua_State
* L
, by_value
<T
>, int index
)
812 // lua_isuserdata(L, index);
813 // getmetatable().__lua_class is true
814 // object_rep->flags() & object_rep::constant == 0
816 // TODO: if T is a holder type and obj is nil, we should be able to
817 // create a null-holder.
818 assert((lua_isnil(L
, index
) == false) && "internal error, please report");
820 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
821 assert((obj
!= 0) && "internal error, please report"); // internal error
822 const class_rep
* crep
= obj
->crep();
825 char target
[sizeof(T
)];
826 T
* ptr
= reinterpret_cast<T
*>(crep
->convert_to(LUABIND_TYPEID(T
), obj
, target
));
828 destruct_guard
<T
> guard(ptr
);
829 if ((void*)ptr
!= (void*)target
) guard
.dismiss
= true;
835 static int match(lua_State
* L
, by_value
<T
>, int index
)
837 if (lua_isnil(L
, index
)) return 0;
838 object_rep
* obj
= is_class_object(L
, index
);
839 if (obj
== 0) return -1;
842 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->holder_type(), LUABIND_TYPEID(T
))))
843 return (obj
->flags() & object_rep::constant
)?-1:0;
844 // if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
846 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->const_holder_type(), LUABIND_TYPEID(T
))))
847 return (obj
->flags() & object_rep::constant
)?0:1;
849 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
853 void converter_postcall(lua_State
*, T
, int) {}
856 // ******* const pointer converter *******
858 template<class Direction
> struct const_pointer_converter
;
861 struct const_pointer_converter
<cpp_to_lua
>
864 void apply(lua_State
* L
, const T
* ptr
)
872 //class_registry* registry = class_registry::get_registry(L);
873 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
874 class_rep
* crep
= get_class_rep
<T
>(L
);
876 // if you get caught in this assert you are
877 // trying to use an unregistered type
878 assert(crep
&& "you are trying to use an unregistered type");
880 // create the struct to hold the object
881 void* obj
= lua_newuserdata(L
, sizeof(object_rep
));
882 assert(obj
&& "internal error, please report");
883 // we send 0 as destructor since we know it will never be called
884 new(obj
) object_rep(const_cast<T
*>(ptr
), crep
, object_rep::constant
, 0);
886 // set the meta table
887 detail::getref(L
, crep
->metatable_ref());
888 lua_setmetatable(L
, -2);
893 template<class T
> struct make_const_pointer
{ typedef const T
* type
; };
895 struct const_pointer_converter
<lua_to_cpp
>
896 : private pointer_converter
<lua_to_cpp
>
899 typename make_const_pointer
<T
>::type
apply(lua_State
* L
, by_const_pointer
<T
>, int index
)
901 // std::cerr << "const_pointer_converter\n";
902 return pointer_converter
<lua_to_cpp
>::apply(L
, by_pointer
<T
>(), index
);
906 static int match(lua_State
* L
, by_const_pointer
<T
>, int index
)
908 if (lua_isnil(L
, index
)) return 0;
909 object_rep
* obj
= is_class_object(L
, index
);
910 if (obj
== 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
912 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->holder_type(), LUABIND_TYPEID(T
))))
913 return (obj
->flags() & object_rep::constant
)?-1:0;
914 if ((LUABIND_TYPE_INFO_EQUAL(obj
->crep()->const_holder_type(), LUABIND_TYPEID(T
))))
915 return (obj
->flags() & object_rep::constant
)?0:1;
918 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
922 void converter_postcall(lua_State
* L
, by_const_pointer
<T
>, int index
)
924 pointer_converter
<lua_to_cpp
>::converter_postcall(L
, by_pointer
<T
>(), index
);
928 // ******* reference converter *******
930 template<class Direction
> struct ref_converter
;
933 struct ref_converter
<cpp_to_lua
>
936 void apply(lua_State
* L
, T
& ref
)
938 //class_registry* registry = class_registry::get_registry(L);
939 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
940 class_rep
* crep
= get_class_rep
<T
>(L
);
942 // if you get caught in this assert you are
943 // trying to use an unregistered type
944 assert(crep
&& "you are trying to use an unregistered type");
948 // create the struct to hold the object
949 void* obj
= lua_newuserdata(L
, sizeof(object_rep
));
950 assert(obj
&& "internal error, please report");
951 new(obj
) object_rep(ptr
, crep
, 0, 0);
953 // set the meta table
954 detail::getref(L
, crep
->metatable_ref());
955 lua_setmetatable(L
, -2);
959 template<class T
> struct make_reference
{ typedef T
& type
; };
961 struct ref_converter
<lua_to_cpp
>
964 typename make_reference
<T
>::type
apply(lua_State
* L
, by_reference
<T
>, int index
)
966 // std::cerr << "ref_converter<lua_to_cpp>\n";
967 return *pointer_converter
<lua_to_cpp
>().apply(L
, by_pointer
<T
>(), index
);
971 static int match(lua_State
* L
, by_reference
<T
>, int index
)
973 return pointer_converter
<lua_to_cpp
>::match(L
, by_pointer
<T
>(), index
);
977 void converter_postcall(lua_State
*, T
, int) {}
980 // ******** const reference converter *********
982 template<class Direction
> struct const_ref_converter
;
985 struct const_ref_converter
<cpp_to_lua
>
988 void apply(lua_State
* L
, const T
& ref
)
990 //class_registry* registry = class_registry::get_registry(L);
991 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
992 class_rep
* crep
= get_class_rep
<T
>(L
);
994 // if you get caught in this assert you are
995 // trying to use an unregistered type
996 assert(crep
&& "you are trying to use an unregistered type");
1002 boost::tie(obj_rep
,held
) = crep
->allocate(L
);
1005 void(*destructor
)(void*);
1006 destructor
= crep
->destructor();
1008 if (crep
->has_holder())
1010 flags
= object_rep::owner
;
1013 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T
), crep
->const_holder_type()))
1015 flags
|= object_rep::constant
;
1016 destructor
= crep
->const_holder_destructor();
1021 object_ptr
= new T(ref
);
1023 new(obj_rep
) object_rep(object_ptr
, crep
, flags
, destructor
);
1025 // set the meta table
1026 detail::getref(L
, crep
->metatable_ref());
1027 lua_setmetatable(L
, -2);
1032 struct const_ref_converter
<lua_to_cpp
>
1033 : private const_pointer_converter
<lua_to_cpp
>
1036 typename make_const_reference
<T
>::type
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
1038 // std::cerr << "const_ref_converter<lua_to_cpp>\n";
1039 return *const_pointer_converter
<lua_to_cpp
>::apply(L
, by_const_pointer
<T
>(), index
);
1043 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
1045 return const_pointer_converter
<lua_to_cpp
>::match(L
, by_const_pointer
<T
>(), index
);
1049 void converter_postcall(lua_State
* L
, by_const_reference
<T
>, int index
)
1051 const_pointer_converter
<lua_to_cpp
>::converter_postcall(L
, by_const_pointer
<T
>(), index
);
1055 // ****** enum converter ********
1057 template<class Direction
= cpp_to_lua
>
1058 struct enum_converter
1060 void apply(lua_State
* L
, int val
)
1062 lua_pushnumber(L
, val
);
1067 struct enum_converter
<lua_to_cpp
>
1070 T
apply(lua_State
* L
, by_value
<T
>, int index
)
1072 // std::cerr << "enum_converter\n";
1073 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
1077 static int match(lua_State
* L
, by_value
<T
>, int index
)
1079 if (lua_isnumber(L
, index
)) return 0; else return -1;
1083 void converter_postcall(lua_State
*, T
, int) {}
1086 // ****** functor converter ********
1088 template<class Direction
> struct functor_converter
;
1091 struct functor_converter
<lua_to_cpp
>
1094 functor
<T
> apply(lua_State
* L
, by_const_reference
<functor
<T
> >, int index
)
1096 if (lua_isnil(L
, index
))
1097 return functor
<T
>();
1099 lua_pushvalue(L
, index
);
1100 detail::lua_reference ref
;
1102 return functor
<T
>(L
, ref
);
1106 functor
<T
> apply(lua_State
* L
, by_value
<functor
<T
> >, int index
)
1108 if (lua_isnil(L
, index
))
1109 return functor
<T
>();
1111 lua_pushvalue(L
, index
);
1112 detail::lua_reference ref
;
1114 return functor
<T
>(L
, ref
);
1118 static int match(lua_State
* L
, by_const_reference
<functor
<T
> >, int index
)
1120 if (lua_isfunction(L
, index
) || lua_isnil(L
, index
)) return 0; else return -1;
1124 static int match(lua_State
* L
, by_value
<functor
<T
> >, int index
)
1126 if (lua_isfunction(L
, index
) || lua_isnil(L
, index
)) return 0; else return -1;
1130 void converter_postcall(lua_State
*, T
, int) {}
1137 // *********** default_policy *****************
1141 struct default_policy
: converter_policy_tag
1143 BOOST_STATIC_CONSTANT(bool, has_arg
= true);
1146 static void precall(lua_State
*, T
, int) {}
1148 // template<class T>
1149 // static void postcall(lua_State*, T, int) {}
1151 template<class T
, class Direction
>
1152 struct generate_converter
1154 typedef typename
boost::mpl::if_
<is_user_defined
<T
>
1155 , user_defined_converter
<Direction
>
1156 // , typename boost::mpl::if_<is_implicit_conversion<T>
1157 // , implicit_converter<Direction>
1158 , typename
boost::mpl::if_
<is_primitive
<T
>
1159 , primitive_converter
<Direction
>
1160 , typename
boost::mpl::if_
<is_lua_functor
<T
>
1161 , functor_converter
<Direction
>
1162 , typename
boost::mpl::if_
<boost::is_enum
<T
>
1163 , enum_converter
<Direction
>
1164 , typename
boost::mpl::if_
<is_nonconst_pointer
<T
>
1165 , pointer_converter
<Direction
>
1166 , typename
boost::mpl::if_
<is_const_pointer
<T
>
1167 , const_pointer_converter
<Direction
>
1168 , typename
boost::mpl::if_
<is_nonconst_reference
<T
>
1169 , ref_converter
<Direction
>
1170 , typename
boost::mpl::if_
<is_const_reference
<T
>
1171 , const_ref_converter
<Direction
>
1172 , value_converter
<Direction
>
1173 >::type
>::type
>::type
>::type
>::type
>::type
>::type
>::type type
;
1177 // ********** get policy **********
1179 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1180 template<int N
, class T
>
1181 struct get_policy_list_impl
1186 typedef typename
U::head head
;
1187 typedef typename
U::tail tail
;
1189 typedef typename
boost::mpl::if_
<boost::mpl::equal_to
<boost::mpl::integral_c
<int, head::index
>, boost::mpl::integral_c
<int, N
> >
1190 , policy_cons
<head
, typename get_policy_list_impl
<N
, tail
>::type
>
1191 , typename get_policy_list_impl
<N
, tail
>::type
1196 struct inner
<null_type
>
1198 typedef null_type type
;
1201 typedef typename inner
<T
>::type type
;
1204 template<class List
>
1205 struct get_policy_list_impl
1210 typedef typename
List::head head
;
1211 typedef typename
List::tail tail
;
1213 typedef typename
boost::mpl::if_
<boost::mpl::equal_to
<boost::mpl::integral_c
<int, head::index
>, boost::mpl::integral_c
<int, N
> >
1214 , policy_cons
<head
, typename get_policy_list_impl
<tail
>::template apply
<N
>::type
>
1215 , typename get_policy_list_impl
<tail
>::template apply
<N
>::type
1221 struct get_policy_list_impl
<detail::null_type
>
1226 typedef null_type type
;
1231 template<int N
, class T
>
1232 struct get_policy_list
1234 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1235 typedef typename get_policy_list_impl
<N
, T
>::type type
;
1237 typedef typename get_policy_list_impl
<T
>::template apply
<N
>::type type
;
1241 // ============== new policy system =================
1243 template<int, class> struct find_conversion_policy
;
1245 template<bool IsConverter
= false>
1246 struct find_conversion_impl
1248 template<int N
, class Policies
>
1251 typedef typename find_conversion_policy
<N
, typename
Policies::tail
>::type type
;
1256 struct find_conversion_impl
<true>
1258 template<int N
, class Policies
>
1261 typedef typename
Policies::head head
;
1262 typedef typename
Policies::tail tail
;
1264 BOOST_STATIC_CONSTANT(bool, found
= (N
== head::index
));
1267 boost::mpl::if_c
<found
1269 , typename find_conversion_policy
<N
, tail
>::type
1274 template<class Policies
>
1275 struct find_conversion_impl2
1279 : find_conversion_impl
<
1280 boost::is_base_and_derived
<conversion_policy_base
, typename
Policies::head
>::value
1281 >::template apply
<N
, Policies
>
1287 struct find_conversion_impl2
<detail::null_type
>
1292 typedef default_policy type
;
1296 template<int N
, class Policies
>
1297 struct find_conversion_policy
: find_conversion_impl2
<Policies
>::template apply
<N
>
1301 template<class List
>
1302 struct policy_list_postcall
1304 typedef typename
List::head head
;
1305 typedef typename
List::tail tail
;
1307 static void apply(lua_State
* L
, const index_map
& i
)
1309 head::postcall(L
, i
);
1310 policy_list_postcall
<tail
>::apply(L
, i
);
1315 struct policy_list_postcall
<detail::null_type
>
1317 static void apply(lua_State
*, const index_map
&) {}
1321 struct find_conversion_policy<N, detail::null_type>
1323 typedef default_policy type;
1326 // ==================================================
1328 // ************** precall and postcall on policy_cons *********************
1331 template<class List
>
1332 struct policy_precall
1334 typedef typename
List::head head
;
1335 typedef typename
List::tail tail
;
1337 static void apply(lua_State
* L
, int index
)
1339 head::precall(L
, index
);
1340 policy_precall
<tail
>::apply(L
, index
);
1345 struct policy_precall
<detail::null_type
>
1347 static void apply(lua_State
*, int) {}
1350 template<class List
>
1351 struct policy_postcall
1353 typedef typename
List::head head
;
1354 typedef typename
List::tail tail
;
1356 static void apply(lua_State
* L
, int index
)
1358 head::postcall(L
, index
);
1359 policy_postcall
<tail
>::apply(L
, index
);
1364 struct policy_postcall
<detail::null_type
>
1366 static void apply(lua_State
*, int) {}
1370 struct pointer_only_converter
1373 static const T* apply(lua_State* L, type<const T*>, int index)
1379 struct only_one_converter_policy_can_be_used_per_index
{};
1381 template<class List
, class T
> struct assert_converter_policy_impl
;
1383 template<class List
>
1384 struct assert_converter_policy
1389 typedef typename
boost::mpl::if_
<boost::is_base_and_derived
<converter_policy_tag
, typename
List::head
>
1390 , only_one_converter_policy_can_be_used_per_index
1391 , typename assert_converter_policy_impl
<typename
List::tail
, T
>::type
1397 struct assert_converter_policy
<detail::null_type
>
1406 template<class List
, class T
>
1407 struct assert_converter_policy_impl
1409 typedef typename assert_converter_policy
<List
>::template apply
<T
>::type type
;
1412 template<class List
>
1413 struct find_converter_policy_impl
1415 typedef typename
List::head head
;
1416 typedef typename
List::tail tail
;
1418 typedef typename
boost::mpl::if_
<boost::is_base_and_derived
<converter_policy_tag
, head
>
1419 , typename assert_converter_policy_impl
<tail
, head
>::type
1420 , typename find_converter_policy_impl
<tail
>::type
1425 struct find_converter_policy_impl
<detail::null_type
>
1427 typedef default_policy type
;
1432 namespace converters
1437 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1439 template<class U, int N>
1440 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1442 typename luabind::detail::default_policy
1443 ::generate_converter<T, detail::lua_to_cpp>::type c;
1444 return static_cast<U>(c.apply(L,
1445 LUABIND_DECORATE_TYPE(T), index));
1449 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1451 typedef typename luabind::detail::default_policy
1452 ::generate_converter<T, detail::lua_to_cpp>::type c;
1454 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1456 std::pair<int,int> result = TO<N + 1, U>
1457 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1459 if (my_match < result.first() && my_match != -1)
1460 return std::make_pair(my_match, N);
1470 namespace luabind
{ namespace
1472 LUABIND_ANONYMOUS_FIX
boost::arg
<0> return_value
;
1473 LUABIND_ANONYMOUS_FIX
boost::arg
<0> result
;
1476 #include <luabind/detail/object_funs.hpp>
1478 #endif // LUABIND_POLICY_HPP_INCLUDED