*** empty log message ***
[luabind.git] / luabind / detail / policy.hpp
blob992b88bd44342e54d63e7453e4eb7c9c3c88c53f
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>
43 #include <luabind/detail/class_cache.hpp>
45 #include <boost/type_traits/add_reference.hpp>
47 #include <luabind/detail/decorate_type.hpp>
48 #include <luabind/object.hpp>
49 //#include <luabind/detail/make_instance.hpp>
50 //#include <luabind/pointer_holder.hpp>
52 namespace luabind
54 namespace detail
56 struct conversion_policy_base {};
59 template<int N, bool HasArg = true>
60 struct conversion_policy : detail::conversion_policy_base
62 BOOST_STATIC_CONSTANT(int, index = N);
63 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
66 class index_map
68 public:
70 index_map(const int* m): m_map(m) {}
72 int operator[](int index) const
74 return m_map[index + 1];
77 private:
79 const int* m_map;
82 namespace converters
84 using luabind::detail::yes_t;
85 using luabind::detail::no_t;
86 using luabind::detail::by_value;
87 using luabind::detail::by_reference;
88 using luabind::detail::by_const_reference;
89 using luabind::detail::by_pointer;
90 using luabind::detail::by_const_pointer;
92 no_t is_user_defined(...);
94 // template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
95 // template<> struct yes_no<false> : no_t { typedef no_t type; };
97 template<int N, class T>
98 struct TO
100 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
102 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
104 return std::make_pair(-1,-1);
107 template<int I>
108 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
111 no_t is_implicit_conversion(...);
113 template<class T>
114 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
116 template<class T>
117 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
119 template<class T>
120 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
122 template<class T>
123 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
125 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
128 namespace detail
130 template<class T>
131 struct is_user_defined
133 BOOST_STATIC_CONSTANT(bool, value =
134 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
137 /* template<class T>
138 struct is_implicit_conversion
140 BOOST_STATIC_CONSTANT(bool, value =
141 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
144 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
147 template<class T> class functor;
148 class object;
151 namespace luabind { namespace detail
153 template<class>
154 struct is_primitive;
156 template<class T>
157 yes_t is_lua_functor_test(const functor<T>&);
159 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
160 no_t is_lua_functor_test(...);
161 #else
162 template<class T>
163 no_t is_lua_functor_test(const T&);
164 #endif
166 template<class T>
167 struct is_lua_functor
169 static T t;
171 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
174 namespace
176 static char msvc_fix[64];
179 template<class T>
180 struct indirect_type
182 typedef typename
183 boost::mpl::if_<is_primitive<T>
184 , const type<T>&
185 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
186 , identity<T>
187 , boost::add_reference<T>
188 >::type
189 >::type result_type;
191 static inline result_type get()
193 return reinterpret_cast<result_type>(msvc_fix);
197 template<class H, class T>
198 struct policy_cons
200 typedef H head;
201 typedef T tail;
203 template<class U>
204 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
206 return policy_cons<U, policy_cons<H,T> >();
209 template<class U>
210 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
212 return policy_cons<U, policy_cons<H,T> >();
215 template<class U>
216 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
218 return policy_cons<U, policy_cons<H,T> >();
222 struct indirection_layer
224 template<class T>
225 indirection_layer(const T&);
228 template<class H, class T>
229 yes_t is_policy_cons_test(const policy_cons<H,T>&);
230 no_t is_policy_cons_test(...);
232 template<class T>
233 struct is_policy_cons
235 static const T& t;
237 BOOST_STATIC_CONSTANT(bool, value =
238 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
241 template<bool>
242 struct is_string_literal
244 static no_t helper(indirection_layer);
245 static yes_t helper(const char*);
248 template<>
249 struct is_string_literal<false>
251 static no_t helper(indirection_layer);
255 template<class T>
256 struct is_primitive/*: boost::mpl::bool_c<false>*/
258 static T t;
260 BOOST_STATIC_CONSTANT(bool, value =
261 sizeof(is_string_literal<boost::is_array<T>::value>::helper(t)) == sizeof(yes_t));
264 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
265 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
266 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
268 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
269 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
270 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
271 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
272 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
273 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
274 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
275 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
276 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
277 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
278 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
279 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
280 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
282 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
283 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
284 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
285 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
286 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
287 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
288 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
289 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
290 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
291 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
292 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
293 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
294 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
295 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
297 // TODO: add more
298 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
299 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
300 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
301 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
302 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
303 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
304 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
305 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
306 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
307 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
308 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
309 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
311 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
312 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
313 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
316 template<class Direction> struct primitive_converter;
318 template<>
319 struct primitive_converter<cpp_to_lua>
321 void apply(lua_State* L, const luabind::object& v)
323 // if the luabind::object is uninitialized
324 // treat it as nil.
325 if (v.lua_state() == 0)
327 lua_pushnil(L);
328 return;
330 // if you hit this assert you are trying to return a value from one state into another lua state
331 assert((v.lua_state() == L) && "you cannot return an uninitilized value "
332 "or a value from one lua state into another");
333 v.pushvalue();
335 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
336 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
337 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
338 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
339 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
340 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
341 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
342 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
343 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
344 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
345 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
346 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
347 void apply(lua_State* L, const std::string& v)
348 { lua_pushlstring(L, v.data(), v.size()); }
349 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
352 template<>
353 struct primitive_converter<lua_to_cpp>
355 #define PRIMITIVE_CONVERTER(prim) \
356 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
357 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
358 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
360 #define PRIMITIVE_MATCHER(prim) \
361 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
362 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
363 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
365 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; }
366 PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; }
368 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); }
369 PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
371 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
372 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
374 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); }
375 PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
377 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); }
378 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
380 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); }
381 PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
383 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); }
384 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
386 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); }
387 PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
389 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); }
390 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
392 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); }
393 PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
395 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); }
396 PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
398 PRIMITIVE_CONVERTER(std::string)
399 { return std::string(lua_tostring(L, index), lua_strlen(L, index)); }
400 PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; }
402 PRIMITIVE_CONVERTER(luabind::object)
404 lua_pushvalue(L, index);
405 detail::lua_reference ref;
406 ref.set(L);
407 return luabind::object(L, ref, true);
410 PRIMITIVE_MATCHER(luabind::object) { return std::numeric_limits<int>::max() - 1; }
412 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
413 const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
414 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
415 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;}
417 /* template<class T>
418 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
420 // TODO: add more
421 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
422 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
423 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
424 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
425 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
426 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
427 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
428 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
429 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
430 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
431 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
432 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
434 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
435 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
436 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
437 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
438 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
439 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
440 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
442 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
443 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
444 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
445 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
447 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
448 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
449 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
450 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
452 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
454 lua_pushvalue(L, index);
455 return luabind::object(L, detail::ref(L), true);
458 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
460 lua_pushvalue(L, index);
461 return luabind::object(L, detail::ref(L), true);
464 // TODO: add more
466 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
468 // matchers
469 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
470 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
471 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
472 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;}
473 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
474 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
475 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
476 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
477 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;}
478 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;}
479 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;}
480 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;}
481 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;}
482 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;}
483 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
484 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
486 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
487 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;}
489 template<class T>
490 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
493 template<class T>
494 void converter_postcall(lua_State*, T, int) {}
496 #undef PRIMITIVE_MATCHER
497 #undef PRIMITIVE_CONVERTER
502 // *********** default converters ***************
504 /* template<class> struct implicit_converter;
506 template<>
507 struct implicit_converter<lua_to_cpp>
509 int converter_index;
511 template<class T>
512 T apply(lua_State* L, detail::by_value<T>, int index)
514 return converters::TO<T>::convert(L, detail::type<T>(), index);
517 template<class T>
518 static int match(lua_State* L, detail::by_value<T>, int index)
520 return converters::TO<T>::match(L, detail::type<T>(), index);
523 template<class T>
524 T apply(lua_State* L, detail::by_const_reference<T>, int index)
526 return converters::TO<T>::convert(L, detail::type<T>(), index);
529 template<class T>
530 static int match(lua_State* L, detail::by_const_reference<T>, int index)
532 return converters::TO<T>::match(L, detail::type<T>(), index);
535 template<class T>
536 T* apply(lua_State* L, detail::by_pointer<T>, int index)
538 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
541 template<class T>
542 static int match(lua_State* L, detail::by_pointer<T>, int index)
544 return converters::TO<T*>::match(L, detail::type<T*>(), index);
547 template<class T>
548 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
550 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
553 template<class T>
554 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
556 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
559 template<class T>
560 void converter_postcall(lua_State*, T, int) {}
564 // ********** user defined converter ***********
566 template<class Direction> struct user_defined_converter;
568 template<>
569 struct user_defined_converter<lua_to_cpp>
571 template<class T>
572 T apply(lua_State* L, detail::by_value<T>, int index)
574 // std::cerr << "user_defined_converter\n";
575 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
578 template<class T>
579 T apply(lua_State* L, detail::by_reference<T>, int index)
581 // std::cerr << "user_defined_converter\n";
582 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
585 template<class T>
586 T apply(lua_State* L, detail::by_const_reference<T>, int index)
588 // std::cerr << "user_defined_converter\n";
589 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
592 template<class T>
593 T* apply(lua_State* L, detail::by_pointer<T>, int index)
595 // std::cerr << "user_defined_converter\n";
596 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
599 template<class T>
600 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
602 // std::cerr << "user_defined_converter\n";
603 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
606 template<class T>
607 static int match(lua_State* L, T, int index)
609 return converters::match_lua_to_cpp(L, T(), index);
612 template<class T>
613 void converter_postcall(lua_State*, T, int) {}
616 template<>
617 struct user_defined_converter<cpp_to_lua>
619 template<class T>
620 void apply(lua_State* L, const T& v)
622 converters::convert_cpp_to_lua(L, v);
626 // ********** pointer converter ***********
629 template<class Direction> struct pointer_converter;
631 template<>
632 struct pointer_converter<cpp_to_lua>
634 template<class T>
635 void apply(lua_State* L, T* ptr)
637 if (ptr == 0)
639 lua_pushnil(L);
640 return;
643 class_rep* crep = get_class_rep<T>(L);
645 // class_registry* registry = class_registry::get_registry(L);
646 // class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
648 // if you get caught in this assert you are
649 // trying to use an unregistered type
650 assert(crep && "you are trying to use an unregistered type");
652 // create the struct to hold the object
653 void* obj = lua_newuserdata(L, sizeof(object_rep));
654 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
655 new(obj) object_rep(ptr, crep, 0, 0);
657 // set the meta table
658 detail::getref(L, crep->metatable_ref());
659 lua_setmetatable(L, -2);
661 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
665 template<class T> struct make_pointer { typedef T* type; };
666 template<>
667 struct pointer_converter<lua_to_cpp>
669 bool made_conversion;
670 char target[32];
672 template<class T>
673 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
675 // preconditions:
676 // lua_isuserdata(L, index);
677 // getmetatable().__lua_class is true
678 // object_rep->flags() & object_rep::constant == 0
680 if (lua_isnil(L, index)) return 0;
682 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
683 assert((obj != 0) && "internal error, please report"); // internal error
684 const class_rep* crep = obj->crep();
686 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
688 void* result = boost::langbinding::inheritance_graph::instance().find_dynamic_type(
689 obj->ptr()
690 , LUABIND_TYPEID(T)
691 , crep->type());
693 made_conversion = false;
695 return (T*)result;
697 made_conversion = (void*)ptr == (char*)target;
698 assert(!made_conversion || sizeof(T) <= 32);
700 // std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
702 return ptr;
705 template<class T>
706 static int match(lua_State* L, by_pointer<T>, int index)
708 if (lua_isnil(L, index)) return 0;
709 object_rep* obj = is_class_object(L, index);
710 if (obj == 0) return -1;
711 // cannot cast a constant object to nonconst
712 if (obj->flags() & object_rep::constant) return -1;
714 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
715 return (obj->flags() & object_rep::constant)?-1:0;
716 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
717 return (obj->flags() & object_rep::constant)?0:-1;
720 int d;
721 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
724 template<class T>
725 void converter_postcall(lua_State*, by_pointer<T>, int)
727 if (made_conversion)
728 reinterpret_cast<T*>(target)->~T();
732 // ******* value converter *******
734 template<class Direction> struct value_converter;
736 template<>
737 struct value_converter<cpp_to_lua>
739 template<class T>
740 void apply(lua_State* L, const T& ref)
742 //class_registry* registry = class_registry::get_registry(L);
743 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
744 class_rep* crep = get_class_rep<T>(L);
746 // if you get caught in this assert you are
747 // trying to use an unregistered type
748 assert(crep && "you are trying to use an unregistered type");
750 void* obj_rep;
751 void* held;
753 boost::tie(obj_rep,held) = crep->allocate(L);
755 void* object_ptr;
756 void(*destructor)(void*);
757 destructor = crep->destructor();
758 int flags = object_rep::owner;
759 if (crep->has_holder())
761 new(held) T(ref);
762 object_ptr = held;
763 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
765 flags |= object_rep::constant;
766 destructor = crep->const_holder_destructor();
769 else
771 object_ptr = new T(ref);
773 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
775 // set the meta table
776 detail::getref(L, crep->metatable_ref());
777 lua_setmetatable(L, -2);
782 template<class T> struct make_const_reference { typedef const T& type; };
784 template<class T>
785 struct destruct_guard
787 T* ptr;
788 bool dismiss;
789 destruct_guard(T* p): ptr(p), dismiss(false) {}
791 ~destruct_guard()
793 if (!dismiss)
794 ptr->~T();
798 template<>
799 struct value_converter<lua_to_cpp>
801 template<class T>
802 /*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
804 // preconditions:
805 // lua_isuserdata(L, index);
806 // getmetatable().__lua_class is true
807 // object_rep->flags() & object_rep::constant == 0
809 assert((lua_isnil(L, index) == false) && "internal error, please report");
811 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
812 assert((obj != 0) && "internal error, please report"); // internal error
813 const class_rep* crep = obj->crep();
815 // TODO: align?
816 char target[sizeof(T)];
817 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
819 destruct_guard<T> guard(ptr);
820 if ((void*)ptr != (void*)target) guard.dismiss = true;
822 return *ptr;
825 template<class T>
826 static int match(lua_State* L, by_value<T>, int index)
828 if (lua_isnil(L, index)) return 0;
829 object_rep* obj = is_class_object(L, index);
830 if (obj == 0) return -1;
831 int d;
833 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
834 return (obj->flags() & object_rep::constant)?-1:0;
835 // if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
836 // return 0;
837 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
838 return (obj->flags() & object_rep::constant)?0:1;
840 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
843 template<class T>
844 void converter_postcall(lua_State*, T, int) {}
847 // ******* const pointer converter *******
849 template<class Direction> struct const_pointer_converter;
851 template<>
852 struct const_pointer_converter<cpp_to_lua>
854 template<class T>
855 void apply(lua_State* L, const T* ptr)
857 if (ptr == 0)
859 lua_pushnil(L);
860 return;
863 //class_registry* registry = class_registry::get_registry(L);
864 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
865 class_rep* crep = get_class_rep<T>(L);
867 // if you get caught in this assert you are
868 // trying to use an unregistered type
869 assert(crep && "you are trying to use an unregistered type");
871 // create the struct to hold the object
872 void* obj = lua_newuserdata(L, sizeof(object_rep));
873 assert(obj && "internal error, please report");
874 // we send 0 as destructor since we know it will never be called
875 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
877 // set the meta table
878 detail::getref(L, crep->metatable_ref());
879 lua_setmetatable(L, -2);
884 template<class T> struct make_const_pointer { typedef const T* type; };
885 template<>
886 struct const_pointer_converter<lua_to_cpp>
887 : private pointer_converter<lua_to_cpp>
889 template<class T>
890 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
892 // std::cerr << "const_pointer_converter\n";
893 return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
896 template<class T>
897 static int match(lua_State* L, by_const_pointer<T>, int index)
899 if (lua_isnil(L, index)) return 0;
900 object_rep* obj = is_class_object(L, index);
901 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
903 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
904 return (obj->flags() & object_rep::constant)?-1:0;
905 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
906 return (obj->flags() & object_rep::constant)?0:1;
908 int d;
909 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
912 template<class T>
913 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
915 pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
919 // ******* reference converter *******
921 template<class Direction> struct ref_converter;
923 template<>
924 struct ref_converter<cpp_to_lua>
926 template<class T>
927 void apply(lua_State* L, T& ref)
929 //class_registry* registry = class_registry::get_registry(L);
930 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
931 class_rep* crep = get_class_rep<T>(L);
933 // if you get caught in this assert you are
934 // trying to use an unregistered type
935 assert(crep && "you are trying to use an unregistered type");
937 T* ptr = &ref;
939 // create the struct to hold the object
940 void* obj = lua_newuserdata(L, sizeof(object_rep));
941 assert(obj && "internal error, please report");
942 new(obj) object_rep(ptr, crep, 0, 0);
944 // set the meta table
945 detail::getref(L, crep->metatable_ref());
946 lua_setmetatable(L, -2);
950 template<class T> struct make_reference { typedef T& type; };
951 template<>
952 struct ref_converter<lua_to_cpp>
954 template<class T>
955 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
957 // std::cerr << "ref_converter<lua_to_cpp>\n";
958 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
961 template<class T>
962 static int match(lua_State* L, by_reference<T>, int index)
964 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
967 template<class T>
968 void converter_postcall(lua_State*, T, int) {}
971 // ******** const reference converter *********
973 template<class Direction> struct const_ref_converter;
975 template<>
976 struct const_ref_converter<cpp_to_lua>
978 template<class T>
979 void apply(lua_State* L, const T& ref)
981 //class_registry* registry = class_registry::get_registry(L);
982 //class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
983 class_rep* crep = get_class_rep<T>(L);
985 // if you get caught in this assert you are
986 // trying to use an unregistered type
987 assert(crep && "you are trying to use an unregistered type");
990 void* obj_rep;
991 void* held;
993 boost::tie(obj_rep,held) = crep->allocate(L);
995 void* object_ptr;
996 void(*destructor)(void*);
997 destructor = crep->destructor();
998 int flags = 0;
999 if (crep->has_holder())
1001 flags = object_rep::owner;
1002 new(held) T(ref);
1003 object_ptr = held;
1004 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
1006 flags |= object_rep::constant;
1007 destructor = crep->const_holder_destructor();
1010 else
1012 object_ptr = new T(ref);
1014 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
1016 // set the meta table
1017 detail::getref(L, crep->metatable_ref());
1018 lua_setmetatable(L, -2);
1022 template<>
1023 struct const_ref_converter<lua_to_cpp>
1024 : private const_pointer_converter<lua_to_cpp>
1026 template<class T>
1027 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
1029 // std::cerr << "const_ref_converter<lua_to_cpp>\n";
1030 return *const_pointer_converter<lua_to_cpp>::apply(L, by_const_pointer<T>(), index);
1033 template<class T>
1034 static int match(lua_State* L, by_const_reference<T>, int index)
1036 return const_pointer_converter<lua_to_cpp>::match(L, by_const_pointer<T>(), index);
1039 template<class T>
1040 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
1042 const_pointer_converter<lua_to_cpp>::converter_postcall(L, by_const_pointer<T>(), index);
1046 // ****** enum converter ********
1048 template<class Direction = cpp_to_lua>
1049 struct enum_converter
1051 void apply(lua_State* L, int val)
1053 lua_pushnumber(L, val);
1057 template<>
1058 struct enum_converter<lua_to_cpp>
1060 template<class T>
1061 T apply(lua_State* L, by_value<T>, int index)
1063 // std::cerr << "enum_converter\n";
1064 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
1067 template<class T>
1068 static int match(lua_State* L, by_value<T>, int index)
1070 if (lua_isnumber(L, index)) return 0; else return -1;
1073 template<class T>
1074 void converter_postcall(lua_State*, T, int) {}
1077 // ****** functor converter ********
1079 template<class Direction> struct functor_converter;
1081 template<>
1082 struct functor_converter<lua_to_cpp>
1084 template<class T>
1085 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
1087 if (lua_isnil(L, index))
1088 return functor<T>();
1090 lua_pushvalue(L, index);
1091 detail::lua_reference ref;
1092 ref.set(L);
1093 return functor<T>(L, ref);
1096 template<class T>
1097 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
1099 if (lua_isnil(L, index))
1100 return functor<T>();
1102 lua_pushvalue(L, index);
1103 detail::lua_reference ref;
1104 ref.set(L);
1105 return functor<T>(L, ref);
1108 template<class T>
1109 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
1111 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1114 template<class T>
1115 static int match(lua_State* L, by_value<functor<T> >, int index)
1117 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1120 template<class T>
1121 void converter_postcall(lua_State*, T, int) {}
1128 // *********** default_policy *****************
1132 struct default_policy : converter_policy_tag
1134 BOOST_STATIC_CONSTANT(bool, has_arg = true);
1136 template<class T>
1137 static void precall(lua_State*, T, int) {}
1139 // template<class T>
1140 // static void postcall(lua_State*, T, int) {}
1142 template<class T, class Direction>
1143 struct generate_converter
1145 typedef typename boost::mpl::if_<is_user_defined<T>
1146 , user_defined_converter<Direction>
1147 // , typename boost::mpl::if_<is_implicit_conversion<T>
1148 // , implicit_converter<Direction>
1149 , typename boost::mpl::if_<is_primitive<T>
1150 , primitive_converter<Direction>
1151 , typename boost::mpl::if_<is_lua_functor<T>
1152 , functor_converter<Direction>
1153 , typename boost::mpl::if_<boost::is_enum<T>
1154 , enum_converter<Direction>
1155 , typename boost::mpl::if_<is_nonconst_pointer<T>
1156 , pointer_converter<Direction>
1157 , typename boost::mpl::if_<is_const_pointer<T>
1158 , const_pointer_converter<Direction>
1159 , typename boost::mpl::if_<is_nonconst_reference<T>
1160 , ref_converter<Direction>
1161 , typename boost::mpl::if_<is_const_reference<T>
1162 , const_ref_converter<Direction>
1163 , value_converter<Direction>
1164 >::type>::type>::type>::type>::type>::type>::type>::type type;
1168 // ********** get policy **********
1170 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1171 template<int N, class T>
1172 struct get_policy_list_impl
1174 template<class U>
1175 struct inner
1177 typedef typename U::head head;
1178 typedef typename U::tail tail;
1180 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1181 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
1182 , typename get_policy_list_impl<N, tail>::type
1183 >::type type;
1186 template<>
1187 struct inner<null_type>
1189 typedef null_type type;
1192 typedef typename inner<T>::type type;
1194 #else
1195 template<class List>
1196 struct get_policy_list_impl
1198 template<int N>
1199 struct apply
1201 typedef typename List::head head;
1202 typedef typename List::tail tail;
1204 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1205 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
1206 , typename get_policy_list_impl<tail>::template apply<N>::type
1207 >::type type;
1211 template<>
1212 struct get_policy_list_impl<detail::null_type>
1214 template<int N>
1215 struct apply
1217 typedef null_type type;
1220 #endif
1222 template<int N, class T>
1223 struct get_policy_list
1225 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1226 typedef typename get_policy_list_impl<N, T>::type type;
1227 #else
1228 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
1229 #endif
1232 // ============== new policy system =================
1234 template<int, class> struct find_conversion_policy;
1236 template<bool IsConverter = false>
1237 struct find_conversion_impl
1239 template<int N, class Policies>
1240 struct apply
1242 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
1246 template<>
1247 struct find_conversion_impl<true>
1249 template<int N, class Policies>
1250 struct apply
1252 typedef typename Policies::head head;
1253 typedef typename Policies::tail tail;
1255 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
1257 typedef typename
1258 boost::mpl::if_c<found
1259 , head
1260 , typename find_conversion_policy<N, tail>::type
1261 >::type type;
1265 template<class Policies>
1266 struct find_conversion_impl2
1268 template<int N>
1269 struct apply
1270 : find_conversion_impl<
1271 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
1272 >::template apply<N, Policies>
1277 template<>
1278 struct find_conversion_impl2<detail::null_type>
1280 template<int N>
1281 struct apply
1283 typedef default_policy type;
1287 template<int N, class Policies>
1288 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
1292 template<class List>
1293 struct policy_list_postcall
1295 typedef typename List::head head;
1296 typedef typename List::tail tail;
1298 static void apply(lua_State* L, const index_map& i)
1300 head::postcall(L, i);
1301 policy_list_postcall<tail>::apply(L, i);
1305 template<>
1306 struct policy_list_postcall<detail::null_type>
1308 static void apply(lua_State*, const index_map&) {}
1311 /* template<int N>
1312 struct find_conversion_policy<N, detail::null_type>
1314 typedef default_policy type;
1315 };*/
1317 // ==================================================
1319 // ************** precall and postcall on policy_cons *********************
1322 template<class List>
1323 struct policy_precall
1325 typedef typename List::head head;
1326 typedef typename List::tail tail;
1328 static void apply(lua_State* L, int index)
1330 head::precall(L, index);
1331 policy_precall<tail>::apply(L, index);
1335 template<>
1336 struct policy_precall<detail::null_type>
1338 static void apply(lua_State*, int) {}
1341 template<class List>
1342 struct policy_postcall
1344 typedef typename List::head head;
1345 typedef typename List::tail tail;
1347 static void apply(lua_State* L, int index)
1349 head::postcall(L, index);
1350 policy_postcall<tail>::apply(L, index);
1354 template<>
1355 struct policy_postcall<detail::null_type>
1357 static void apply(lua_State*, int) {}
1361 struct pointer_only_converter
1363 template<class T>
1364 static const T* apply(lua_State* L, type<const T*>, int index)
1366 int a = index;
1370 struct only_one_converter_policy_can_be_used_per_index {};
1372 template<class List, class T> struct assert_converter_policy_impl;
1374 template<class List>
1375 struct assert_converter_policy
1377 template<class T>
1378 struct apply
1380 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1381 , only_one_converter_policy_can_be_used_per_index
1382 , typename assert_converter_policy_impl<typename List::tail, T>::type
1383 >::type type;
1387 template<>
1388 struct assert_converter_policy<detail::null_type>
1390 template<class T>
1391 struct apply
1393 typedef T type;
1397 template<class List, class T>
1398 struct assert_converter_policy_impl
1400 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1403 template<class List>
1404 struct find_converter_policy_impl
1406 typedef typename List::head head;
1407 typedef typename List::tail tail;
1409 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1410 , typename assert_converter_policy_impl<tail, head>::type
1411 , typename find_converter_policy_impl<tail>::type
1412 >::type type;
1415 template<>
1416 struct find_converter_policy_impl<detail::null_type>
1418 typedef default_policy type;
1423 namespace converters
1425 template<class T>
1426 struct FROM
1428 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1430 template<class U, int N>
1431 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1433 typename luabind::detail::default_policy
1434 ::generate_converter<T, detail::lua_to_cpp>::type c;
1435 return static_cast<U>(c.apply(L,
1436 LUABIND_DECORATE_TYPE(T), index));
1439 template<class U>
1440 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1442 typedef typename luabind::detail::default_policy
1443 ::generate_converter<T, detail::lua_to_cpp>::type c;
1445 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1447 std::pair<int,int> result = TO<N + 1, U>
1448 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1450 if (my_match < result.first() && my_match != -1)
1451 return std::make_pair(my_match, N);
1452 else
1453 return result;
1461 namespace luabind { namespace
1463 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1464 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1467 #include <luabind/detail/object_funs.hpp>
1469 #endif // LUABIND_POLICY_HPP_INCLUDED