*** empty log message ***
[luabind.git] / luabind / detail / policy.hpp
blobc52af7b16388fdcfee387545f1007adfc4455ae2
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/limits.hpp>
43 #include <luabind/detail/class_registry.hpp>
44 #include <luabind/detail/primitives.hpp>
45 #include <luabind/detail/object_rep.hpp>
46 #include <luabind/detail/typetraits.hpp>
47 #include <luabind/detail/class_cache.hpp>
48 #include <luabind/detail/debug.hpp>
50 #include <boost/type_traits/add_reference.hpp>
52 #include <luabind/detail/decorate_type.hpp>
53 #include <luabind/object.hpp>
54 //#include <luabind/detail/make_instance.hpp>
55 //#include <luabind/pointer_holder.hpp>
57 namespace luabind
59 namespace detail
61 struct conversion_policy_base {};
64 template<int N, bool HasArg = true>
65 struct conversion_policy : detail::conversion_policy_base
67 BOOST_STATIC_CONSTANT(int, index = N);
68 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
71 class index_map
73 public:
75 index_map(const int* m): m_map(m) {}
77 int operator[](int index) const
79 return m_map[index + 1];
82 private:
84 const int* m_map;
87 namespace converters
89 using luabind::detail::yes_t;
90 using luabind::detail::no_t;
91 using luabind::detail::by_value;
92 using luabind::detail::by_reference;
93 using luabind::detail::by_const_reference;
94 using luabind::detail::by_pointer;
95 using luabind::detail::by_const_pointer;
97 no_t is_user_defined(...);
99 // template<bool B = true> struct yes_no : yes_t { typedef yes_t type; };
100 // template<> struct yes_no<false> : no_t { typedef no_t type; };
102 template<int N, class T>
103 struct TO
105 BOOST_STATIC_CONSTANT(bool, is_specialized = false);
107 std::pair<int,int> match(lua_State*, detail::type<T>, boost::mpl::int_<N>, int)
109 return std::make_pair(-1,-1);
112 template<int I>
113 void convert(lua_State*, detail::type<T>, boost::mpl::int_<N>, int) {}
116 no_t is_implicit_conversion(...);
118 template<class T>
119 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_value<T>);
121 template<class T>
122 yes_no<TO<0,T>::is_specialized> is_implicit_conversion(by_const_reference<T>);
124 template<class T>
125 yes_no<TO<0,T*>::is_specialized> is_implicit_conversion(by_pointer<T>);
127 template<class T>
128 yes_no<TO<0,const T*>::is_specialized> is_implicit_conversion(by_const_pointer<T>);
130 #define LUABIND_IMPLICIT(index, to, from) template<> struct TO<index,to >:FROM<from > {}*/
133 namespace detail
135 template<class T>
136 struct is_user_defined
138 BOOST_STATIC_CONSTANT(bool, value =
139 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
142 /* template<class T>
143 struct is_implicit_conversion
145 BOOST_STATIC_CONSTANT(bool, value =
146 sizeof(luabind::converters::is_implicit_conversion(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
149 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
152 template<class T> class functor;
153 class object;
156 namespace luabind { namespace detail
158 template<class>
159 struct is_primitive;
161 template<class T>
162 yes_t is_lua_functor_test(const functor<T>&);
164 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
165 no_t is_lua_functor_test(...);
166 #else
167 template<class T>
168 no_t is_lua_functor_test(const T&);
169 #endif
171 template<class T>
172 struct is_lua_functor
174 static T t;
176 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
179 namespace
181 static char msvc_fix[64];
184 template<class T>
185 struct indirect_type
187 typedef typename
188 boost::mpl::if_<is_primitive<T>
189 , const type<T>&
190 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
191 , identity<T>
192 , boost::add_reference<T>
193 >::type
194 >::type result_type;
196 static inline result_type get()
198 return reinterpret_cast<result_type>(msvc_fix);
202 template<class H, class T>
203 struct policy_cons
205 typedef H head;
206 typedef T tail;
208 template<class U>
209 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
211 return policy_cons<U, policy_cons<H,T> >();
214 template<class U>
215 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
217 return policy_cons<U, policy_cons<H,T> >();
220 template<class U>
221 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
223 return policy_cons<U, policy_cons<H,T> >();
227 struct indirection_layer
229 template<class T>
230 indirection_layer(const T&);
233 template<class H, class T>
234 yes_t is_policy_cons_test(const policy_cons<H,T>&);
235 no_t is_policy_cons_test(...);
237 template<class T>
238 struct is_policy_cons
240 static const T& t;
242 BOOST_STATIC_CONSTANT(bool, value =
243 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
246 template<bool>
247 struct is_string_literal
249 static no_t helper(indirection_layer);
250 static yes_t helper(const char*);
253 template<>
254 struct is_string_literal<false>
256 static no_t helper(indirection_layer);
260 template<class T>
261 struct is_primitive/*: boost::mpl::bool_c<false>*/
263 static T t;
265 BOOST_STATIC_CONSTANT(bool, value =
266 sizeof(is_string_literal<boost::is_array<T>::value>::helper(t)) == sizeof(yes_t));
269 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
270 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
271 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
273 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
274 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
275 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
276 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
277 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
278 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
279 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
280 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
281 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
282 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
283 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
284 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
285 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
287 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
288 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
289 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
290 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
291 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
292 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
293 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
294 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
295 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
296 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
297 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
298 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
299 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
300 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
302 // TODO: add more
303 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
304 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
305 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
306 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
307 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
308 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
309 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
310 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
311 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
312 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
313 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
314 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
316 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
317 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
318 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
321 template<class Direction> struct primitive_converter;
323 template<>
324 struct primitive_converter<cpp_to_lua>
326 void apply(lua_State* L, const luabind::object& v)
328 // if the luabind::object is uninitialized
329 // treat it as nil.
330 if (v.lua_state() == 0)
332 lua_pushnil(L);
333 return;
335 // if you hit this assert you are trying to return a value from one state into another lua state
336 assert((v.lua_state() == L) && "you cannot return an uninitilized value "
337 "or a value from one lua state into another");
338 v.pushvalue();
340 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
341 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
342 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
343 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
344 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
345 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
346 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
347 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
348 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
349 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
350 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
351 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
352 void apply(lua_State* L, const std::string& v)
353 { lua_pushlstring(L, v.data(), v.size()); }
354 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
357 template<>
358 struct primitive_converter<lua_to_cpp>
360 #define PRIMITIVE_CONVERTER(prim) \
361 prim apply(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
362 prim apply(lua_State* L, luabind::detail::by_value<const prim>, int index) { return apply(L, detail::by_value<prim>(), index); } \
363 prim apply(lua_State* L, luabind::detail::by_value<prim>, int index)
365 #define PRIMITIVE_MATCHER(prim) \
366 static int match(lua_State* L, luabind::detail::by_const_reference<prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
367 static int match(lua_State* L, luabind::detail::by_value<const prim>, int index) { return match(L, detail::by_value<prim>(), index); } \
368 static int match(lua_State* L, luabind::detail::by_value<prim>, int index)
370 PRIMITIVE_CONVERTER(bool) { return lua_toboolean(L, index) == 1; }
371 PRIMITIVE_MATCHER(bool) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1; }
373 PRIMITIVE_CONVERTER(int) { return static_cast<int>(lua_tonumber(L, index)); }
374 PRIMITIVE_MATCHER(int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
376 PRIMITIVE_CONVERTER(unsigned int) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
377 PRIMITIVE_MATCHER(unsigned int) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
379 PRIMITIVE_CONVERTER(char) { return static_cast<char>(lua_tonumber(L, index)); }
380 PRIMITIVE_MATCHER(char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
382 PRIMITIVE_CONVERTER(unsigned char) { return static_cast<unsigned char>(lua_tonumber(L, index)); }
383 PRIMITIVE_MATCHER(unsigned char) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
385 PRIMITIVE_CONVERTER(short) { return static_cast<short>(lua_tonumber(L, index)); }
386 PRIMITIVE_MATCHER(short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
388 PRIMITIVE_CONVERTER(unsigned short) { return static_cast<unsigned short>(lua_tonumber(L, index)); }
389 PRIMITIVE_MATCHER(unsigned short) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
391 PRIMITIVE_CONVERTER(long) { return static_cast<long>(lua_tonumber(L, index)); }
392 PRIMITIVE_MATCHER(long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
394 PRIMITIVE_CONVERTER(unsigned long) { return static_cast<unsigned long>(lua_tonumber(L, index)); }
395 PRIMITIVE_MATCHER(unsigned long) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
397 PRIMITIVE_CONVERTER(float) { return static_cast<float>(lua_tonumber(L, index)); }
398 PRIMITIVE_MATCHER(float) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
400 PRIMITIVE_CONVERTER(double) { return static_cast<double>(lua_tonumber(L, index)); }
401 PRIMITIVE_MATCHER(double) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1; }
403 PRIMITIVE_CONVERTER(std::string)
404 { return std::string(lua_tostring(L, index), lua_strlen(L, index)); }
405 PRIMITIVE_MATCHER(std::string) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1; }
407 PRIMITIVE_CONVERTER(luabind::object)
409 LUABIND_CHECK_STACK(L);
411 lua_pushvalue(L, index);
412 detail::lua_reference ref;
413 ref.set(L);
414 return luabind::object(L, ref, true);
417 PRIMITIVE_MATCHER(luabind::object) { return std::numeric_limits<int>::max() - 1; }
419 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
420 const char* apply(lua_State* L, detail::by_const_pointer<const char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
421 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
422 static int match(lua_State* L, by_const_pointer<const char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
424 /* template<class T>
425 T apply(lua_State* L, luabind::detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
427 // TODO: add more
428 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
429 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
430 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
431 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
432 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
433 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
434 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
435 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
436 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
437 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
438 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
439 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
441 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
442 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
443 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
444 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
445 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
446 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
447 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
449 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
450 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
451 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
452 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
454 // std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
455 // const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
456 // const std::string apply(lua_State* L, detail::by_const_reference<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
457 PRIMITIVE_CONVERTER(std::string) { return static_cast<const char*>(lua_tostring(L, index)); }
459 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
461 lua_pushvalue(L, index);
462 return luabind::object(L, detail::ref(L), true);
465 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
467 lua_pushvalue(L, index);
468 return luabind::object(L, detail::ref(L), true);
471 // TODO: add more
473 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
475 // matchers
476 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
477 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
478 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
479 static int match(lua_State* L, detail::by_value<long double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
480 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
481 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
482 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
483 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
484 static int match(lua_State* L, detail::by_value<unsigned int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
485 static int match(lua_State* L, detail::by_value<unsigned short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
486 static int match(lua_State* L, detail::by_value<unsigned char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
487 static int match(lua_State* L, detail::by_value<unsigned long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
488 static int match(lua_State* L, detail::by_value<std::string>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
489 static int match(lua_State* L, detail::by_value<const std::string>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
490 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
491 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
493 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
494 static int match(lua_State* L, by_const_pointer<const char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
496 template<class T>
497 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
500 template<class T>
501 void converter_postcall(lua_State*, T, int) {}
503 #undef PRIMITIVE_MATCHER
504 #undef PRIMITIVE_CONVERTER
509 // *********** default converters ***************
511 /* template<class> struct implicit_converter;
513 template<>
514 struct implicit_converter<lua_to_cpp>
516 int converter_index;
518 template<class T>
519 T apply(lua_State* L, detail::by_value<T>, int index)
521 return converters::TO<T>::convert(L, detail::type<T>(), index);
524 template<class T>
525 static int match(lua_State* L, detail::by_value<T>, int index)
527 return converters::TO<T>::match(L, detail::type<T>(), index);
530 template<class T>
531 T apply(lua_State* L, detail::by_const_reference<T>, int index)
533 return converters::TO<T>::convert(L, detail::type<T>(), index);
536 template<class T>
537 static int match(lua_State* L, detail::by_const_reference<T>, int index)
539 return converters::TO<T>::match(L, detail::type<T>(), index);
542 template<class T>
543 T* apply(lua_State* L, detail::by_pointer<T>, int index)
545 return converters::TO<T*>::convert(L, detail::type<T*>(), index);
548 template<class T>
549 static int match(lua_State* L, detail::by_pointer<T>, int index)
551 return converters::TO<T*>::match(L, detail::type<T*>(), index);
554 template<class T>
555 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
557 return converters::TO<const T*>::convert(L, detail::type<const T*>(), index);
560 template<class T>
561 static int match(lua_State* L, detail::by_const_pointer<T>, int index)
563 return converters::TO<const T*>::match(L, detail::type<const T*>(), index);
566 template<class T>
567 void converter_postcall(lua_State*, T, int) {}
571 // ********** user defined converter ***********
573 template<class Direction> struct user_defined_converter;
575 template<>
576 struct user_defined_converter<lua_to_cpp>
578 template<class T>
579 T apply(lua_State* L, detail::by_value<T>, int index)
581 // std::cerr << "user_defined_converter\n";
582 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
585 template<class T>
586 T apply(lua_State* L, detail::by_reference<T>, int index)
588 // std::cerr << "user_defined_converter\n";
589 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
592 template<class T>
593 T apply(lua_State* L, detail::by_const_reference<T>, int index)
595 // std::cerr << "user_defined_converter\n";
596 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
599 template<class T>
600 T* apply(lua_State* L, detail::by_pointer<T>, int index)
602 // std::cerr << "user_defined_converter\n";
603 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
606 template<class T>
607 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
609 // std::cerr << "user_defined_converter\n";
610 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
613 template<class T>
614 static int match(lua_State* L, T, int index)
616 return converters::match_lua_to_cpp(L, T(), index);
619 template<class T>
620 void converter_postcall(lua_State*, T, int) {}
623 template<>
624 struct user_defined_converter<cpp_to_lua>
626 template<class T>
627 void apply(lua_State* L, const T& v)
629 converters::convert_cpp_to_lua(L, v);
633 // ********** pointer converter ***********
636 template<class Direction> struct pointer_converter;
638 template<>
639 struct pointer_converter<cpp_to_lua>
641 template<class T>
642 void apply(lua_State* L, T* ptr)
644 if (ptr == 0)
646 lua_pushnil(L);
647 return;
650 class_rep* crep = get_class_rep<T>(L);
652 // if you get caught in this assert you are
653 // trying to use an unregistered type
654 assert(crep && "you are trying to use an unregistered type");
656 // create the struct to hold the object
657 void* obj = lua_newuserdata(L, sizeof(object_rep));
658 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
659 new(obj) object_rep(ptr, crep, 0, 0);
661 // set the meta table
662 detail::getref(L, crep->metatable_ref());
663 lua_setmetatable(L, -2);
665 // make_instance(L, ptr, (pointer_holder<T, T*>*)0);
669 template<class T> struct make_pointer { typedef T* type; };
670 template<>
671 struct pointer_converter<lua_to_cpp>
673 // TODO: does the pointer converter need this?!
674 char target[32];
675 void (*destructor)(void *);
677 pointer_converter(): destructor(0) {}
679 template<class T>
680 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
682 // preconditions:
683 // lua_isuserdata(L, index);
684 // getmetatable().__lua_class is true
685 // object_rep->flags() & object_rep::constant == 0
687 if (lua_isnil(L, index)) return 0;
689 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
690 assert((obj != 0) && "internal error, please report"); // internal error
691 const class_rep* crep = obj->crep();
693 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
695 if ((void*)ptr == (char*)target) destructor = detail::destruct_only_s<T>::apply;
696 assert(!destructor || sizeof(T) <= 32);
698 return ptr;
701 template<class T>
702 static int match(lua_State* L, by_pointer<T>, int index)
704 if (lua_isnil(L, index)) return 0;
705 object_rep* obj = is_class_object(L, index);
706 if (obj == 0) return -1;
707 // cannot cast a constant object to nonconst
708 if (obj->flags() & object_rep::constant) return -1;
710 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
711 return (obj->flags() & object_rep::constant)?-1:0;
712 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
713 return (obj->flags() & object_rep::constant)?0:-1;
716 int d;
717 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
720 ~pointer_converter()
722 if (destructor) destructor(target);
725 template<class T>
726 void converter_postcall(lua_State*, by_pointer<T>, int)
730 // ******* value converter *******
732 template<class Direction> struct value_converter;
734 template<>
735 struct value_converter<cpp_to_lua>
737 template<class T>
738 void apply(lua_State* L, const T& ref)
740 class_rep* crep = get_class_rep<T>(L);
742 // if you get caught in this assert you are
743 // trying to use an unregistered type
744 assert(crep && "you are trying to use an unregistered type");
746 void* obj_rep;
747 void* held;
749 boost::tie(obj_rep,held) = crep->allocate(L);
751 void* object_ptr;
752 void(*destructor)(void*);
753 destructor = crep->destructor();
754 int flags = object_rep::owner;
755 if (crep->has_holder())
757 new(held) T(ref);
758 object_ptr = held;
759 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
761 flags |= object_rep::constant;
762 destructor = crep->const_holder_destructor();
765 else
767 object_ptr = new T(ref);
769 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
771 // set the meta table
772 detail::getref(L, crep->metatable_ref());
773 lua_setmetatable(L, -2);
778 template<class T> struct make_const_reference { typedef const T& type; };
780 template<class T>
781 struct destruct_guard
783 T* ptr;
784 bool dismiss;
785 destruct_guard(T* p): ptr(p), dismiss(false) {}
787 ~destruct_guard()
789 if (!dismiss)
790 ptr->~T();
794 template<>
795 struct value_converter<lua_to_cpp>
797 template<class T>
798 /*typename make_const_reference<T>::type*/T apply(lua_State* L, by_value<T>, int index)
800 // preconditions:
801 // lua_isuserdata(L, index);
802 // getmetatable().__lua_class is true
803 // object_rep->flags() & object_rep::constant == 0
805 object_rep* obj = 0;
806 const class_rep* crep = 0;
808 // special case if we get nil in, try to convert the holder type
809 if (lua_isnil(L, index))
811 crep = get_class_rep<T>(L);;
812 assert(crep);
814 else
816 obj = static_cast<object_rep*>(lua_touserdata(L, index));
817 assert((obj != 0) && "internal error, please report"); // internal error
818 crep = obj->crep();
820 assert(crep);
822 // TODO: align!
823 char target[sizeof(T)];
824 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
826 destruct_guard<T> guard(ptr);
827 if ((void*)ptr != (void*)target) guard.dismiss = true;
829 return *ptr;
832 template<class T>
833 static int match(lua_State* L, by_value<T>, int index)
835 // special case if we get nil in, try to match the holder type
836 if (lua_isnil(L, index))
838 class_rep* crep = get_class_rep<T>(L);
839 if (crep == 0) return -1;
840 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
841 return 0;
842 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
843 return 0;
844 return -1;
847 object_rep* obj = is_class_object(L, index);
848 if (obj == 0) return -1;
849 int d;
851 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
852 return (obj->flags() & object_rep::constant)?-1:0;
853 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
854 return (obj->flags() & object_rep::constant)?0:1;
856 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
859 template<class T>
860 void converter_postcall(lua_State*, T, int) {}
863 // ******* const pointer converter *******
865 template<class Direction> struct const_pointer_converter;
867 template<>
868 struct const_pointer_converter<cpp_to_lua>
870 template<class T>
871 void apply(lua_State* L, const T* ptr)
873 if (ptr == 0)
875 lua_pushnil(L);
876 return;
879 class_rep* crep = get_class_rep<T>(L);
881 // if you get caught in this assert you are
882 // trying to use an unregistered type
883 assert(crep && "you are trying to use an unregistered type");
885 // create the struct to hold the object
886 void* obj = lua_newuserdata(L, sizeof(object_rep));
887 assert(obj && "internal error, please report");
888 // we send 0 as destructor since we know it will never be called
889 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
891 // set the meta table
892 detail::getref(L, crep->metatable_ref());
893 lua_setmetatable(L, -2);
898 template<class T> struct make_const_pointer { typedef const T* type; };
899 template<>
900 struct const_pointer_converter<lua_to_cpp>
901 : private pointer_converter<lua_to_cpp>
903 template<class T>
904 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
906 // std::cerr << "const_pointer_converter\n";
907 return pointer_converter<lua_to_cpp>::apply(L, by_pointer<T>(), index);
910 template<class T>
911 static int match(lua_State* L, by_const_pointer<T>, int index)
913 if (lua_isnil(L, index)) return 0;
914 object_rep* obj = is_class_object(L, index);
915 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
917 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
918 return (obj->flags() & object_rep::constant)?-1:0;
919 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
920 return (obj->flags() & object_rep::constant)?0:1;
922 int d;
923 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
926 template<class T>
927 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
929 pointer_converter<lua_to_cpp>::converter_postcall(L, by_pointer<T>(), index);
933 // ******* reference converter *******
935 template<class Direction> struct ref_converter;
937 template<>
938 struct ref_converter<cpp_to_lua>
940 template<class T>
941 void apply(lua_State* L, T& ref)
943 class_rep* crep = get_class_rep<T>(L);
945 // if you get caught in this assert you are
946 // trying to use an unregistered type
947 assert(crep && "you are trying to use an unregistered type");
949 T* ptr = &ref;
951 // create the struct to hold the object
952 void* obj = lua_newuserdata(L, sizeof(object_rep));
953 assert(obj && "internal error, please report");
954 new(obj) object_rep(ptr, crep, 0, 0);
956 // set the meta table
957 detail::getref(L, crep->metatable_ref());
958 lua_setmetatable(L, -2);
962 template<class T> struct make_reference { typedef T& type; };
963 template<>
964 struct ref_converter<lua_to_cpp>
966 template<class T>
967 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
969 // std::cerr << "ref_converter<lua_to_cpp>\n";
970 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
973 template<class T>
974 static int match(lua_State* L, by_reference<T>, int index)
976 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
979 template<class T>
980 void converter_postcall(lua_State*, T, int) {}
983 // ******** const reference converter *********
985 template<class Direction> struct const_ref_converter;
987 template<>
988 struct const_ref_converter<cpp_to_lua>
990 template<class T>
991 void apply(lua_State* L, const T& ref)
993 class_rep* crep = get_class_rep<T>(L);
995 // if you get caught in this assert you are
996 // trying to use an unregistered type
997 assert(crep && "you are trying to use an unregistered type");
1000 void* obj_rep;
1001 void* held;
1003 boost::tie(obj_rep,held) = crep->allocate(L);
1005 void* object_ptr;
1006 void(*destructor)(void*);
1007 destructor = crep->destructor();
1008 int flags = 0;
1009 if (crep->has_holder())
1011 flags = object_rep::owner;
1012 new(held) T(ref);
1013 object_ptr = held;
1014 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
1016 flags |= object_rep::constant;
1017 destructor = crep->const_holder_destructor();
1020 else
1022 object_ptr = new T(ref);
1024 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
1026 // set the meta table
1027 detail::getref(L, crep->metatable_ref());
1028 lua_setmetatable(L, -2);
1032 template<>
1033 struct const_ref_converter<lua_to_cpp>
1035 // TODO: align!
1036 char target[32];
1037 void (*destructor)(void*);
1039 const_ref_converter(): destructor(0) {}
1041 template<class T>
1042 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
1044 object_rep* obj = 0;
1045 class_rep const * crep = 0;
1047 // special case if we get nil in, try to convert the holder type
1048 if (lua_isnil(L, index))
1050 crep = get_class_rep<T>(L);
1051 assert(crep);
1053 else
1055 obj = static_cast<object_rep*>(lua_touserdata(L, index));
1056 assert((obj != 0) && "internal error, please report"); // internal error
1057 crep = obj->crep();
1059 assert(crep);
1061 T* ptr = reinterpret_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, target));
1062 // if the pointer returned points into the converter storage,
1063 // we need to destruct it once the converter destructs
1064 if ((void*)ptr == (void*)target) destructor = detail::destruct_only_s<T>::apply;
1065 assert(!destructor || sizeof(T) <= 32);
1067 return *ptr;
1070 template<class T>
1071 static int match(lua_State* L, by_const_reference<T>, int index)
1073 // special case if we get nil in, try to match the holder type
1074 if (lua_isnil(L, index))
1076 class_rep* crep = get_class_rep<T>(L);;
1077 if (crep == 0) return -1;
1078 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
1079 return 0;
1080 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
1081 return 0;
1082 return -1;
1085 object_rep* obj = is_class_object(L, index);
1086 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
1088 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
1089 return (obj->flags() & object_rep::constant)?-1:0;
1090 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
1091 return (obj->flags() & object_rep::constant)?0:1;
1093 int d;
1094 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
1097 ~const_ref_converter()
1099 if (destructor) destructor(target);
1102 template<class T>
1103 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
1108 // ****** enum converter ********
1110 template<class Direction = cpp_to_lua>
1111 struct enum_converter
1113 void apply(lua_State* L, int val)
1115 lua_pushnumber(L, val);
1119 template<>
1120 struct enum_converter<lua_to_cpp>
1122 template<class T>
1123 T apply(lua_State* L, by_value<T>, int index)
1125 // std::cerr << "enum_converter\n";
1126 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
1129 template<class T>
1130 static int match(lua_State* L, by_value<T>, int index)
1132 if (lua_isnumber(L, index)) return 0; else return -1;
1135 template<class T>
1136 void converter_postcall(lua_State*, T, int) {}
1139 // ****** functor converter ********
1141 template<class Direction> struct functor_converter;
1143 template<>
1144 struct functor_converter<lua_to_cpp>
1146 template<class T>
1147 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
1149 if (lua_isnil(L, index))
1150 return functor<T>();
1152 lua_pushvalue(L, index);
1153 detail::lua_reference ref;
1154 ref.set(L);
1155 return functor<T>(L, ref);
1158 template<class T>
1159 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
1161 if (lua_isnil(L, index))
1162 return functor<T>();
1164 lua_pushvalue(L, index);
1165 detail::lua_reference ref;
1166 ref.set(L);
1167 return functor<T>(L, ref);
1170 template<class T>
1171 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
1173 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1176 template<class T>
1177 static int match(lua_State* L, by_value<functor<T> >, int index)
1179 if (lua_isfunction(L, index) || lua_isnil(L, index)) return 0; else return -1;
1182 template<class T>
1183 void converter_postcall(lua_State*, T, int) {}
1190 // *********** default_policy *****************
1194 struct default_policy : converter_policy_tag
1196 BOOST_STATIC_CONSTANT(bool, has_arg = true);
1198 template<class T>
1199 static void precall(lua_State*, T, int) {}
1201 // template<class T>
1202 // static void postcall(lua_State*, T, int) {}
1204 template<class T, class Direction>
1205 struct generate_converter
1207 typedef typename boost::mpl::if_<is_user_defined<T>
1208 , user_defined_converter<Direction>
1209 // , typename boost::mpl::if_<is_implicit_conversion<T>
1210 // , implicit_converter<Direction>
1211 , typename boost::mpl::if_<is_primitive<T>
1212 , primitive_converter<Direction>
1213 , typename boost::mpl::if_<is_lua_functor<T>
1214 , functor_converter<Direction>
1215 , typename boost::mpl::if_<boost::is_enum<T>
1216 , enum_converter<Direction>
1217 , typename boost::mpl::if_<is_nonconst_pointer<T>
1218 , pointer_converter<Direction>
1219 , typename boost::mpl::if_<is_const_pointer<T>
1220 , const_pointer_converter<Direction>
1221 , typename boost::mpl::if_<is_nonconst_reference<T>
1222 , ref_converter<Direction>
1223 , typename boost::mpl::if_<is_const_reference<T>
1224 , const_ref_converter<Direction>
1225 , value_converter<Direction>
1226 >::type>::type>::type>::type>::type>::type>::type>::type type;
1230 // ********** get policy **********
1232 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1233 template<int N, class T>
1234 struct get_policy_list_impl
1236 template<class U>
1237 struct inner
1239 typedef typename U::head head;
1240 typedef typename U::tail tail;
1242 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1243 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
1244 , typename get_policy_list_impl<N, tail>::type
1245 >::type type;
1248 template<>
1249 struct inner<null_type>
1251 typedef null_type type;
1254 typedef typename inner<T>::type type;
1256 #else
1257 template<class List>
1258 struct get_policy_list_impl
1260 template<int N>
1261 struct apply
1263 typedef typename List::head head;
1264 typedef typename List::tail tail;
1266 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
1267 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
1268 , typename get_policy_list_impl<tail>::template apply<N>::type
1269 >::type type;
1273 template<>
1274 struct get_policy_list_impl<detail::null_type>
1276 template<int N>
1277 struct apply
1279 typedef null_type type;
1282 #endif
1284 template<int N, class T>
1285 struct get_policy_list
1287 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
1288 typedef typename get_policy_list_impl<N, T>::type type;
1289 #else
1290 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
1291 #endif
1294 // ============== new policy system =================
1296 template<int, class> struct find_conversion_policy;
1298 template<bool IsConverter = false>
1299 struct find_conversion_impl
1301 template<int N, class Policies>
1302 struct apply
1304 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
1308 template<>
1309 struct find_conversion_impl<true>
1311 template<int N, class Policies>
1312 struct apply
1314 typedef typename Policies::head head;
1315 typedef typename Policies::tail tail;
1317 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
1319 typedef typename
1320 boost::mpl::if_c<found
1321 , head
1322 , typename find_conversion_policy<N, tail>::type
1323 >::type type;
1327 template<class Policies>
1328 struct find_conversion_impl2
1330 template<int N>
1331 struct apply
1332 : find_conversion_impl<
1333 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
1334 >::template apply<N, Policies>
1339 template<>
1340 struct find_conversion_impl2<detail::null_type>
1342 template<int N>
1343 struct apply
1345 typedef default_policy type;
1349 template<int N, class Policies>
1350 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
1354 template<class List>
1355 struct policy_list_postcall
1357 typedef typename List::head head;
1358 typedef typename List::tail tail;
1360 static void apply(lua_State* L, const index_map& i)
1362 head::postcall(L, i);
1363 policy_list_postcall<tail>::apply(L, i);
1367 template<>
1368 struct policy_list_postcall<detail::null_type>
1370 static void apply(lua_State*, const index_map&) {}
1373 /* template<int N>
1374 struct find_conversion_policy<N, detail::null_type>
1376 typedef default_policy type;
1377 };*/
1379 // ==================================================
1381 // ************** precall and postcall on policy_cons *********************
1384 template<class List>
1385 struct policy_precall
1387 typedef typename List::head head;
1388 typedef typename List::tail tail;
1390 static void apply(lua_State* L, int index)
1392 head::precall(L, index);
1393 policy_precall<tail>::apply(L, index);
1397 template<>
1398 struct policy_precall<detail::null_type>
1400 static void apply(lua_State*, int) {}
1403 template<class List>
1404 struct policy_postcall
1406 typedef typename List::head head;
1407 typedef typename List::tail tail;
1409 static void apply(lua_State* L, int index)
1411 head::postcall(L, index);
1412 policy_postcall<tail>::apply(L, index);
1416 template<>
1417 struct policy_postcall<detail::null_type>
1419 static void apply(lua_State*, int) {}
1423 struct pointer_only_converter
1425 template<class T>
1426 static const T* apply(lua_State* L, type<const T*>, int index)
1428 int a = index;
1432 struct only_one_converter_policy_can_be_used_per_index {};
1434 template<class List, class T> struct assert_converter_policy_impl;
1436 template<class List>
1437 struct assert_converter_policy
1439 template<class T>
1440 struct apply
1442 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1443 , only_one_converter_policy_can_be_used_per_index
1444 , typename assert_converter_policy_impl<typename List::tail, T>::type
1445 >::type type;
1449 template<>
1450 struct assert_converter_policy<detail::null_type>
1452 template<class T>
1453 struct apply
1455 typedef T type;
1459 template<class List, class T>
1460 struct assert_converter_policy_impl
1462 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1465 template<class List>
1466 struct find_converter_policy_impl
1468 typedef typename List::head head;
1469 typedef typename List::tail tail;
1471 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1472 , typename assert_converter_policy_impl<tail, head>::type
1473 , typename find_converter_policy_impl<tail>::type
1474 >::type type;
1477 template<>
1478 struct find_converter_policy_impl<detail::null_type>
1480 typedef default_policy type;
1485 namespace converters
1487 template<class T>
1488 struct FROM
1490 BOOST_STATIC_CONSTANT(bool, is_specialized = true);
1492 template<class U, int N>
1493 static U convert(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1495 typename luabind::detail::default_policy
1496 ::generate_converter<T, detail::lua_to_cpp>::type c;
1497 return static_cast<U>(c.apply(L,
1498 LUABIND_DECORATE_TYPE(T), index));
1501 template<class U>
1502 static std::pair<int,int> match(lua_State* L, boost::mpl::int_<N>, detail::type<U>, int index)
1504 typedef typename luabind::detail::default_policy
1505 ::generate_converter<T, detail::lua_to_cpp>::type c;
1507 int my_match = c::match(L, LUABIND_DECORATE_TYPE(T), index);
1509 std::pair<int,int> result = TO<N + 1, U>
1510 ::match(L, boost::mpl::int_<N + 1>(), detail::type<U>(), index);
1512 if (my_match < result.first() && my_match != -1)
1513 return std::make_pair(my_match, N);
1514 else
1515 return result;
1523 namespace luabind { namespace
1525 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1526 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1529 #include <luabind/detail/object_funs.hpp>
1531 #endif // LUABIND_POLICY_HPP_INCLUDED