simplified function dispatch
[luabind.git] / luabind / detail / policy.hpp
blob10428474ecbc8ea4e6b84c655ca1d26dc0f8d96c
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>
29 #include <typeinfo>
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/type_traits/add_reference.hpp>
37 #include <boost/limits.hpp>
39 #include <luabind/detail/class_registry.hpp>
40 #include <luabind/detail/primitives.hpp>
41 #include <luabind/detail/object_rep.hpp>
42 #include <luabind/detail/typetraits.hpp>
44 #include <boost/type_traits/add_reference.hpp>
46 #include <luabind/detail/decorate_type.hpp>
47 #include <luabind/object.hpp>
48 //#include <luabind/detail/make_instance.hpp>
49 //#include <luabind/pointer_holder.hpp>
51 namespace luabind
53 namespace detail
55 struct conversion_policy_base {};
58 template<int N, bool HasArg = true>
59 struct conversion_policy : detail::conversion_policy_base
61 BOOST_STATIC_CONSTANT(int, index = N);
62 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
65 class index_map
67 public:
69 index_map(const int* m): m_map(m) {}
71 int operator[](int index) const
73 return m_map[index + 1];
76 private:
78 const int* m_map;
81 namespace converters
83 using luabind::detail::yes_t;
84 using luabind::detail::no_t;
85 using luabind::detail::by_value;
86 using luabind::detail::by_reference;
87 using luabind::detail::by_const_reference;
88 using luabind::detail::by_pointer;
89 using luabind::detail::by_const_pointer;
91 no_t is_user_defined(...);
93 // template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
94 // template<> struct yes_no<false> : no_t { typedef no_t type; };
96 template<int N, class T>
97 struct TO
99 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
101 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
103 return std::make_pair(-1,-1);
106 template<int I>
107 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
110 no_t is_implicit_conversion(...);
112 template<class T>
113 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
115 template<class T>
116 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
118 template<class T>
119 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
121 template<class T>
122 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
124 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
127 namespace detail
129 template<class T>
130 struct is_user_defined
132 BOOST_STATIC_CONSTANT(bool, value =
133 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
136 /* template<class T>
137 struct is_implicit_conversion
139 BOOST_STATIC_CONSTANT(bool, value =
140 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
143 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
146 template<class T> class functor;
147 class object;
150 namespace luabind { namespace detail
152 template<class>
153 struct is_primitive;
155 template<class T>
156 yes_t is_lua_functor_test(const functor<T>&);
158 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
159 no_t is_lua_functor_test(...);
160 #else
161 template<class T>
162 no_t is_lua_functor_test(const T&);
163 #endif
165 template<class T>
166 struct is_lua_functor
168 static T t;
170 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
173 namespace
175 static char msvc_fix[64];
178 template<class T>
179 struct indirect_type
181 typedef typename
182 boost::mpl::if_<is_primitive<T>
183 , const type<T>&
184 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
185 , identity<T>
186 , boost::add_reference<T>
187 >::type
188 >::type result_type;
190 static inline result_type get()
192 return reinterpret_cast<result_type>(msvc_fix);
196 template<class H, class T>
197 struct policy_cons
199 typedef H head;
200 typedef T tail;
202 template<class U>
203 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
205 return policy_cons<U, policy_cons<H,T> >();
208 template<class U>
209 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
211 return policy_cons<U, policy_cons<H,T> >();
214 template<class U>
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 struct indirection_layer
223 template<class T>
224 indirection_layer(const T&);
227 template<class H, class T>
228 yes_t is_policy_cons_test(const policy_cons<H,T>&);
229 no_t is_policy_cons_test(...);
231 template<class T>
232 struct is_policy_cons
234 static const T& t;
236 BOOST_STATIC_CONSTANT(bool, value =
237 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
240 template<bool>
241 struct is_string_literal
243 static no_t helper(indirection_layer);
244 static yes_t helper(const char*);
247 template<>
248 struct is_string_literal<false>
250 static no_t helper(indirection_layer);
254 template<class T>
255 struct is_primitive/*: boost::mpl::bool_c<false>*/
257 static T t;
259 BOOST_STATIC_CONSTANT(bool, value =
260 sizeof(is_string_literal<boost::is_array<T>::value>::helper(t)) == sizeof(yes_t));
263 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
264 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
265 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
267 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
268 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
269 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
270 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
271 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
272 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
273 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
274 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
275 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
276 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
277 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
278 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
279 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
281 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
282 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
283 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
284 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
285 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
286 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
287 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
288 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
289 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
290 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
291 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
292 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
293 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
294 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
296 // TODO: add more
297 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
298 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
299 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
300 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
301 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
302 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
303 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
304 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
305 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
306 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
307 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
308 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
310 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
311 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
312 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
315 template<class Direction> struct primitive_converter;
317 template<>
318 struct primitive_converter<cpp_to_lua>
320 void apply(lua_State* L, const luabind::object& v)
322 // if you hit this assert you are trying to return a value from one state into another lua state
323 assert((v.lua_state() == L) && "you cannot return a value from one lua state into another");
324 v.pushvalue();
326 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
327 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
328 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
329 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
330 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
331 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
332 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
333 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
334 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
335 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
336 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
337 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
338 void apply(lua_State* L, const std::string& v)
339 { lua_pushlstring(L, v.data(), v.size()); }
340 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
343 template<>
344 struct primitive_converter<lua_to_cpp>
346 #define PRIMITIVE_CONVERTER(prim) \
347 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
348 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
349 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
351 #define PRIMITIVE_MATCHER(prim) \
352 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
353 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
354 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
356 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; }
357 PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; }
359 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); }
360 PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
362 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
363 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
365 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); }
366 PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
368 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); }
369 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
371 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); }
372 PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
374 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); }
375 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
377 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); }
378 PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
380 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); }
381 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
383 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); }
384 PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
386 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); }
387 PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
389 PRIMITIVE_CONVERTER(std::string)
390 { return std::string(lua_tostring(L, index), lua_strlen(L, index)); }
391 PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; }
393 PRIMITIVE_CONVERTER(luabind::object)
395 lua_pushvalue(L, index);
396 return luabind::object(L, detail::ref(L), true);
399 PRIMITIVE_MATCHER(luabind::object) { return std::numeric_limits<int>::max() - 1; }
401 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
402 const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
403 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
404 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;}
406 /* template<class T>
407 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
409 // TODO: add more
410 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
411 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
412 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
413 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
414 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
415 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
416 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
417 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
418 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
419 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
420 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
421 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
423 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
424 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
425 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
426 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
427 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
428 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
429 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
431 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
432 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
433 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
434 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
436 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
437 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
438 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
439 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
441 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
443 lua_pushvalue(L, index);
444 return luabind::object(L, detail::ref(L), true);
447 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
449 lua_pushvalue(L, index);
450 return luabind::object(L, detail::ref(L), true);
453 // TODO: add more
455 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
457 // matchers
458 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
459 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
460 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
461 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;}
462 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
463 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
464 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
465 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
466 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;}
467 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;}
468 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;}
469 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;}
470 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;}
471 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;}
472 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
473 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
475 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
476 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;}
478 template<class T>
479 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
482 template<class T>
483 void converter_postcall(lua_State*, T, int) {}
485 #undef PRIMITIVE_MATCHER
486 #undef PRIMITIVE_CONVERTER
491 // *********** default converters ***************
493 /* template<class> struct implicit_converter;
495 template<>
496 struct implicit_converter<lua_to_cpp>
498 int converter_index;
500 template<class T>
501 T apply(lua_State* L, detail::by_value<T>, int index)
503 return converters::TO<T>::convert(L, detail::type<T>(), index);
506 template<class T>
507 static int match(lua_State* L, detail::by_value<T>, int index)
509 return converters::TO<T>::match(L, detail::type<T>(), index);
512 template<class T>
513 T apply(lua_State* L, detail::by_const_reference<T>, int index)
515 return converters::TO<T>::convert(L, detail::type<T>(), index);
518 template<class T>
519 static int match(lua_State* L, detail::by_const_reference<T>, int index)
521 return converters::TO<T>::match(L, detail::type<T>(), index);
524 template<class T>
525 T* apply(lua_State* L, detail::by_pointer<T>, int index)
527 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
530 template<class T>
531 static int match(lua_State* L, detail::by_pointer<T>, int index)
533 return converters::TO<T*>::match(L, detail::type<T*>(), index);
536 template<class T>
537 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
539 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
542 template<class T>
543 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
545 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
548 template<class T>
549 void converter_postcall(lua_State*, T, int) {}
553 // ********** user defined converter ***********
555 template<class Direction> struct user_defined_converter;
557 template<>
558 struct user_defined_converter<lua_to_cpp>
560 template<class T>
561 T apply(lua_State* L, detail::by_value<T>, int index)
563 // std::cerr << "user_defined_converter\n";
564 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
567 template<class T>
568 T apply(lua_State* L, detail::by_reference<T>, int index)
570 // std::cerr << "user_defined_converter\n";
571 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
574 template<class T>
575 T apply(lua_State* L, detail::by_const_reference<T>, int index)
577 // std::cerr << "user_defined_converter\n";
578 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
581 template<class T>
582 T* apply(lua_State* L, detail::by_pointer<T>, int index)
584 // std::cerr << "user_defined_converter\n";
585 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
588 template<class T>
589 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
591 // std::cerr << "user_defined_converter\n";
592 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
595 template<class T>
596 static int match(lua_State* L, T, int index)
598 return converters::match_lua_to_cpp(L, T(), index);
601 template<class T>
602 void converter_postcall(lua_State*, T, int) {}
605 template<>
606 struct user_defined_converter<cpp_to_lua>
608 template<class T>
609 void apply(lua_State* L, const T& v)
611 converters::convert_cpp_to_lua(L, v);
615 // ********** pointer converter ***********
618 template<class Direction> struct pointer_converter;
620 template<>
621 struct pointer_converter<cpp_to_lua>
623 template<class T>
624 void apply(lua_State* L, T* ptr)
626 if (ptr == 0)
628 lua_pushnil(L);
629 return;
632 class_registry* registry = class_registry::get_registry(L);
633 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
635 // if you get caught in this assert you are
636 // trying to use an unregistered type
637 assert(crep && "you are trying to use an unregistered type");
639 // create the struct to hold the object
640 void* obj = lua_newuserdata(L, sizeof(object_rep));
641 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
642 new(obj) object_rep(ptr, crep, 0, 0);
644 // set the meta table
645 detail::getref(L, crep->metatable_ref());
646 lua_setmetatable(L, -2);
648 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
652 template<class T> struct make_pointer { typedef T* type; };
653 template<>
654 struct pointer_converter<lua_to_cpp>
656 bool made_conversion;
657 char target[32];
659 template<class T>
660 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
662 // preconditions:
663 // lua_isuserdata(L, index);
664 // getmetatable().__lua_class is true
665 // object_rep->flags() & object_rep::constant == 0
667 if (lua_isnil(L, index)) return 0;
669 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
670 assert((obj != 0) && "internal error, please report"); // internal error
671 const class_rep* crep = obj->crep();
673 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
675 void* result = boost::langbinding::inheritance_graph::instance().find_dynamic_type(
676 obj->ptr()
677 , LUABIND_TYPEID(T)
678 , crep->type());
680 made_conversion = false;
682 return (T*)result;
684 made_conversion = (void*)ptr == (char*)target;
685 assert(!made_conversion || sizeof(T) <= 32);
687 // std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
689 return ptr;
692 template<class T>
693 static int match(lua_State* L, by_pointer<T>, int index)
695 if (lua_isnil(L, index)) return 0;
696 object_rep* obj = is_class_object(L, index);
697 if (obj == 0) return -1;
698 // cannot cast a constant object to nonconst
699 if (obj->flags() & object_rep::constant) return -1;
701 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
702 return (obj->flags() & object_rep::constant)?-1:0;
703 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
704 return (obj->flags() & object_rep::constant)?0:-1;
707 int d;
708 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
711 template<class T>
712 void converter_postcall(lua_State*, by_pointer<T>, int)
714 if (made_conversion)
715 reinterpret_cast<T*>(target)->~T();
719 // ******* value converter *******
721 template<class Direction> struct value_converter;
723 template<>
724 struct value_converter<cpp_to_lua>
726 template<class T>
727 void apply(lua_State* L, const T& ref)
729 class_registry* registry = class_registry::get_registry(L);
730 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
732 // if you get caught in this assert you are
733 // trying to use an unregistered type
734 assert(crep && "you are trying to use an unregistered type");
736 void* obj_rep;
737 void* held;
739 boost::tie(obj_rep,held) = crep->allocate(L);
741 void* object_ptr;
742 void(*destructor)(void*);
743 destructor = crep->destructor();
744 int flags = object_rep::owner;
745 if (crep->has_holder())
747 new(held) T(ref);
748 object_ptr = held;
749 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
751 flags |= object_rep::constant;
752 destructor = crep->const_holder_destructor();
755 else
757 object_ptr = new T(ref);
759 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
761 // set the meta table
762 detail::getref(L, crep->metatable_ref());
763 lua_setmetatable(L, -2);
768 template<class T> struct make_const_reference { typedef const T& type; };
770 template<class T>
771 struct destruct_guard
773 T* ptr;
774 bool dismiss;
775 destruct_guard(T* p): ptr(p), dismiss(false) {}
777 ~destruct_guard()
779 if (!dismiss)
780 ptr->~T();
784 template<>
785 struct value_converter<lua_to_cpp>
787 template<class T>
788 /*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
790 // preconditions:
791 // lua_isuserdata(L, index);
792 // getmetatable().__lua_class is true
793 // object_rep->flags() & object_rep::constant == 0
795 assert((lua_isnil(L, index) == false) && "internal error, please report");
797 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
798 assert((obj != 0) && "internal error, please report"); // internal error
799 const class_rep* crep = obj->crep();
801 // TODO: align?
802 char target[sizeof(T)];
803 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
805 destruct_guard<T> guard(ptr);
806 if ((void*)ptr != (void*)target) guard.dismiss = true;
808 return *ptr;
811 template<class T>
812 static int match(lua_State* L, by_value<T>, int index)
814 if (lua_isnil(L, index)) return 0;
815 object_rep* obj = is_class_object(L, index);
816 if (obj == 0) return -1;
817 int d;
819 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
820 return (obj->flags() & object_rep::constant)?-1:0;
821 // if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
822 // return 0;
823 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
824 return (obj->flags() & object_rep::constant)?0:1;
826 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
829 template<class T>
830 void converter_postcall(lua_State*, T, int) {}
833 // ******* const pointer converter *******
835 template<class Direction> struct const_pointer_converter;
837 template<>
838 struct const_pointer_converter<cpp_to_lua>
840 template<class T>
841 void apply(lua_State* L, const T* ptr)
843 if (ptr == 0)
845 lua_pushnil(L);
846 return;
849 class_registry* registry = class_registry::get_registry(L);
850 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
852 // if you get caught in this assert you are
853 // trying to use an unregistered type
854 assert(crep && "you are trying to use an unregistered type");
856 // create the struct to hold the object
857 void* obj = lua_newuserdata(L, sizeof(object_rep));
858 assert(obj && "internal error, please report");
859 // we send 0 as destructor since we know it will never be called
860 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
862 // set the meta table
863 detail::getref(L, crep->metatable_ref());
864 lua_setmetatable(L, -2);
869 template<class T> struct make_const_pointer { typedef const T* type; };
870 template<>
871 struct const_pointer_converter<lua_to_cpp>
872 : private pointer_converter<lua_to_cpp>
874 template<class T>
875 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
877 // std::cerr << "const_pointer_converter\n";
878 return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
881 template<class T>
882 static int match(lua_State* L, by_const_pointer<T>, int index)
884 if (lua_isnil(L, index)) return 0;
885 object_rep* obj = is_class_object(L, index);
886 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
888 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
889 return (obj->flags() & object_rep::constant)?-1:0;
890 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
891 return (obj->flags() & object_rep::constant)?0:1;
893 int d;
894 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
897 template<class T>
898 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
900 pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
904 // ******* reference converter *******
906 template<class Direction> struct ref_converter;
908 template<>
909 struct ref_converter<cpp_to_lua>
911 template<class T>
912 void apply(lua_State* L, T& ref)
914 class_registry* registry = class_registry::get_registry(L);
915 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
917 // if you get caught in this assert you are
918 // trying to use an unregistered type
919 assert(crep && "you are trying to use an unregistered type");
921 T* ptr = &ref;
923 // create the struct to hold the object
924 void* obj = lua_newuserdata(L, sizeof(object_rep));
925 assert(obj && "internal error, please report");
926 new(obj) object_rep(ptr, crep, 0, 0);
928 // set the meta table
929 detail::getref(L, crep->metatable_ref());
930 lua_setmetatable(L, -2);
934 template<class T> struct make_reference { typedef T& type; };
935 template<>
936 struct ref_converter<lua_to_cpp>
938 template<class T>
939 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
941 // std::cerr << "ref_converter<lua_to_cpp>\n";
942 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
945 template<class T>
946 static int match(lua_State* L, by_reference<T>, int index)
948 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
951 template<class T>
952 void converter_postcall(lua_State*, T, int) {}
955 // ******** const reference converter *********
957 template<class Direction> struct const_ref_converter;
959 template<>
960 struct const_ref_converter<cpp_to_lua>
962 template<class T>
963 void apply(lua_State* L, const T& ref)
965 class_registry* registry = class_registry::get_registry(L);
966 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
968 // if you get caught in this assert you are
969 // trying to use an unregistered type
970 assert(crep && "you are trying to use an unregistered type");
973 void* obj_rep;
974 void* held;
976 boost::tie(obj_rep,held) = crep->allocate(L);
978 void* object_ptr;
979 void(*destructor)(void*);
980 destructor = crep->destructor();
981 int flags = 0;
982 if (crep->has_holder())
984 flags = object_rep::owner;
985 new(held) T(ref);
986 object_ptr = held;
987 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
989 flags |= object_rep::constant;
990 destructor = crep->const_holder_destructor();
993 else
995 object_ptr = new T(ref);
997 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
999 // set the meta table
1000 detail::getref(L, crep->metatable_ref());
1001 lua_setmetatable(L, -2);
1005 template<>
1006 struct const_ref_converter<lua_to_cpp>
1007 : private const_pointer_converter<lua_to_cpp>
1009 template<class T>
1010 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
1012 // std::cerr << "const_ref_converter<lua_to_cpp>\n";
1013 return *const_pointer_converter<lua_to_cpp>::apply(L, by_const_pointer<T>(), index);
1016 template<class T>
1017 static int match(lua_State* L, by_const_reference<T>, int index)
1019 return const_pointer_converter<lua_to_cpp>::match(L, by_const_pointer<T>(), index);
1022 template<class T>
1023 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
1025 const_pointer_converter<lua_to_cpp>::converter_postcall(L, by_const_pointer<T>(), index);
1029 // ****** enum converter ********
1031 template<class Direction = cpp_to_lua>
1032 struct enum_converter
1034 void apply(lua_State* L, int val)
1036 lua_pushnumber(L, val);
1040 template<>
1041 struct enum_converter<lua_to_cpp>
1043 template<class T>
1044 T apply(lua_State* L, by_value<T>, int index)
1046 // std::cerr << "enum_converter\n";
1047 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
1050 template<class T>
1051 static int match(lua_State* L, by_value<T>, int index)
1053 if (lua_isnumber(L, index)) return 0; else return -1;
1056 template<class T>
1057 void converter_postcall(lua_State*, T, int) {}
1060 // ****** functor converter ********
1062 template<class Direction> struct functor_converter;
1064 template<>
1065 struct functor_converter<lua_to_cpp>
1067 template<class T>
1068 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
1070 if (lua_isnil(L, index))
1071 return functor<T>();
1073 lua_pushvalue(L, index);
1074 int ref = detail::ref(L);
1075 return functor<T>(L, ref);
1078 template<class T>
1079 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
1081 if (lua_isnil(L, index))
1082 return functor<T>();
1084 lua_pushvalue(L, index);
1085 int ref = detail::ref(L);
1086 return functor<T>(L, ref);
1089 template<class T>
1090 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
1092 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1095 template<class T>
1096 static int match(lua_State* L, by_value<functor<T> >, int index)
1098 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1101 template<class T>
1102 void converter_postcall(lua_State*, T, int) {}
1109 // *********** default_policy *****************
1113 struct default_policy : converter_policy_tag
1115 BOOST_STATIC_CONSTANT(bool, has_arg = true);
1117 template<class T>
1118 static void precall(lua_State*, T, int) {}
1120 // template<class T>
1121 // static void postcall(lua_State*, T, int) {}
1123 template<class T, class Direction>
1124 struct generate_converter
1126 typedef typename boost::mpl::if_<is_user_defined<T>
1127 , user_defined_converter<Direction>
1128 // , typename boost::mpl::if_<is_implicit_conversion<T>
1129 // , implicit_converter<Direction>
1130 , typename boost::mpl::if_<is_primitive<T>
1131 , primitive_converter<Direction>
1132 , typename boost::mpl::if_<is_lua_functor<T>
1133 , functor_converter<Direction>
1134 , typename boost::mpl::if_<boost::is_enum<T>
1135 , enum_converter<Direction>
1136 , typename boost::mpl::if_<is_nonconst_pointer<T>
1137 , pointer_converter<Direction>
1138 , typename boost::mpl::if_<is_const_pointer<T>
1139 , const_pointer_converter<Direction>
1140 , typename boost::mpl::if_<is_nonconst_reference<T>
1141 , ref_converter<Direction>
1142 , typename boost::mpl::if_<is_const_reference<T>
1143 , const_ref_converter<Direction>
1144 , value_converter<Direction>
1145 >::type>::type>::type>::type>::type>::type>::type>::type type;
1149 // ********** get policy **********
1151 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1152 template<int N, class T>
1153 struct get_policy_list_impl
1155 template<class U>
1156 struct inner
1158 typedef typename U::head head;
1159 typedef typename U::tail tail;
1161 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1162 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
1163 , typename get_policy_list_impl<N, tail>::type
1164 >::type type;
1167 template<>
1168 struct inner<null_type>
1170 typedef null_type type;
1173 typedef typename inner<T>::type type;
1175 #else
1176 template<class List>
1177 struct get_policy_list_impl
1179 template<int N>
1180 struct apply
1182 typedef typename List::head head;
1183 typedef typename List::tail tail;
1185 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1186 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
1187 , typename get_policy_list_impl<tail>::template apply<N>::type
1188 >::type type;
1192 template<>
1193 struct get_policy_list_impl<detail::null_type>
1195 template<int N>
1196 struct apply
1198 typedef null_type type;
1201 #endif
1203 template<int N, class T>
1204 struct get_policy_list
1206 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1207 typedef typename get_policy_list_impl<N, T>::type type;
1208 #else
1209 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
1210 #endif
1213 // ============== new policy system =================
1215 template<int, class> struct find_conversion_policy;
1217 template<bool IsConverter = false>
1218 struct find_conversion_impl
1220 template<int N, class Policies>
1221 struct apply
1223 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
1227 template<>
1228 struct find_conversion_impl<true>
1230 template<int N, class Policies>
1231 struct apply
1233 typedef typename Policies::head head;
1234 typedef typename Policies::tail tail;
1236 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
1238 typedef typename
1239 boost::mpl::if_c<found
1240 , head
1241 , typename find_conversion_policy<N, tail>::type
1242 >::type type;
1246 template<class Policies>
1247 struct find_conversion_impl2
1249 template<int N>
1250 struct apply
1251 : find_conversion_impl<
1252 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
1253 >::template apply<N, Policies>
1258 template<>
1259 struct find_conversion_impl2<detail::null_type>
1261 template<int N>
1262 struct apply
1264 typedef default_policy type;
1268 template<int N, class Policies>
1269 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
1273 template<class List>
1274 struct policy_list_postcall
1276 typedef typename List::head head;
1277 typedef typename List::tail tail;
1279 static void apply(lua_State* L, const index_map& i)
1281 head::postcall(L, i);
1282 policy_list_postcall<tail>::apply(L, i);
1286 template<>
1287 struct policy_list_postcall<detail::null_type>
1289 static void apply(lua_State*, const index_map&) {}
1292 /* template<int N>
1293 struct find_conversion_policy<N, detail::null_type>
1295 typedef default_policy type;
1296 };*/
1298 // ==================================================
1300 // ************** precall and postcall on policy_cons *********************
1303 template<class List>
1304 struct policy_precall
1306 typedef typename List::head head;
1307 typedef typename List::tail tail;
1309 static void apply(lua_State* L, int index)
1311 head::precall(L, index);
1312 policy_precall<tail>::apply(L, index);
1316 template<>
1317 struct policy_precall<detail::null_type>
1319 static void apply(lua_State*, int) {}
1322 template<class List>
1323 struct policy_postcall
1325 typedef typename List::head head;
1326 typedef typename List::tail tail;
1328 static void apply(lua_State* L, int index)
1330 head::postcall(L, index);
1331 policy_postcall<tail>::apply(L, index);
1335 template<>
1336 struct policy_postcall<detail::null_type>
1338 static void apply(lua_State*, int) {}
1342 struct pointer_only_converter
1344 template<class T>
1345 static const T* apply(lua_State* L, type<const T*>, int index)
1347 int a = index;
1351 struct only_one_converter_policy_can_be_used_per_index {};
1353 template<class List, class T> struct assert_converter_policy_impl;
1355 template<class List>
1356 struct assert_converter_policy
1358 template<class T>
1359 struct apply
1361 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1362 , only_one_converter_policy_can_be_used_per_index
1363 , typename assert_converter_policy_impl<typename List::tail, T>::type
1364 >::type type;
1368 template<>
1369 struct assert_converter_policy<detail::null_type>
1371 template<class T>
1372 struct apply
1374 typedef T type;
1378 template<class List, class T>
1379 struct assert_converter_policy_impl
1381 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1384 template<class List>
1385 struct find_converter_policy_impl
1387 typedef typename List::head head;
1388 typedef typename List::tail tail;
1390 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1391 , typename assert_converter_policy_impl<tail, head>::type
1392 , typename find_converter_policy_impl<tail>::type
1393 >::type type;
1396 template<>
1397 struct find_converter_policy_impl<detail::null_type>
1399 typedef default_policy type;
1404 namespace converters
1406 template<class T>
1407 struct FROM
1409 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1411 template<class U, int N>
1412 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1414 typename luabind::detail::default_policy
1415 ::generate_converter<T, detail::lua_to_cpp>::type c;
1416 return static_cast<U>(c.apply(L,
1417 LUABIND_DECORATE_TYPE(T), index));
1420 template<class U>
1421 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1423 typedef typename luabind::detail::default_policy
1424 ::generate_converter<T, detail::lua_to_cpp>::type c;
1426 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1428 std::pair<int,int> result = TO<N + 1, U>
1429 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1431 if (my_match < result.first() && my_match != -1)
1432 return std::make_pair(my_match, N);
1433 else
1434 return result;
1442 namespace luabind { namespace
1444 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1445 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1448 #include <luabind/detail/object_funs.hpp>
1450 #endif // LUABIND_POLICY_HPP_INCLUDED