*** empty log message ***
[luabind.git] / luabind / detail / policy.hpp
blob7dbd9a140818f9b7239db876c98388e78bcc136a
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/mpl/bool.hpp>
33 #include <boost/mpl/integral_c.hpp>
34 #include <boost/mpl/equal_to.hpp>
35 #include <boost/type_traits/add_reference.hpp>
36 #include <boost/limits.hpp>
38 #include <luabind/detail/class_registry.hpp>
39 #include <luabind/detail/primitives.hpp>
40 #include <luabind/detail/object_rep.hpp>
41 #include <luabind/detail/typetraits.hpp>
43 #include <boost/type_traits/add_reference.hpp>
45 #include <luabind/detail/decorate_type.hpp>
46 #include <luabind/object.hpp>
47 #include <luabind/detail/make_instance.hpp>
48 #include <luabind/pointer_holder.hpp>
50 namespace luabind
52 namespace detail
54 struct conversion_policy_base {};
57 template<int N, bool HasArg = true>
58 struct conversion_policy : detail::conversion_policy_base
60 BOOST_STATIC_CONSTANT(int, index = N);
61 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
64 class index_map
66 public:
68 index_map(const int* m): m_map(m) {}
70 int operator[](int index) const
72 return m_map[index + 1];
75 private:
77 const int* m_map;
80 namespace converters
82 using luabind::detail::yes_t;
83 using luabind::detail::no_t;
84 using luabind::detail::by_value;
85 using luabind::detail::by_reference;
86 using luabind::detail::by_const_reference;
87 using luabind::detail::by_pointer;
88 using luabind::detail::by_const_pointer;
90 no_t is_user_defined(...);
92 template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
93 template<> struct yes_no<false> : no_t { typedef no_t type; };
95 template<int N, class T>
96 struct TO
98 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
100 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
102 return std::make_pair(-1,-1);
105 template<int I>
106 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
109 no_t is_implicit_conversion(...);
111 template<class T>
112 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
114 template<class T>
115 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
117 template<class T>
118 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
120 template<class T>
121 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
123 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
126 namespace detail
128 template<class T>
129 struct is_user_defined
131 BOOST_STATIC_CONSTANT(bool, value =
132 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
135 /* template<class T>
136 struct is_implicit_conversion
138 BOOST_STATIC_CONSTANT(bool, value =
139 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
142 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
145 template<class T> class functor;
146 class object;
149 namespace luabind { namespace detail
151 template<class>
152 struct is_primitive;
154 template<class T>
155 yes_t is_lua_functor_test(const functor<T>&);
157 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
158 no_t is_lua_functor_test(...);
159 #else
160 template<class T>
161 no_t is_lua_functor_test(const T&);
162 #endif
164 template<class T>
165 struct is_lua_functor
167 static T t;
169 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
172 namespace
174 static char msvc_fix[64];
177 template<class T>
178 struct indirect_type
180 typedef typename
181 boost::mpl::if_<is_primitive<T>
182 , const type<T>&
183 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
184 , identity<T>
185 , boost::add_reference<T>
186 >::type
187 >::type result_type;
189 static inline result_type get()
191 return reinterpret_cast<result_type>(msvc_fix);
195 template<class H, class T>
196 struct policy_cons
198 typedef H head;
199 typedef T tail;
201 template<class U>
202 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
204 return policy_cons<U, policy_cons<H,T> >();
207 template<class U>
208 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
210 return policy_cons<U, policy_cons<H,T> >();
213 template<class U>
214 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
216 return policy_cons<U, policy_cons<H,T> >();
220 struct indirection_layer
222 template<class T>
223 indirection_layer(const T&);
226 template<class H, class T>
227 yes_t is_policy_cons_test(const policy_cons<H,T>&);
228 no_t is_policy_cons_test(...);
230 template<class T>
231 struct is_policy_cons
233 static const T& t;
235 BOOST_STATIC_CONSTANT(bool, value =
236 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
239 no_t is_string_literal(indirection_layer);
240 yes_t is_string_literal(const char*);
242 template<class T>
243 struct is_primitive/*: boost::mpl::bool_c<false>*/
245 static T t;
247 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_string_literal(t)) == sizeof(yes_t));
250 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
251 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
252 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
254 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
255 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
256 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
257 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
258 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
259 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
260 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
261 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
262 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
263 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
264 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
265 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
266 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
268 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
269 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
270 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
271 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
272 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
273 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
274 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
275 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
276 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
277 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
278 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
279 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
280 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
281 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
283 // TODO: add more
284 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
285 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
286 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
287 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
288 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
289 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
290 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
291 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
292 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
293 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
294 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
295 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
297 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
298 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
299 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
302 template<class Direction> struct primitive_converter;
304 template<>
305 struct primitive_converter<cpp_to_lua>
307 void apply(lua_State* L, const luabind::object& v)
309 // if you hit this assert you are trying to return a value from one state into another lua state
310 assert((v.lua_state() == L) && "you cannot return a value from one lua state into another");
311 v.pushvalue();
313 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
314 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
315 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
316 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
317 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
318 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
319 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
320 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
321 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
322 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
323 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
324 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
325 void apply(lua_State* L, const std::string& v) { lua_pushstring(L, v.c_str()); }
326 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
329 template<>
330 struct primitive_converter<lua_to_cpp>
332 #define PRIMITIVE_CONVERTER(prim) \
333 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
334 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
335 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
337 #define PRIMITIVE_MATCHER(prim) \
338 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
339 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
340 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
342 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; }
343 PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; }
345 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); }
346 PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
348 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
349 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
351 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); }
352 PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
354 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); }
355 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
357 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); }
358 PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
360 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); }
361 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
363 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); }
364 PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
366 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); }
367 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
369 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); }
370 PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
372 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); }
373 PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
375 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
376 PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; }
378 PRIMITIVE_CONVERTER(luabind::object)
380 lua_pushvalue(L, index);
381 return luabind::object(L, detail::ref(L), true);
384 PRIMITIVE_MATCHER(luabind::object) { return std::numeric_limits<int>::max() - 1; }
386 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
387 const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
388 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
389 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;}
391 /* template<class T>
392 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
394 // TODO: add more
395 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
396 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
397 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
398 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
399 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
400 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
401 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
402 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
403 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
404 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
405 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
406 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
408 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
409 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
410 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
411 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
412 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
413 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
414 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
416 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
417 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
418 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
419 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
421 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
422 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
423 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
424 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
426 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
428 lua_pushvalue(L, index);
429 return luabind::object(L, detail::ref(L), true);
432 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
434 lua_pushvalue(L, index);
435 return luabind::object(L, detail::ref(L), true);
438 // TODO: add more
440 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
442 // matchers
443 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
444 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
445 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
446 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;}
447 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
448 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
449 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
450 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
451 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;}
452 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;}
453 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;}
454 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;}
455 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;}
456 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;}
457 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
458 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
460 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
461 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;}
463 template<class T>
464 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
467 template<class T>
468 void converter_postcall(lua_State*, T, int) {}
470 #undef PRIMITIVE_MATCHER
471 #undef PRIMITIVE_CONVERTER
476 // *********** default converters ***************
478 /* template<class> struct implicit_converter;
480 template<>
481 struct implicit_converter<lua_to_cpp>
483 int converter_index;
485 template<class T>
486 T apply(lua_State* L, detail::by_value<T>, int index)
488 return converters::TO<T>::convert(L, detail::type<T>(), index);
491 template<class T>
492 static int match(lua_State* L, detail::by_value<T>, int index)
494 return converters::TO<T>::match(L, detail::type<T>(), index);
497 template<class T>
498 T apply(lua_State* L, detail::by_const_reference<T>, int index)
500 return converters::TO<T>::convert(L, detail::type<T>(), index);
503 template<class T>
504 static int match(lua_State* L, detail::by_const_reference<T>, int index)
506 return converters::TO<T>::match(L, detail::type<T>(), index);
509 template<class T>
510 T* apply(lua_State* L, detail::by_pointer<T>, int index)
512 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
515 template<class T>
516 static int match(lua_State* L, detail::by_pointer<T>, int index)
518 return converters::TO<T*>::match(L, detail::type<T*>(), index);
521 template<class T>
522 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
524 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
527 template<class T>
528 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
530 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
533 template<class T>
534 void converter_postcall(lua_State*, T, int) {}
538 // ********** user defined converter ***********
540 template<class Direction> struct user_defined_converter;
542 template<>
543 struct user_defined_converter<lua_to_cpp>
545 template<class T>
546 T apply(lua_State* L, detail::by_value<T>, int index)
548 // std::cerr << "user_defined_converter\n";
549 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
552 template<class T>
553 T apply(lua_State* L, detail::by_reference<T>, int index)
555 // std::cerr << "user_defined_converter\n";
556 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
559 template<class T>
560 T apply(lua_State* L, detail::by_const_reference<T>, int index)
562 // std::cerr << "user_defined_converter\n";
563 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
566 template<class T>
567 T* apply(lua_State* L, detail::by_pointer<T>, int index)
569 // std::cerr << "user_defined_converter\n";
570 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
573 template<class T>
574 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
576 // std::cerr << "user_defined_converter\n";
577 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
580 template<class T>
581 static int match(lua_State* L, T, int index)
583 return converters::match_lua_to_cpp(L, T(), index);
586 template<class T>
587 void converter_postcall(lua_State*, T, int) {}
590 template<>
591 struct user_defined_converter<cpp_to_lua>
593 template<class T>
594 void apply(lua_State* L, const T& v)
596 converters::convert_cpp_to_lua(L, v);
600 // ********** pointer converter ***********
603 template<class Direction> struct pointer_converter;
605 template<>
606 struct pointer_converter<cpp_to_lua>
608 template<class T>
609 void apply(lua_State* L, T* ptr)
611 if (ptr == 0)
613 lua_pushnil(L);
614 return;
617 class_registry* registry = class_registry::get_registry(L);
618 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
620 // if you get caught in this assert you are
621 // trying to use an unregistered type
622 assert(crep && "you are trying to use an unregistered type");
624 // create the struct to hold the object
625 void* obj = lua_newuserdata(L, sizeof(object_rep));
626 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
627 new(obj) object_rep(ptr, crep, 0, 0);
629 // set the meta table
630 detail::getref(L, crep->metatable_ref());
631 lua_setmetatable(L, -2);
633 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
637 template<class T> struct make_pointer { typedef T* type; };
638 template<>
639 struct pointer_converter<lua_to_cpp>
641 bool made_conversion;
642 char target[32];
644 template<class T>
645 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
647 // preconditions:
648 // lua_isuserdata(L, index);
649 // getmetatable().__lua_class is true
650 // object_rep->flags() & object_rep::constant == 0
652 if (lua_isnil(L, index)) return 0;
654 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
655 assert((obj != 0) && "internal error, please report"); // internal error
656 const class_rep* crep = obj->crep();
658 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
660 void* result = boost::langbinding::inheritance_graph::instance().find_dynamic_type(
661 obj->ptr()
662 , LUABIND_TYPEID(T)
663 , crep->type());
665 made_conversion = false;
667 return (T*)result;
669 made_conversion = (void*)ptr == (char*)target;
670 assert(!made_conversion || sizeof(T) <= 32);
672 // std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
674 return ptr;
677 template<class T>
678 static int match(lua_State* L, by_pointer<T>, int index)
680 if (lua_isnil(L, index)) return 0;
681 object_rep* obj = is_class_object(L, index);
682 if (obj == 0) return -1;
683 // cannot cast a constant object to nonconst
684 if (obj->flags() & object_rep::constant) return -1;
686 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
687 return (obj->flags() & object_rep::constant)?-1:0;
688 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
689 return (obj->flags() & object_rep::constant)?0:-1;
692 int d;
693 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
696 template<class T>
697 void converter_postcall(lua_State*, by_pointer<T>, int)
699 if (made_conversion)
700 reinterpret_cast<T*>(target)->~T();
704 // ******* value converter *******
706 template<class Direction> struct value_converter;
708 template<>
709 struct value_converter<cpp_to_lua>
711 template<class T>
712 void apply(lua_State* L, const T& ref)
714 class_registry* registry = class_registry::get_registry(L);
715 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
717 // if you get caught in this assert you are
718 // trying to use an unregistered type
719 assert(crep && "you are trying to use an unregistered type");
721 void* obj_rep;
722 void* held;
724 boost::tie(obj_rep,held) = crep->allocate(L);
726 void* object_ptr;
727 void(*destructor)(void*);
728 destructor = crep->destructor();
729 int flags = object_rep::owner;
730 if (crep->has_holder())
732 new(held) T(ref);
733 object_ptr = held;
734 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
736 flags |= object_rep::constant;
737 destructor = crep->const_holder_destructor();
740 else
742 object_ptr = new T(ref);
744 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
746 // set the meta table
747 detail::getref(L, crep->metatable_ref());
748 lua_setmetatable(L, -2);
753 template<class T> struct make_const_reference { typedef const T& type; };
755 template<class T>
756 struct destruct_guard
758 T* ptr;
759 bool dismiss;
760 destruct_guard(T* p): ptr(p), dismiss(false) {}
762 ~destruct_guard()
764 if (!dismiss)
765 ptr->~T();
769 template<>
770 struct value_converter<lua_to_cpp>
772 template<class T>
773 /*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
775 // preconditions:
776 // lua_isuserdata(L, index);
777 // getmetatable().__lua_class is true
778 // object_rep->flags() & object_rep::constant == 0
780 assert((lua_isnil(L, index) == false) && "internal error, please report");
782 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
783 assert((obj != 0) && "internal error, please report"); // internal error
784 const class_rep* crep = obj->crep();
786 // TODO: align?
787 char target[sizeof(T)];
788 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
790 destruct_guard<T> guard(ptr);
791 if ((void*)ptr != (void*)target) guard.dismiss = true;
793 return *ptr;
796 template<class T>
797 static int match(lua_State* L, by_value<T>, int index)
799 if (lua_isnil(L, index)) return 0;
800 object_rep* obj = is_class_object(L, index);
801 if (obj == 0) return -1;
802 int d;
804 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
805 return (obj->flags() & object_rep::constant)?-1:0;
806 // if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
807 // return 0;
808 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
809 return (obj->flags() & object_rep::constant)?0:1;
811 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
814 template<class T>
815 void converter_postcall(lua_State*, T, int) {}
818 // ******* const pointer converter *******
820 template<class Direction> struct const_pointer_converter;
822 template<>
823 struct const_pointer_converter<cpp_to_lua>
825 template<class T>
826 void apply(lua_State* L, const T* ptr)
828 if (ptr == 0)
830 lua_pushnil(L);
831 return;
834 class_registry* registry = class_registry::get_registry(L);
835 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
837 // if you get caught in this assert you are
838 // trying to use an unregistered type
839 assert(crep && "you are trying to use an unregistered type");
841 // create the struct to hold the object
842 void* obj = lua_newuserdata(L, sizeof(object_rep));
843 assert(obj && "internal error, please report");
844 // we send 0 as destructor since we know it will never be called
845 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
847 // set the meta table
848 detail::getref(L, crep->metatable_ref());
849 lua_setmetatable(L, -2);
854 template<class T> struct make_const_pointer { typedef const T* type; };
855 template<>
856 struct const_pointer_converter<lua_to_cpp>
857 : private pointer_converter<lua_to_cpp>
859 template<class T>
860 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
862 // std::cerr << "const_pointer_converter\n";
863 return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
866 template<class T>
867 static int match(lua_State* L, by_const_pointer<T>, int index)
869 if (lua_isnil(L, index)) return 0;
870 object_rep* obj = is_class_object(L, index);
871 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
873 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
874 return (obj->flags() & object_rep::constant)?-1:0;
875 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
876 return (obj->flags() & object_rep::constant)?0:1;
878 int d;
879 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
882 template<class T>
883 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
885 pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
889 // ******* reference converter *******
891 template<class Direction> struct ref_converter;
893 template<>
894 struct ref_converter<cpp_to_lua>
896 template<class T>
897 void apply(lua_State* L, T& ref)
899 class_registry* registry = class_registry::get_registry(L);
900 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
902 // if you get caught in this assert you are
903 // trying to use an unregistered type
904 assert(crep && "you are trying to use an unregistered type");
906 T* ptr = &ref;
908 // create the struct to hold the object
909 void* obj = lua_newuserdata(L, sizeof(object_rep));
910 assert(obj && "internal error, please report");
911 new(obj) object_rep(ptr, crep, 0, 0);
913 // set the meta table
914 detail::getref(L, crep->metatable_ref());
915 lua_setmetatable(L, -2);
919 template<class T> struct make_reference { typedef T& type; };
920 template<>
921 struct ref_converter<lua_to_cpp>
923 template<class T>
924 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
926 // std::cerr << "ref_converter<lua_to_cpp>\n";
927 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
930 template<class T>
931 static int match(lua_State* L, by_reference<T>, int index)
933 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
936 template<class T>
937 void converter_postcall(lua_State*, T, int) {}
940 // ******** const reference converter *********
942 template<class Direction> struct const_ref_converter;
944 template<>
945 struct const_ref_converter<cpp_to_lua>
947 template<class T>
948 void apply(lua_State* L, const T& ref)
950 class_registry* registry = class_registry::get_registry(L);
951 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
953 // if you get caught in this assert you are
954 // trying to use an unregistered type
955 assert(crep && "you are trying to use an unregistered type");
958 void* obj_rep;
959 void* held;
961 boost::tie(obj_rep,held) = crep->allocate(L);
963 void* object_ptr;
964 void(*destructor)(void*);
965 destructor = crep->destructor();
966 int flags = 0;
967 if (crep->has_holder())
969 flags = object_rep::owner;
970 new(held) T(ref);
971 object_ptr = held;
972 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
974 flags |= object_rep::constant;
975 destructor = crep->const_holder_destructor();
978 else
980 object_ptr = new T(ref);
982 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
984 // set the meta table
985 detail::getref(L, crep->metatable_ref());
986 lua_setmetatable(L, -2);
990 template<>
991 struct const_ref_converter<lua_to_cpp>
992 : private const_pointer_converter<lua_to_cpp>
994 template<class T>
995 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
997 // std::cerr << "const_ref_converter<lua_to_cpp>\n";
998 return *const_pointer_converter<lua_to_cpp>::apply(L, by_const_pointer<T>(), index);
1001 template<class T>
1002 static int match(lua_State* L, by_const_reference<T>, int index)
1004 return const_pointer_converter<lua_to_cpp>::match(L, by_const_pointer<T>(), index);
1007 template<class T>
1008 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
1010 const_pointer_converter<lua_to_cpp>::converter_postcall(L, by_const_pointer<T>(), index);
1014 // ****** enum converter ********
1016 template<class Direction = cpp_to_lua>
1017 struct enum_converter
1019 void apply(lua_State* L, int val)
1021 lua_pushnumber(L, val);
1025 template<>
1026 struct enum_converter<lua_to_cpp>
1028 template<class T>
1029 T apply(lua_State* L, by_value<T>, int index)
1031 // std::cerr << "enum_converter\n";
1032 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
1035 template<class T>
1036 static int match(lua_State* L, by_value<T>, int index)
1038 if (lua_isnumber(L, index)) return 0; else return -1;
1041 template<class T>
1042 void converter_postcall(lua_State*, T, int) {}
1045 // ****** functor converter ********
1047 template<class Direction> struct functor_converter;
1049 template<>
1050 struct functor_converter<lua_to_cpp>
1052 template<class T>
1053 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
1055 if (lua_isnil(L, index))
1056 return functor<T>();
1058 lua_pushvalue(L, index);
1059 int ref = detail::ref(L);
1060 return functor<T>(L, ref);
1063 template<class T>
1064 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
1066 if (lua_isnil(L, index))
1067 return functor<T>();
1069 lua_pushvalue(L, index);
1070 int ref = detail::ref(L);
1071 return functor<T>(L, ref);
1074 template<class T>
1075 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
1077 if (lua_isfunction(L, index)) return 0; else return -1;
1080 template<class T>
1081 static int match(lua_State* L, by_value<functor<T> >, int index)
1083 if (lua_isfunction(L, index)) return 0; else return -1;
1086 template<class T>
1087 void converter_postcall(lua_State*, T, int) {}
1094 // *********** default_policy *****************
1098 struct default_policy : converter_policy_tag
1100 BOOST_STATIC_CONSTANT(bool, has_arg = true);
1102 template<class T>
1103 static void precall(lua_State*, T, int) {}
1105 // template<class T>
1106 // static void postcall(lua_State*, T, int) {}
1108 template<class T, class Direction>
1109 struct generate_converter
1111 typedef typename boost::mpl::if_<is_user_defined<T>
1112 , user_defined_converter<Direction>
1113 // , typename boost::mpl::if_<is_implicit_conversion<T>
1114 // , implicit_converter<Direction>
1115 , typename boost::mpl::if_<is_primitive<T>
1116 , primitive_converter<Direction>
1117 , typename boost::mpl::if_<is_lua_functor<T>
1118 , functor_converter<Direction>
1119 , typename boost::mpl::if_<boost::is_enum<T>
1120 , enum_converter<Direction>
1121 , typename boost::mpl::if_<is_nonconst_pointer<T>
1122 , pointer_converter<Direction>
1123 , typename boost::mpl::if_<is_const_pointer<T>
1124 , const_pointer_converter<Direction>
1125 , typename boost::mpl::if_<is_nonconst_reference<T>
1126 , ref_converter<Direction>
1127 , typename boost::mpl::if_<is_const_reference<T>
1128 , const_ref_converter<Direction>
1129 , value_converter<Direction>
1130 >::type>::type>::type>::type>::type>::type>::type>::type type;
1134 // ********** get policy **********
1136 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1137 template<int N, class T>
1138 struct get_policy_list_impl
1140 template<class U>
1141 struct inner
1143 typedef typename U::head head;
1144 typedef typename U::tail tail;
1146 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1147 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
1148 , typename get_policy_list_impl<N, tail>::type
1149 >::type type;
1152 template<>
1153 struct inner<null_type>
1155 typedef null_type type;
1158 typedef typename inner<T>::type type;
1160 #else
1161 template<class List>
1162 struct get_policy_list_impl
1164 template<int N>
1165 struct apply
1167 typedef typename List::head head;
1168 typedef typename List::tail tail;
1170 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1171 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
1172 , typename get_policy_list_impl<tail>::template apply<N>::type
1173 >::type type;
1177 template<>
1178 struct get_policy_list_impl<detail::null_type>
1180 template<int N>
1181 struct apply
1183 typedef null_type type;
1186 #endif
1188 template<int N, class T>
1189 struct get_policy_list
1191 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1192 typedef typename get_policy_list_impl<N, T>::type type;
1193 #else
1194 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
1195 #endif
1198 // ============== new policy system =================
1200 template<int, class> struct find_conversion_policy;
1202 template<bool IsConverter = false>
1203 struct find_conversion_impl
1205 template<int N, class Policies>
1206 struct apply
1208 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
1212 template<>
1213 struct find_conversion_impl<true>
1215 template<int N, class Policies>
1216 struct apply
1218 typedef typename Policies::head head;
1219 typedef typename Policies::tail tail;
1221 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
1223 typedef typename
1224 boost::mpl::if_c<found
1225 , head
1226 , typename find_conversion_policy<N, tail>::type
1227 >::type type;
1231 template<class Policies>
1232 struct find_conversion_impl2
1234 template<int N>
1235 struct apply
1236 : find_conversion_impl<
1237 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
1238 >::template apply<N, Policies>
1243 template<>
1244 struct find_conversion_impl2<detail::null_type>
1246 template<int N>
1247 struct apply
1249 typedef default_policy type;
1253 template<int N, class Policies>
1254 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
1258 template<class List>
1259 struct policy_list_postcall
1261 typedef typename List::head head;
1262 typedef typename List::tail tail;
1264 static void apply(lua_State* L, const index_map& i)
1266 head::postcall(L, i);
1267 policy_list_postcall<tail>::apply(L, i);
1271 template<>
1272 struct policy_list_postcall<detail::null_type>
1274 static void apply(lua_State*, const index_map&) {}
1277 /* template<int N>
1278 struct find_conversion_policy<N, detail::null_type>
1280 typedef default_policy type;
1281 };*/
1283 // ==================================================
1285 // ************** precall and postcall on policy_cons *********************
1288 template<class List>
1289 struct policy_precall
1291 typedef typename List::head head;
1292 typedef typename List::tail tail;
1294 static void apply(lua_State* L, int index)
1296 head::precall(L, index);
1297 policy_precall<tail>::apply(L, index);
1301 template<>
1302 struct policy_precall<detail::null_type>
1304 static void apply(lua_State*, int) {}
1307 template<class List>
1308 struct policy_postcall
1310 typedef typename List::head head;
1311 typedef typename List::tail tail;
1313 static void apply(lua_State* L, int index)
1315 head::postcall(L, index);
1316 policy_postcall<tail>::apply(L, index);
1320 template<>
1321 struct policy_postcall<detail::null_type>
1323 static void apply(lua_State*, int) {}
1327 struct pointer_only_converter
1329 template<class T>
1330 static const T* apply(lua_State* L, type<const T*>, int index)
1332 int a = index;
1336 struct only_one_converter_policy_can_be_used_per_index {};
1338 template<class List, class T> struct assert_converter_policy_impl;
1340 template<class List>
1341 struct assert_converter_policy
1343 template<class T>
1344 struct apply
1346 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1347 , only_one_converter_policy_can_be_used_per_index
1348 , typename assert_converter_policy_impl<typename List::tail, T>::type
1349 >::type type;
1353 template<>
1354 struct assert_converter_policy<detail::null_type>
1356 template<class T>
1357 struct apply
1359 typedef T type;
1363 template<class List, class T>
1364 struct assert_converter_policy_impl
1366 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1369 template<class List>
1370 struct find_converter_policy_impl
1372 typedef typename List::head head;
1373 typedef typename List::tail tail;
1375 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1376 , typename assert_converter_policy_impl<tail, head>::type
1377 , typename find_converter_policy_impl<tail>::type
1378 >::type type;
1381 template<>
1382 struct find_converter_policy_impl<detail::null_type>
1384 typedef default_policy type;
1389 namespace converters
1391 template<class T>
1392 struct FROM
1394 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1396 template<class U, int N>
1397 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1399 typename luabind::detail::default_policy
1400 ::generate_converter<T, detail::lua_to_cpp>::type c;
1401 return static_cast<U>(c.apply(L,
1402 LUABIND_DECORATE_TYPE(T), index));
1405 template<class U>
1406 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1408 typedef typename luabind::detail::default_policy
1409 ::generate_converter<T, detail::lua_to_cpp>::type c;
1411 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1413 std::pair<int,int> result = TO<N + 1, U>
1414 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1416 if (my_match < result.first() && my_match != -1)
1417 return std::make_pair(my_match, N);
1418 else
1419 return result;
1427 namespace luabind { namespace
1429 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1430 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1433 #include <luabind/detail/object_funs.hpp>
1435 #endif // LUABIND_POLICY_HPP_INCLUDED