converted some tests to Boost.Test
[luabind.git] / luabind / detail / policy.hpp
blob7ed9832f195161ee6e7099508e1b5e3e7e5a5bf4
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/mpl/apply_if.hpp>
37 #include <boost/mpl/or.hpp>
38 #include <boost/type_traits/add_reference.hpp>
39 #include <boost/type_traits/is_pointer.hpp>
40 #include <boost/type_traits/is_base_and_derived.hpp>
41 #include <boost/bind/arg.hpp>
42 #include <boost/limits.hpp>
44 #include <luabind/detail/class_registry.hpp>
45 #include <luabind/detail/primitives.hpp>
46 #include <luabind/detail/object_rep.hpp>
47 #include <luabind/detail/typetraits.hpp>
48 #include <luabind/detail/class_cache.hpp>
49 #include <luabind/detail/debug.hpp>
51 #include <boost/type_traits/add_reference.hpp>
53 #include <luabind/detail/decorate_type.hpp>
54 #include <luabind/object.hpp>
55 //#include <luabind/detail/make_instance.hpp>
56 //#include <luabind/pointer_holder.hpp>
58 namespace luabind
60 namespace detail
62 struct conversion_policy_base {};
65 template<int N, bool HasArg = true>
66 struct conversion_policy : detail::conversion_policy_base
68 BOOST_STATIC_CONSTANT(int, index = N);
69 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
72 class index_map
74 public:
76 index_map(const int* m): m_map(m) {}
78 int operator[](int index) const
80 return m_map[index + 1];
83 private:
85 const int* m_map;
88 namespace converters
90 using luabind::detail::yes_t;
91 using luabind::detail::no_t;
92 using luabind::detail::by_value;
93 using luabind::detail::by_reference;
94 using luabind::detail::by_const_reference;
95 using luabind::detail::by_pointer;
96 using luabind::detail::by_const_pointer;
98 no_t is_user_defined(...);
100 // template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
101 // template<> struct yes_no<false> : no_t { typedef no_t type; };
103 template<int N, class T>
104 struct TO
106 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
108 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
110 return std::make_pair(-1,-1);
113 template<int I>
114 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
117 no_t is_implicit_conversion(...);
119 template<class T>
120 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
122 template<class T>
123 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
125 template<class T>
126 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
128 template<class T>
129 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
131 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
134 namespace detail
136 template<class T>
137 struct is_user_defined
139 BOOST_STATIC_CONSTANT(bool, value =
140 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
143 /* template<class T>
144 struct is_implicit_conversion
146 BOOST_STATIC_CONSTANT(bool, value =
147 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
150 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
153 template<class T> class functor;
154 class object;
157 namespace luabind { namespace detail
159 template<class>
160 struct is_primitive;
162 template<class T>
163 yes_t is_lua_functor_test(const functor<T>&);
165 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
166 no_t is_lua_functor_test(...);
167 #else
168 template<class T>
169 no_t is_lua_functor_test(const T&);
170 #endif
172 template<class T>
173 struct is_lua_functor
175 static T t;
177 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
180 namespace
182 static char msvc_fix[64];
185 template<class T>
186 struct indirect_type
188 typedef typename
189 boost::mpl::if_<is_primitive<T>
190 , const type<T>&
191 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
192 , identity<T>
193 , boost::add_reference<T>
194 >::type
195 >::type result_type;
197 static inline result_type get()
199 return reinterpret_cast<result_type>(msvc_fix);
203 template<class H, class T>
204 struct policy_cons
206 typedef H head;
207 typedef T tail;
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> >();
221 template<class U>
222 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
224 return policy_cons<U, policy_cons<H,T> >();
228 struct indirection_layer
230 template<class T>
231 indirection_layer(const T&);
234 template<class H, class T>
235 yes_t is_policy_cons_test(const policy_cons<H,T>&);
236 no_t is_policy_cons_test(...);
238 template<class T>
239 struct is_policy_cons
241 static const T& t;
243 BOOST_STATIC_CONSTANT(bool, value =
244 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
247 template<bool>
248 struct is_string_literal
250 static no_t helper(indirection_layer);
251 static yes_t helper(const char*);
254 template<>
255 struct is_string_literal<false>
257 static no_t helper(indirection_layer);
261 template<class T>
262 struct is_primitive/*: boost::mpl::bool_c<false>*/
264 static T t;
266 BOOST_STATIC_CONSTANT(bool, value =
267 sizeof(is_string_literal<boost::is_array<T>::value>::helper(t)) == sizeof(yes_t));
270 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
271 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
272 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
274 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
275 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
276 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
277 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
278 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
279 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
280 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
281 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
282 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
283 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
284 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
285 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
286 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
288 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
289 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
290 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
291 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
292 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
293 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
294 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
295 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
296 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
297 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
298 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
299 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
300 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
301 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
303 // TODO: add more
304 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
305 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
306 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
307 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
308 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
309 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
310 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
311 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
312 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
313 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
314 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
315 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
317 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
318 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
319 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
322 template<class Direction> struct primitive_converter;
324 template<>
325 struct primitive_converter<cpp_to_lua>
327 void apply(lua_State* L, const luabind::object& v)
329 // if the luabind::object is uninitialized
330 // treat it as nil.
331 if (v.lua_state() == 0)
333 lua_pushnil(L);
334 return;
336 // if you hit this assert you are trying to return a value from one state into another lua state
337 assert((v.lua_state() == L) && "you cannot return an uninitilized value "
338 "or a value from one lua state into another");
339 v.pushvalue();
341 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
342 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
343 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
344 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
345 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
346 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
347 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
348 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
349 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
350 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
351 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
352 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
353 void apply(lua_State* L, const std::string& v)
354 { lua_pushlstring(L, v.data(), v.size()); }
355 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
358 template<>
359 struct primitive_converter<lua_to_cpp>
361 #define PRIMITIVE_CONVERTER(prim) \
362 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
363 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
364 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
366 #define PRIMITIVE_MATCHER(prim) \
367 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
368 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
369 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
371 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; }
372 PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; }
374 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); }
375 PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
377 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
378 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
380 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); }
381 PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
383 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); }
384 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
386 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); }
387 PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
389 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); }
390 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
392 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); }
393 PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
395 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); }
396 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
398 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); }
399 PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
401 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); }
402 PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
404 PRIMITIVE_CONVERTER(std::string)
405 { return std::string(lua_tostring(L, index), lua_strlen(L, index)); }
406 PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; }
408 PRIMITIVE_CONVERTER(luabind::object)
410 LUABIND_CHECK_STACK(L);
412 lua_pushvalue(L, index);
413 detail::lua_reference ref;
414 ref.set(L);
415 return luabind::object(L, ref, true);
418 PRIMITIVE_MATCHER(luabind::object) { return std::numeric_limits<int>::max() - 1; }
420 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
421 const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
422 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
423 static int match(lua_State* L, by_const_pointer<const char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
425 /* template<class T>
426 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
428 // TODO: add more
429 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
430 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
431 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
432 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
433 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
434 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
435 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
436 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
437 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
438 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
439 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
440 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
442 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
443 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
444 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
445 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
446 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
447 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
448 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
450 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
451 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
452 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
453 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
455 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
456 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
457 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
458 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
460 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
462 lua_pushvalue(L, index);
463 return luabind::object(L, detail::ref(L), true);
466 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
468 lua_pushvalue(L, index);
469 return luabind::object(L, detail::ref(L), true);
472 // TODO: add more
474 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
476 // matchers
477 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
478 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
479 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
480 static int match(lua_State* L, detail::by_value<long double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
481 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
482 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
483 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
484 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
485 static int match(lua_State* L, detail::by_value<unsigned int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
486 static int match(lua_State* L, detail::by_value<unsigned short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
487 static int match(lua_State* L, detail::by_value<unsigned char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
488 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;}
489 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;}
490 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;}
491 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
492 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
494 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
495 static int match(lua_State* L, by_const_pointer<const char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
497 template<class T>
498 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
501 template<class T>
502 void converter_postcall(lua_State*, T, int) {}
504 #undef PRIMITIVE_MATCHER
505 #undef PRIMITIVE_CONVERTER
510 // *********** default converters ***************
512 /* template<class> struct implicit_converter;
514 template<>
515 struct implicit_converter<lua_to_cpp>
517 int converter_index;
519 template<class T>
520 T apply(lua_State* L, detail::by_value<T>, int index)
522 return converters::TO<T>::convert(L, detail::type<T>(), index);
525 template<class T>
526 static int match(lua_State* L, detail::by_value<T>, int index)
528 return converters::TO<T>::match(L, detail::type<T>(), index);
531 template<class T>
532 T apply(lua_State* L, detail::by_const_reference<T>, int index)
534 return converters::TO<T>::convert(L, detail::type<T>(), index);
537 template<class T>
538 static int match(lua_State* L, detail::by_const_reference<T>, int index)
540 return converters::TO<T>::match(L, detail::type<T>(), index);
543 template<class T>
544 T* apply(lua_State* L, detail::by_pointer<T>, int index)
546 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
549 template<class T>
550 static int match(lua_State* L, detail::by_pointer<T>, int index)
552 return converters::TO<T*>::match(L, detail::type<T*>(), index);
555 template<class T>
556 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
558 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
561 template<class T>
562 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
564 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
567 template<class T>
568 void converter_postcall(lua_State*, T, int) {}
572 // ********** user defined converter ***********
574 template<class Direction> struct user_defined_converter;
576 template<>
577 struct user_defined_converter<lua_to_cpp>
579 template<class T>
580 T apply(lua_State* L, detail::by_value<T>, int index)
582 // std::cerr << "user_defined_converter\n";
583 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
586 template<class T>
587 T apply(lua_State* L, detail::by_reference<T>, int index)
589 // std::cerr << "user_defined_converter\n";
590 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
593 template<class T>
594 T apply(lua_State* L, detail::by_const_reference<T>, int index)
596 // std::cerr << "user_defined_converter\n";
597 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
600 template<class T>
601 T* apply(lua_State* L, detail::by_pointer<T>, int index)
603 // std::cerr << "user_defined_converter\n";
604 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
607 template<class T>
608 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
610 // std::cerr << "user_defined_converter\n";
611 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
614 template<class T>
615 static int match(lua_State* L, T, int index)
617 return converters::match_lua_to_cpp(L, T(), index);
620 template<class T>
621 void converter_postcall(lua_State*, T, int) {}
624 template<>
625 struct user_defined_converter<cpp_to_lua>
627 template<class T>
628 void apply(lua_State* L, const T& v)
630 converters::convert_cpp_to_lua(L, v);
634 // ********** pointer converter ***********
637 template<class Direction> struct pointer_converter;
639 template<>
640 struct pointer_converter<cpp_to_lua>
642 template<class T>
643 void apply(lua_State* L, T* ptr)
645 if (ptr == 0)
647 lua_pushnil(L);
648 return;
651 class_rep* crep = get_class_rep<T>(L);
653 // if you get caught in this assert you are
654 // trying to use an unregistered type
655 assert(crep && "you are trying to use an unregistered type");
657 // create the struct to hold the object
658 void* obj = lua_newuserdata(L, sizeof(object_rep));
659 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
660 new(obj) object_rep(ptr, crep, 0, 0);
662 // set the meta table
663 detail::getref(L, crep->metatable_ref());
664 lua_setmetatable(L, -2);
666 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
670 template<class T> struct make_pointer { typedef T* type; };
671 template<>
672 struct pointer_converter<lua_to_cpp>
674 // TODO: does the pointer converter need this?!
675 char target[32];
676 void (*destructor)(void *);
678 pointer_converter(): destructor(0) {}
680 template<class T>
681 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
683 // preconditions:
684 // lua_isuserdata(L, index);
685 // getmetatable().__lua_class is true
686 // object_rep->flags() & object_rep::constant == 0
688 if (lua_isnil(L, index)) return 0;
690 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
691 assert((obj != 0) && "internal error, please report"); // internal error
692 const class_rep* crep = obj->crep();
694 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
696 if ((void*)ptr == (char*)target) destructor = detail::destruct_only_s<T>::apply;
697 assert(!destructor || sizeof(T) <= 32);
699 return ptr;
702 template<class T>
703 static int match(lua_State* L, by_pointer<T>, int index)
705 if (lua_isnil(L, index)) return 0;
706 object_rep* obj = is_class_object(L, index);
707 if (obj == 0) return -1;
708 // cannot cast a constant object to nonconst
709 if (obj->flags() & object_rep::constant) return -1;
711 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
712 return (obj->flags() & object_rep::constant)?-1:0;
713 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
714 return (obj->flags() & object_rep::constant)?0:-1;
717 int d;
718 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
721 ~pointer_converter()
723 if (destructor) destructor(target);
726 template<class T>
727 void converter_postcall(lua_State*, by_pointer<T>, int)
731 // ******* value converter *******
733 template<class Direction> struct value_converter;
735 template<>
736 struct value_converter<cpp_to_lua>
738 template<class T>
739 void apply(lua_State* L, const T& ref)
741 class_rep* crep = get_class_rep<T>(L);
743 // if you get caught in this assert you are
744 // trying to use an unregistered type
745 assert(crep && "you are trying to use an unregistered type");
747 void* obj_rep;
748 void* held;
750 boost::tie(obj_rep,held) = crep->allocate(L);
752 void* object_ptr;
753 void(*destructor)(void*);
754 destructor = crep->destructor();
755 int flags = object_rep::owner;
756 if (crep->has_holder())
758 new(held) T(ref);
759 object_ptr = held;
760 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
762 flags |= object_rep::constant;
763 destructor = crep->const_holder_destructor();
766 else
768 object_ptr = new T(ref);
770 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
772 // set the meta table
773 detail::getref(L, crep->metatable_ref());
774 lua_setmetatable(L, -2);
779 template<class T> struct make_const_reference { typedef const T& type; };
781 template<class T>
782 struct destruct_guard
784 T* ptr;
785 bool dismiss;
786 destruct_guard(T* p): ptr(p), dismiss(false) {}
788 ~destruct_guard()
790 if (!dismiss)
791 ptr->~T();
795 template<>
796 struct value_converter<lua_to_cpp>
798 template<class T>
799 /*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
801 // preconditions:
802 // lua_isuserdata(L, index);
803 // getmetatable().__lua_class is true
804 // object_rep->flags() & object_rep::constant == 0
806 object_rep* obj = 0;
807 const class_rep* crep = 0;
809 // special case if we get nil in, try to convert the holder type
810 if (lua_isnil(L, index))
812 crep = get_class_rep<T>(L);;
813 assert(crep);
815 else
817 obj = static_cast<object_rep*>(lua_touserdata(L, index));
818 assert((obj != 0) && "internal error, please report"); // internal error
819 crep = obj->crep();
821 assert(crep);
823 // TODO: align!
824 char target[sizeof(T)];
825 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
827 destruct_guard<T> guard(ptr);
828 if ((void*)ptr != (void*)target) guard.dismiss = true;
830 return *ptr;
833 template<class T>
834 static int match(lua_State* L, by_value<T>, int index)
836 // special case if we get nil in, try to match the holder type
837 if (lua_isnil(L, index))
839 class_rep* crep = get_class_rep<T>(L);
840 if (crep == 0) return -1;
841 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
842 return 0;
843 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
844 return 0;
845 return -1;
848 object_rep* obj = is_class_object(L, index);
849 if (obj == 0) return -1;
850 int d;
852 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
853 return (obj->flags() & object_rep::constant)?-1:0;
854 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
855 return (obj->flags() & object_rep::constant)?0:1;
857 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
860 template<class T>
861 void converter_postcall(lua_State*, T, int) {}
864 // ******* const pointer converter *******
866 template<class Direction> struct const_pointer_converter;
868 template<>
869 struct const_pointer_converter<cpp_to_lua>
871 template<class T>
872 void apply(lua_State* L, const T* ptr)
874 if (ptr == 0)
876 lua_pushnil(L);
877 return;
880 class_rep* crep = get_class_rep<T>(L);
882 // if you get caught in this assert you are
883 // trying to use an unregistered type
884 assert(crep && "you are trying to use an unregistered type");
886 // create the struct to hold the object
887 void* obj = lua_newuserdata(L, sizeof(object_rep));
888 assert(obj && "internal error, please report");
889 // we send 0 as destructor since we know it will never be called
890 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
892 // set the meta table
893 detail::getref(L, crep->metatable_ref());
894 lua_setmetatable(L, -2);
899 template<class T> struct make_const_pointer { typedef const T* type; };
900 template<>
901 struct const_pointer_converter<lua_to_cpp>
902 : private pointer_converter<lua_to_cpp>
904 template<class T>
905 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
907 // std::cerr << "const_pointer_converter\n";
908 return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
911 template<class T>
912 static int match(lua_State* L, by_const_pointer<T>, int index)
914 if (lua_isnil(L, index)) return 0;
915 object_rep* obj = is_class_object(L, index);
916 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
918 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
919 return (obj->flags() & object_rep::constant)?-1:0;
920 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
921 return (obj->flags() & object_rep::constant)?0:1;
923 int d;
924 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
927 template<class T>
928 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
930 pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
934 // ******* reference converter *******
936 template<class Direction> struct ref_converter;
938 template<>
939 struct ref_converter<cpp_to_lua>
941 template<class T>
942 void apply(lua_State* L, T& ref)
944 class_rep* crep = get_class_rep<T>(L);
946 // if you get caught in this assert you are
947 // trying to use an unregistered type
948 assert(crep && "you are trying to use an unregistered type");
950 T* ptr = &ref;
952 // create the struct to hold the object
953 void* obj = lua_newuserdata(L, sizeof(object_rep));
954 assert(obj && "internal error, please report");
955 new(obj) object_rep(ptr, crep, 0, 0);
957 // set the meta table
958 detail::getref(L, crep->metatable_ref());
959 lua_setmetatable(L, -2);
963 template<class T> struct make_reference { typedef T& type; };
964 template<>
965 struct ref_converter<lua_to_cpp>
967 template<class T>
968 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
970 // std::cerr << "ref_converter<lua_to_cpp>\n";
971 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
974 template<class T>
975 static int match(lua_State* L, by_reference<T>, int index)
977 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
980 template<class T>
981 void converter_postcall(lua_State*, T, int) {}
984 // ******** const reference converter *********
986 template<class Direction> struct const_ref_converter;
988 template<>
989 struct const_ref_converter<cpp_to_lua>
991 template<class T>
992 void apply(lua_State* L, const T& ref)
994 class_rep* crep = get_class_rep<T>(L);
996 // if you get caught in this assert you are
997 // trying to use an unregistered type
998 assert(crep && "you are trying to use an unregistered type");
1001 void* obj_rep;
1002 void* held;
1004 boost::tie(obj_rep,held) = crep->allocate(L);
1006 void* object_ptr;
1007 void(*destructor)(void*);
1008 destructor = crep->destructor();
1009 int flags = 0;
1010 if (crep->has_holder())
1012 flags = object_rep::owner;
1013 new(held) T(ref);
1014 object_ptr = held;
1015 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
1017 flags |= object_rep::constant;
1018 destructor = crep->const_holder_destructor();
1021 else
1023 object_ptr = new T(ref);
1025 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
1027 // set the meta table
1028 detail::getref(L, crep->metatable_ref());
1029 lua_setmetatable(L, -2);
1033 template<>
1034 struct const_ref_converter<lua_to_cpp>
1036 // TODO: align!
1037 char target[32];
1038 void (*destructor)(void*);
1040 const_ref_converter(): destructor(0) {}
1042 template<class T>
1043 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
1045 object_rep* obj = 0;
1046 class_rep const * crep = 0;
1048 // special case if we get nil in, try to convert the holder type
1049 if (lua_isnil(L, index))
1051 crep = get_class_rep<T>(L);
1052 assert(crep);
1054 else
1056 obj = static_cast<object_rep*>(lua_touserdata(L, index));
1057 assert((obj != 0) && "internal error, please report"); // internal error
1058 crep = obj->crep();
1060 assert(crep);
1062 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
1063 // if the pointer returned points into the converter storage,
1064 // we need to destruct it once the converter destructs
1065 if ((void*)ptr == (void*)target) destructor = detail::destruct_only_s<T>::apply;
1066 assert(!destructor || sizeof(T) <= 32);
1068 return *ptr;
1071 template<class T>
1072 static int match(lua_State* L, by_const_reference<T>, int index)
1074 // special case if we get nil in, try to match the holder type
1075 if (lua_isnil(L, index))
1077 class_rep* crep = get_class_rep<T>(L);;
1078 if (crep == 0) return -1;
1079 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
1080 return 0;
1081 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
1082 return 0;
1083 return -1;
1086 object_rep* obj = is_class_object(L, index);
1087 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
1089 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
1090 return (obj->flags() & object_rep::constant)?-1:0;
1091 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
1092 return (obj->flags() & object_rep::constant)?0:1;
1094 int d;
1095 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
1098 ~const_ref_converter()
1100 if (destructor) destructor(target);
1103 template<class T>
1104 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
1109 // ****** enum converter ********
1111 template<class Direction = cpp_to_lua>
1112 struct enum_converter
1114 void apply(lua_State* L, int val)
1116 lua_pushnumber(L, val);
1120 template<>
1121 struct enum_converter<lua_to_cpp>
1123 template<class T>
1124 T apply(lua_State* L, by_value<T>, int index)
1126 // std::cerr << "enum_converter\n";
1127 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
1130 template<class T>
1131 static int match(lua_State* L, by_value<T>, int index)
1133 if (lua_isnumber(L, index)) return 0; else return -1;
1136 template<class T>
1137 void converter_postcall(lua_State*, T, int) {}
1140 // ****** functor converter ********
1142 template<class Direction> struct functor_converter;
1144 template<>
1145 struct functor_converter<lua_to_cpp>
1147 template<class T>
1148 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
1150 if (lua_isnil(L, index))
1151 return functor<T>();
1153 lua_pushvalue(L, index);
1154 detail::lua_reference ref;
1155 ref.set(L);
1156 return functor<T>(L, ref);
1159 template<class T>
1160 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
1162 if (lua_isnil(L, index))
1163 return functor<T>();
1165 lua_pushvalue(L, index);
1166 detail::lua_reference ref;
1167 ref.set(L);
1168 return functor<T>(L, ref);
1171 template<class T>
1172 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
1174 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1177 template<class T>
1178 static int match(lua_State* L, by_value<functor<T> >, int index)
1180 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1183 template<class T>
1184 void converter_postcall(lua_State*, T, int) {}
1191 // *********** default_policy *****************
1195 struct default_policy : converter_policy_tag
1197 BOOST_STATIC_CONSTANT(bool, has_arg = true);
1199 template<class T>
1200 static void precall(lua_State*, T, int) {}
1202 // template<class T>
1203 // static void postcall(lua_State*, T, int) {}
1205 template<class T, class Direction>
1206 struct generate_converter
1208 typedef typename boost::mpl::if_<is_user_defined<T>
1209 , user_defined_converter<Direction>
1210 // , typename boost::mpl::if_<is_implicit_conversion<T>
1211 // , implicit_converter<Direction>
1212 , typename boost::mpl::if_<is_primitive<T>
1213 , primitive_converter<Direction>
1214 , typename boost::mpl::if_<is_lua_functor<T>
1215 , functor_converter<Direction>
1216 , typename boost::mpl::if_<boost::is_enum<T>
1217 , enum_converter<Direction>
1218 , typename boost::mpl::if_<is_nonconst_pointer<T>
1219 , pointer_converter<Direction>
1220 , typename boost::mpl::if_<is_const_pointer<T>
1221 , const_pointer_converter<Direction>
1222 , typename boost::mpl::if_<is_nonconst_reference<T>
1223 , ref_converter<Direction>
1224 , typename boost::mpl::if_<is_const_reference<T>
1225 , const_ref_converter<Direction>
1226 , value_converter<Direction>
1227 >::type>::type>::type>::type>::type>::type>::type>::type type;
1231 // ********** get policy **********
1233 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1234 template<int N, class T>
1235 struct get_policy_list_impl
1237 template<class U>
1238 struct inner
1240 typedef typename U::head head;
1241 typedef typename U::tail tail;
1243 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1244 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
1245 , typename get_policy_list_impl<N, tail>::type
1246 >::type type;
1249 template<>
1250 struct inner<null_type>
1252 typedef null_type type;
1255 typedef typename inner<T>::type type;
1257 #else
1258 template<class List>
1259 struct get_policy_list_impl
1261 template<int N>
1262 struct apply
1264 typedef typename List::head head;
1265 typedef typename List::tail tail;
1267 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1268 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
1269 , typename get_policy_list_impl<tail>::template apply<N>::type
1270 >::type type;
1274 template<>
1275 struct get_policy_list_impl<detail::null_type>
1277 template<int N>
1278 struct apply
1280 typedef null_type type;
1283 #endif
1285 template<int N, class T>
1286 struct get_policy_list
1288 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1289 typedef typename get_policy_list_impl<N, T>::type type;
1290 #else
1291 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
1292 #endif
1295 // ============== new policy system =================
1297 template<int, class> struct find_conversion_policy;
1299 template<bool IsConverter = false>
1300 struct find_conversion_impl
1302 template<int N, class Policies>
1303 struct apply
1305 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
1309 template<>
1310 struct find_conversion_impl<true>
1312 template<int N, class Policies>
1313 struct apply
1315 typedef typename Policies::head head;
1316 typedef typename Policies::tail tail;
1318 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
1320 typedef typename
1321 boost::mpl::if_c<found
1322 , head
1323 , typename find_conversion_policy<N, tail>::type
1324 >::type type;
1328 template<class Policies>
1329 struct find_conversion_impl2
1331 template<int N>
1332 struct apply
1333 : find_conversion_impl<
1334 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
1335 >::template apply<N, Policies>
1340 template<>
1341 struct find_conversion_impl2<detail::null_type>
1343 template<int N>
1344 struct apply
1346 typedef default_policy type;
1350 template<int N, class Policies>
1351 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
1355 template<class List>
1356 struct policy_list_postcall
1358 typedef typename List::head head;
1359 typedef typename List::tail tail;
1361 static void apply(lua_State* L, const index_map& i)
1363 head::postcall(L, i);
1364 policy_list_postcall<tail>::apply(L, i);
1368 template<>
1369 struct policy_list_postcall<detail::null_type>
1371 static void apply(lua_State*, const index_map&) {}
1374 /* template<int N>
1375 struct find_conversion_policy<N, detail::null_type>
1377 typedef default_policy type;
1378 };*/
1380 // ==================================================
1382 // ************** precall and postcall on policy_cons *********************
1385 template<class List>
1386 struct policy_precall
1388 typedef typename List::head head;
1389 typedef typename List::tail tail;
1391 static void apply(lua_State* L, int index)
1393 head::precall(L, index);
1394 policy_precall<tail>::apply(L, index);
1398 template<>
1399 struct policy_precall<detail::null_type>
1401 static void apply(lua_State*, int) {}
1404 template<class List>
1405 struct policy_postcall
1407 typedef typename List::head head;
1408 typedef typename List::tail tail;
1410 static void apply(lua_State* L, int index)
1412 head::postcall(L, index);
1413 policy_postcall<tail>::apply(L, index);
1417 template<>
1418 struct policy_postcall<detail::null_type>
1420 static void apply(lua_State*, int) {}
1424 struct pointer_only_converter
1426 template<class T>
1427 static const T* apply(lua_State* L, type<const T*>, int index)
1429 int a = index;
1433 struct only_one_converter_policy_can_be_used_per_index {};
1435 template<class List, class T> struct assert_converter_policy_impl;
1437 template<class List>
1438 struct assert_converter_policy
1440 template<class T>
1441 struct apply
1443 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1444 , only_one_converter_policy_can_be_used_per_index
1445 , typename assert_converter_policy_impl<typename List::tail, T>::type
1446 >::type type;
1450 template<>
1451 struct assert_converter_policy<detail::null_type>
1453 template<class T>
1454 struct apply
1456 typedef T type;
1460 template<class List, class T>
1461 struct assert_converter_policy_impl
1463 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1466 template<class List>
1467 struct find_converter_policy_impl
1469 typedef typename List::head head;
1470 typedef typename List::tail tail;
1472 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1473 , typename assert_converter_policy_impl<tail, head>::type
1474 , typename find_converter_policy_impl<tail>::type
1475 >::type type;
1478 template<>
1479 struct find_converter_policy_impl<detail::null_type>
1481 typedef default_policy type;
1486 namespace converters
1488 template<class T>
1489 struct FROM
1491 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1493 template<class U, int N>
1494 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1496 typename luabind::detail::default_policy
1497 ::generate_converter<T, detail::lua_to_cpp>::type c;
1498 return static_cast<U>(c.apply(L,
1499 LUABIND_DECORATE_TYPE(T), index));
1502 template<class U>
1503 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1505 typedef typename luabind::detail::default_policy
1506 ::generate_converter<T, detail::lua_to_cpp>::type c;
1508 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1510 std::pair<int,int> result = TO<N + 1, U>
1511 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1513 if (my_match < result.first() && my_match != -1)
1514 return std::make_pair(my_match, N);
1515 else
1516 return result;
1524 namespace luabind { namespace
1526 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1527 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1530 #include <luabind/detail/object_funs.hpp>
1532 #endif // LUABIND_POLICY_HPP_INCLUDED