*** empty log message ***
[luabind.git] / luabind / detail / policy.hpp
blob582471c85a8b0577f563af02462e343739504b3e
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
24 #ifndef LUABIND_POLICY_HPP_INCLUDED
25 #define LUABIND_POLICY_HPP_INCLUDED
27 #include <luabind/config.hpp>
29 #include <typeinfo>
31 #include <boost/type_traits/is_enum.hpp>
32 #include <boost/mpl/bool.hpp>
33 #include <boost/mpl/integral_c.hpp>
34 #include <boost/mpl/equal_to.hpp>
35 #include <boost/type_traits/add_reference.hpp>
36 #include <boost/limits.hpp>
38 #include <luabind/detail/class_registry.hpp>
39 #include <luabind/detail/primitives.hpp>
40 #include <luabind/detail/object_rep.hpp>
41 #include <luabind/detail/typetraits.hpp>
43 #include <boost/type_traits/add_reference.hpp>
45 #include <luabind/detail/decorate_type.hpp>
46 #include <luabind/object.hpp>
48 namespace luabind
50 namespace detail
52 struct conversion_policy_base {};
55 template<int N, bool HasArg = true>
56 struct conversion_policy : detail::conversion_policy_base
58 BOOST_STATIC_CONSTANT(int, index = N);
59 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
62 class index_map
64 public:
66 index_map(const int* m): m_map(m) {}
68 int operator[](int index) const
70 return m_map[index + 1];
73 private:
75 const int* m_map;
78 namespace converters
80 using luabind::detail::yes_t;
81 using luabind::detail::no_t;
82 using luabind::detail::by_value;
83 using luabind::detail::by_reference;
84 using luabind::detail::by_const_reference;
85 using luabind::detail::by_pointer;
86 using luabind::detail::by_const_pointer;
88 no_t is_user_defined(...);
91 namespace detail
93 template<class T>
94 struct is_user_defined
96 BOOST_STATIC_CONSTANT(bool, value =
97 sizeof(luabind::converters::is_user_defined(LUABIND_DECORATE_TYPE(T))) == sizeof(yes_t));
100 int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
103 template<class T> class functor;
104 class object;
107 namespace luabind { namespace detail
109 template<class>
110 struct is_primitive;
112 template<class T>
113 yes_t is_lua_functor_test(const functor<T>&);
115 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
116 no_t is_lua_functor_test(...);
117 #else
118 template<class T>
119 no_t is_lua_functor_test(const T&);
120 #endif
122 template<class T>
123 struct is_lua_functor
125 static T t;
127 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_lua_functor_test(t)) == sizeof(yes_t));
130 namespace
132 static char msvc_fix[64];
135 template<class T>
136 struct indirect_type
138 typedef typename
139 boost::mpl::if_<is_primitive<T>
140 , const type<T>&
141 , typename boost::mpl::apply_if<boost::mpl::or_<boost::is_reference<T>, boost::is_pointer<T> >
142 , identity<T>
143 , boost::add_reference<T>
144 >::type
145 >::type result_type;
147 static inline result_type get()
149 return reinterpret_cast<result_type>(msvc_fix);
153 template<class H, class T>
154 struct policy_cons
156 typedef H head;
157 typedef T tail;
159 template<class U>
160 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
162 return policy_cons<U, policy_cons<H,T> >();
165 template<class U>
166 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
168 return policy_cons<U, policy_cons<H,T> >();
171 template<class U>
172 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
174 return policy_cons<U, policy_cons<H,T> >();
178 struct indirection_layer
180 template<class T>
181 indirection_layer(const T&);
184 template<class H, class T>
185 yes_t is_policy_cons_test(const policy_cons<H,T>&);
186 no_t is_policy_cons_test(...);
188 template<class T>
189 struct is_policy_cons
191 static const T& t;
193 BOOST_STATIC_CONSTANT(bool, value =
194 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
197 no_t is_string_literal(indirection_layer);
198 yes_t is_string_literal(const char*);
200 template<class T>
201 struct is_primitive/*: boost::mpl::bool_c<false>*/
203 static T t;
205 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_string_literal(t)) == sizeof(yes_t));
208 template<> struct is_primitive<luabind::object>: boost::mpl::bool_<true> {};
209 template<> struct is_primitive<const luabind::object>: boost::mpl::bool_<true> {};
210 template<> struct is_primitive<const luabind::object&>: boost::mpl::bool_<true> {};
212 template<> struct is_primitive<int>: boost::mpl::bool_<true> {};
213 template<> struct is_primitive<char>: boost::mpl::bool_<true> {};
214 template<> struct is_primitive<short>: boost::mpl::bool_<true> {};
215 template<> struct is_primitive<long>: boost::mpl::bool_<true> {};
216 template<> struct is_primitive<unsigned char>: boost::mpl::bool_<true> {};
217 template<> struct is_primitive<unsigned short>: boost::mpl::bool_<true> {};
218 template<> struct is_primitive<unsigned long>: boost::mpl::bool_<true> {};
219 template<> struct is_primitive<unsigned int>: boost::mpl::bool_<true> {};
220 template<> struct is_primitive<float>: boost::mpl::bool_<true> {};
221 template<> struct is_primitive<double>: boost::mpl::bool_<true> {};
222 template<> struct is_primitive<long double>: boost::mpl::bool_<true> {};
223 template<> struct is_primitive<char*>: boost::mpl::bool_<true> {};
224 template<> struct is_primitive<bool>: boost::mpl::bool_<true> {};
226 template<> struct is_primitive<const int>: boost::mpl::bool_<true> {};
227 template<> struct is_primitive<const char>: boost::mpl::bool_<true> {};
228 template<> struct is_primitive<const short>: boost::mpl::bool_<true> {};
229 template<> struct is_primitive<const long>: boost::mpl::bool_<true> {};
230 template<> struct is_primitive<const unsigned int>: boost::mpl::bool_<true> {};
231 template<> struct is_primitive<const unsigned char>: boost::mpl::bool_<true> {};
232 template<> struct is_primitive<const unsigned short>: boost::mpl::bool_<true> {};
233 template<> struct is_primitive<const unsigned long>: boost::mpl::bool_<true> {};
234 template<> struct is_primitive<const float>: boost::mpl::bool_<true> {};
235 template<> struct is_primitive<const double>: boost::mpl::bool_<true> {};
236 template<> struct is_primitive<const long double>: boost::mpl::bool_<true> {};
237 template<> struct is_primitive<const char*>: boost::mpl::bool_<true> {};
238 template<> struct is_primitive<const char* const>: boost::mpl::bool_<true> {};
239 template<> struct is_primitive<const bool>: boost::mpl::bool_<true> {};
241 // TODO: add more
242 template<> struct is_primitive<const int&>: boost::mpl::bool_<true> {};
243 template<> struct is_primitive<const char&>: boost::mpl::bool_<true> {};
244 template<> struct is_primitive<const short&>: boost::mpl::bool_<true> {};
245 template<> struct is_primitive<const long&>: boost::mpl::bool_<true> {};
246 template<> struct is_primitive<const unsigned int&>: boost::mpl::bool_<true> {};
247 template<> struct is_primitive<const unsigned char&>: boost::mpl::bool_<true> {};
248 template<> struct is_primitive<const unsigned short&>: boost::mpl::bool_<true> {};
249 template<> struct is_primitive<const unsigned long&>: boost::mpl::bool_<true> {};
250 template<> struct is_primitive<const float&>: boost::mpl::bool_<true> {};
251 template<> struct is_primitive<const double&>: boost::mpl::bool_<true> {};
252 template<> struct is_primitive<const long double&>: boost::mpl::bool_<true> {};
253 template<> struct is_primitive<const bool&>: boost::mpl::bool_<true> {};
255 template<> struct is_primitive<const std::string&>: boost::mpl::bool_<true> {};
256 template<> struct is_primitive<std::string>: boost::mpl::bool_<true> {};
257 template<> struct is_primitive<const std::string>: boost::mpl::bool_<true> {};
260 template<class Direction> struct primitive_converter;
262 template<>
263 struct primitive_converter<cpp_to_lua>
265 void apply(lua_State* L, const luabind::object& v)
267 // if you hit this assert you are trying to return a value from one state into another lua state
268 assert((v.lua_state() == L) && "you cannot return a value from one lua state into another");
269 v.pushvalue();
271 void apply(lua_State* L, int v) { lua_pushnumber(L, v); }
272 void apply(lua_State* L, short v) { lua_pushnumber(L, v); }
273 void apply(lua_State* L, char v) { lua_pushnumber(L, v); }
274 void apply(lua_State* L, long v) { lua_pushnumber(L, v); }
275 void apply(lua_State* L, unsigned int v) { lua_pushnumber(L, v); }
276 void apply(lua_State* L, unsigned short v) { lua_pushnumber(L, v); }
277 void apply(lua_State* L, unsigned char v) { lua_pushnumber(L, v); }
278 void apply(lua_State* L, unsigned long v) { lua_pushnumber(L, v); }
279 void apply(lua_State* L, float v) { lua_pushnumber(L, v); }
280 void apply(lua_State* L, double v) { lua_pushnumber(L, v); }
281 void apply(lua_State* L, long double v) { lua_pushnumber(L, v); }
282 void apply(lua_State* L, const char* v) { lua_pushstring(L, v); }
283 void apply(lua_State* L, const std::string& v) { lua_pushstring(L, v.c_str()); }
284 void apply(lua_State* L, bool b) { lua_pushboolean(L, b); }
287 template<>
288 struct primitive_converter<lua_to_cpp>
290 // TODO: add more
291 bool apply(lua_State* L, detail::by_value<bool>, int index) { return lua_toboolean(L, index) == 1; }
292 float apply(lua_State* L, detail::by_value<float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
293 double apply(lua_State* L, detail::by_value<double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
294 long double apply(lua_State* L, detail::by_value<long double>, int index) { return static_cast<long double>(lua_tonumber(L, index)); }
295 int apply(lua_State* L, detail::by_value<int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
296 short apply(lua_State* L, detail::by_value<short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
297 char apply(lua_State* L, detail::by_value<char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
298 long apply(lua_State* L, detail::by_value<long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
299 unsigned int apply(lua_State* L, detail::by_value<unsigned int>, int index) { return static_cast<unsigned int>(lua_tonumber(L, index)); }
300 unsigned short apply(lua_State* L, detail::by_value<unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
301 unsigned char apply(lua_State* L, detail::by_value<unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
302 unsigned long apply(lua_State* L, detail::by_value<unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
304 float apply(lua_State* L, detail::by_value<const float>, int index) { return static_cast<float>(lua_tonumber(L, index)); }
305 double apply(lua_State* L, detail::by_value<const double>, int index) { return static_cast<double>(lua_tonumber(L, index)); }
306 long double apply(lua_State* L, detail::by_value<const long double>, int index) {return static_cast<long double>(lua_tonumber(L, index)); }
307 int apply(lua_State* L, detail::by_value<const int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
308 short apply(lua_State* L, detail::by_value<const short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
309 char apply(lua_State* L, detail::by_value<const char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
310 long apply(lua_State* L, detail::by_value<const long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
312 unsigned int apply(lua_State* L, detail::by_value<const unsigned int>, int index) { return static_cast<int>(lua_tonumber(L, index)); }
313 unsigned short apply(lua_State* L, detail::by_value<const unsigned short>, int index) { return static_cast<short>(lua_tonumber(L, index)); }
314 unsigned char apply(lua_State* L, detail::by_value<const unsigned char>, int index) { return static_cast<char>(lua_tonumber(L, index)); }
315 unsigned long apply(lua_State* L, detail::by_value<const unsigned long>, int index) { return static_cast<long>(lua_tonumber(L, index)); }
317 std::string apply(lua_State* L, detail::by_value<std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
318 const std::string apply(lua_State* L, detail::by_value<const std::string>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
320 luabind::object apply(lua_State* L, detail::by_value<luabind::object>, int index)
322 lua_pushvalue(L, index);
323 return luabind::object(L, detail::ref(L), true/*luabind::object::reference()*/);
326 const luabind::object apply(lua_State* L, detail::by_value<const luabind::object>, int index)
328 lua_pushvalue(L, index);
329 return luabind::object(L, detail::ref(L), true/*luabind::object::reference()*/);
332 // TODO: add more
334 template<class T>
335 T apply(lua_State* L, detail::by_const_reference<T>, int index) { return apply(L, detail::by_value<T>(), index); }
337 const char* apply(lua_State* L, detail::by_const_pointer<char>, int index) { return static_cast<const char*>(lua_tostring(L, index)); }
339 // matchers
340 static int match(lua_State* L, detail::by_value<bool>, int index) { if (lua_type(L, index) == LUA_TBOOLEAN) return 0; else return -1;}
341 static int match(lua_State* L, detail::by_value<float>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
342 static int match(lua_State* L, detail::by_value<double>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
343 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;}
344 static int match(lua_State* L, detail::by_value<int>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
345 static int match(lua_State* L, detail::by_value<short>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
346 static int match(lua_State* L, detail::by_value<char>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
347 static int match(lua_State* L, detail::by_value<long>, int index) { if (lua_type(L, index) == LUA_TNUMBER) return 0; else return -1;}
348 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;}
349 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;}
350 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;}
351 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;}
352 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;}
353 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;}
354 static int match(lua_State*, detail::by_value<luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
355 static int match(lua_State*, detail::by_value<const luabind::object>, int) { return std::numeric_limits<int>::max() - 1; }
357 static int match(lua_State* L, by_const_pointer<char>, int index) { if (lua_type(L, index) == LUA_TSTRING) return 0; else return -1;}
358 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;}
360 template<class T>
361 static int match(lua_State* L, detail::by_const_reference<T>, int index) { return match(L, detail::by_value<T>(), index); }
363 template<class T>
364 void converter_postcall(lua_State*, T, int) {}
369 // *********** default converters ***************
372 // ********** user defined converter ***********
374 template<class Direction> struct user_defined_converter;
376 template<>
377 struct user_defined_converter<lua_to_cpp>
379 template<class T>
380 T apply(lua_State* L, detail::by_value<T>, int index)
382 // std::cerr << "user_defined_converter\n";
383 return converters::convert_lua_to_cpp(L, detail::by_value<T>(), index);
386 template<class T>
387 T apply(lua_State* L, detail::by_reference<T>, int index)
389 // std::cerr << "user_defined_converter\n";
390 return converters::convert_lua_to_cpp(L, detail::by_reference<T>(), index);
393 template<class T>
394 T apply(lua_State* L, detail::by_const_reference<T>, int index)
396 // std::cerr << "user_defined_converter\n";
397 return converters::convert_lua_to_cpp(L, detail::by_const_reference<T>(), index);
400 template<class T>
401 T* apply(lua_State* L, detail::by_pointer<T>, int index)
403 // std::cerr << "user_defined_converter\n";
404 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
407 template<class T>
408 const T* apply(lua_State* L, detail::by_const_pointer<T>, int index)
410 // std::cerr << "user_defined_converter\n";
411 return converters::convert_lua_to_cpp(L, detail::by_pointer<T>(), index);
414 template<class T>
415 static int match(lua_State* L, T, int index)
417 return converters::match_lua_to_cpp(L, T(), index);
420 template<class T>
421 void converter_postcall(lua_State*, T, int) {}
424 template<>
425 struct user_defined_converter<cpp_to_lua>
427 template<class T>
428 void apply(lua_State* L, const T& v)
430 converters::convert_cpp_to_lua(L, v);
434 // ********** pointer converter ***********
437 template<class Direction> struct pointer_converter;
439 template<>
440 struct pointer_converter<cpp_to_lua>
442 template<class T>
443 void apply(lua_State* L, T* ptr)
445 if (ptr == 0)
447 lua_pushnil(L);
448 return;
451 class_registry* registry = class_registry::get_registry(L);
452 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
454 // if you get caught in this assert you are
455 // trying to use an unregistered type
456 assert(crep && "you are trying to use an unregistered type");
458 // create the struct to hold the object
459 void* obj = lua_newuserdata(L, sizeof(object_rep));
460 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
461 new(obj) object_rep(ptr, crep, 0, 0);
463 // set the meta table
464 detail::getref(L, crep->metatable_ref());
465 lua_setmetatable(L, -2);
469 template<class T> struct make_pointer { typedef T* type; };
470 template<>
471 struct pointer_converter<lua_to_cpp>
473 template<class T>
474 typename make_pointer<T>::type apply(lua_State* L, by_pointer<T>, int index)
476 // preconditions:
477 // lua_isuserdata(L, index);
478 // getmetatable().__lua_class is true
479 // object_rep->flags() & object_rep::constant == 0
481 if (lua_isnil(L, index)) return 0;
483 int offset = 0;
484 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
485 assert((obj != 0) && "internal error, please report"); // internal error
486 const class_rep* crep = obj->crep();
488 int steps = implicit_cast(crep, LUABIND_TYPEID(T), offset);
490 // should never be called with a type that can't be cast
491 assert((steps >= 0) && "internal error, please report");
493 T* ptr = reinterpret_cast<T*>(obj->ptr(offset));
494 // std::cerr << "pointer_converter<lua_to_cpp>: " << ptr << " " << offset << "\n";
496 return ptr;
499 template<class T>
500 static int match(lua_State* L, by_pointer<T>, int index)
502 if (lua_isnil(L, index)) return 0;
503 object_rep* obj = is_class_object(L, index);
504 if (obj == 0) return -1;
505 // cannot cast a constant object to nonconst
506 if (obj->flags() & object_rep::constant) return -1;
507 int d;
508 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
511 template<class T>
512 void converter_postcall(lua_State*, T, int) {}
515 // ******* value converter *******
517 template<class Direction> struct value_converter;
519 template<>
520 struct value_converter<cpp_to_lua>
522 template<class T>
523 void apply(lua_State* L, const T& ref)
525 class_registry* registry = class_registry::get_registry(L);
526 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
528 // if you get caught in this assert you are
529 // trying to use an unregistered type
530 assert(crep && "you are trying to use an unregistered type");
532 T* copied_obj = new T(ref);
534 // std::cerr << "value_converter<cpp_to_lua>: " << copied_obj << "\n";
536 // create the struct to hold the object
537 void* obj = lua_newuserdata(L, sizeof(object_rep));
538 // we send 0 as destructor since we know it will never be called
539 new(obj) object_rep(copied_obj, crep, object_rep::owner, destructor<T>);
541 // set the meta table
542 detail::getref(L, crep->metatable_ref());
543 lua_setmetatable(L, -2);
548 template<class T> struct make_const_reference { typedef const T& type; };
550 template<>
551 struct value_converter<lua_to_cpp>
553 template<class T>
554 typename make_const_reference<T>::type apply(lua_State* L, by_value<T>, int index)
556 // preconditions:
557 // lua_isuserdata(L, index);
558 // getmetatable().__lua_class is true
559 // object_rep->flags() & object_rep::constant == 0
561 assert((lua_isnil(L, index) == false) && "internal error, please report");
563 int offset = 0;
564 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
565 assert((obj != 0) && "internal error, please report"); // internal error
566 const class_rep* crep = obj->crep();
568 int steps = implicit_cast(crep, LUABIND_TYPEID(T), offset);
570 // should never be called with a type that can't be cast
571 assert((steps >= 0) && "internal error, please report");
573 T* ptr = reinterpret_cast<T*>(obj->ptr(offset));
575 return *ptr;
578 template<class T>
579 static int match(lua_State* L, by_value<T>, int index)
581 if (lua_isnil(L, index)) return 0;
582 object_rep* obj = is_class_object(L, index);
583 if (obj == 0) return -1;
584 int d;
585 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
588 template<class T>
589 void converter_postcall(lua_State*, T, int) {}
592 // ******* const pointer converter *******
594 template<class Direction> struct const_pointer_converter;
596 template<>
597 struct const_pointer_converter<cpp_to_lua>
599 template<class T>
600 void apply(lua_State* L, const T* ptr)
602 if (ptr == 0)
604 lua_pushnil(L);
605 return;
608 class_registry* registry = class_registry::get_registry(L);
609 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
611 // if you get caught in this assert you are
612 // trying to use an unregistered type
613 assert(crep && "you are trying to use an unregistered type");
615 // create the struct to hold the object
616 void* obj = lua_newuserdata(L, sizeof(object_rep));
617 assert(obj && "internal error, please report");
618 // we send 0 as destructor since we know it will never be called
619 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
621 // set the meta table
622 detail::getref(L, crep->metatable_ref());
623 lua_setmetatable(L, -2);
628 template<class T> struct make_const_pointer { typedef const T* type; };
629 template<>
630 struct const_pointer_converter<lua_to_cpp>
632 template<class T>
633 typename make_const_pointer<T>::type apply(lua_State* L, by_const_pointer<T>, int index)
635 // std::cerr << "const_pointer_converter\n";
636 return pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
639 template<class T>
640 static int match(lua_State* L, by_const_pointer<T>, int index)
642 if (lua_isnil(L, index)) return 0;
643 object_rep* obj = is_class_object(L, index);
644 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
645 int d;
646 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
649 template<class T>
650 void converter_postcall(lua_State*, T, int) {}
653 // ******* reference converter *******
655 template<class Direction> struct ref_converter;
657 template<>
658 struct ref_converter<cpp_to_lua>
660 template<class T>
661 void apply(lua_State* L, T& ref)
663 class_registry* registry = class_registry::get_registry(L);
664 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
666 // if you get caught in this assert you are
667 // trying to use an unregistered type
668 assert(crep && "you are trying to use an unregistered type");
670 T* ptr = &ref;
672 // create the struct to hold the object
673 void* obj = lua_newuserdata(L, sizeof(object_rep));
674 assert(obj && "internal error, please report");
675 new(obj) object_rep(ptr, crep, 0, 0);
677 // set the meta table
678 detail::getref(L, crep->metatable_ref());
679 lua_setmetatable(L, -2);
683 template<class T> struct make_reference { typedef T& type; };
684 template<>
685 struct ref_converter<lua_to_cpp>
687 template<class T>
688 typename make_reference<T>::type apply(lua_State* L, by_reference<T>, int index)
690 // std::cerr << "ref_converter<lua_to_cpp>\n";
691 return *pointer_converter<lua_to_cpp>().apply(L, by_pointer<T>(), index);
694 template<class T>
695 static int match(lua_State* L, by_reference<T>, int index)
697 return pointer_converter<lua_to_cpp>::match(L, by_pointer<T>(), index);
700 template<class T>
701 void converter_postcall(lua_State*, T, int) {}
704 // ******** const reference converter *********
706 template<class Direction> struct const_ref_converter;
708 template<>
709 struct const_ref_converter<cpp_to_lua>
711 template<class T>
712 void apply(lua_State* L, const T& ref)
714 class_registry* registry = class_registry::get_registry(L);
715 class_rep* crep = registry->find_class(LUABIND_TYPEID(T));
717 // if you get caught in this assert you are
718 // trying to use an unregistered type
719 assert(crep && "you are trying to use an unregistered type");
721 T* ptr = const_cast<T*>(&ref);
723 // std::cerr << "const_ref_converter<cpp_to_lua>: " << ptr << "\n";
725 // create the table to hold the object
726 object_rep* obj = static_cast<object_rep*>(lua_newuserdata(L, sizeof(object_rep)));
727 assert(obj && "internal error, please report");
728 new(obj) object_rep(ptr, crep, object_rep::constant, 0);
730 // set the meta table
731 detail::getref(L, crep->metatable_ref());
732 lua_setmetatable(L, -2);
736 template<>
737 struct const_ref_converter<lua_to_cpp>
739 template<class T>
740 typename make_const_reference<T>::type apply(lua_State* L, by_const_reference<T>, int index)
742 // std::cerr << "const_ref_converter<lua_to_cpp>\n";
743 return *const_pointer_converter<lua_to_cpp>().apply(L, by_const_pointer<T>(), index);
746 template<class T>
747 static int match(lua_State* L, by_const_reference<T>, int index)
749 return const_pointer_converter<lua_to_cpp>::match(L, by_const_pointer<T>(), index);
752 template<class T>
753 void converter_postcall(lua_State*, T, int) {}
756 // ****** enum converter ********
758 template<class Direction = cpp_to_lua>
759 struct enum_converter;
761 template<>
762 struct enum_converter<lua_to_cpp>
764 template<class T>
765 T apply(lua_State* L, by_value<T>, int index)
767 // std::cerr << "enum_converter\n";
768 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
771 template<class T>
772 static int match(lua_State* L, by_value<T>, int index)
774 if (lua_isnumber(L, index)) return 0; else return -1;
777 template<class T>
778 void converter_postcall(lua_State*, T, int) {}
781 // ****** functor converter ********
783 template<class Direction> struct functor_converter;
785 template<>
786 struct functor_converter<lua_to_cpp>
788 template<class T>
789 functor<T> apply(lua_State* L, by_const_reference<functor<T> >, int index)
791 lua_pushvalue(L, index);
792 int ref = detail::ref(L);
793 return functor<T>(L, ref);
796 template<class T>
797 functor<T> apply(lua_State* L, by_value<functor<T> >, int index)
799 lua_pushvalue(L, index);
800 int ref = detail::ref(L);
801 return functor<T>(L, ref);
804 template<class T>
805 static int match(lua_State* L, by_const_reference<functor<T> >, int index)
807 if (lua_isfunction(L, index)) return 0; else return -1;
810 template<class T>
811 static int match(lua_State* L, by_value<functor<T> >, int index)
813 if (lua_isfunction(L, index)) return 0; else return -1;
816 template<class T>
817 void converter_postcall(lua_State*, T, int) {}
824 // *********** default_policy *****************
828 struct default_policy : converter_policy_tag
830 BOOST_STATIC_CONSTANT(bool, has_arg = true);
832 template<class T>
833 static void precall(lua_State*, T, int) {}
835 // template<class T>
836 // static void postcall(lua_State*, T, int) {}
838 template<class T, class Direction>
839 struct generate_converter
841 typedef typename boost::mpl::if_<is_user_defined<T>
842 , user_defined_converter<Direction>
843 , typename boost::mpl::if_<is_primitive<T>
844 , primitive_converter<Direction>
845 , typename boost::mpl::if_<is_lua_functor<T>
846 , functor_converter<Direction>
847 , typename boost::mpl::if_<boost::is_enum<T>
848 , enum_converter<Direction>
849 , typename boost::mpl::if_<is_nonconst_pointer<T>
850 , pointer_converter<Direction>
851 , typename boost::mpl::if_<is_const_pointer<T>
852 , const_pointer_converter<Direction>
853 , typename boost::mpl::if_<is_nonconst_reference<T>
854 , ref_converter<Direction>
855 , typename boost::mpl::if_<is_const_reference<T>
856 , const_ref_converter<Direction>
857 , value_converter<Direction>
858 >::type>::type>::type>::type>::type>::type>::type>::type type;
862 // ********** get policy **********
864 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
865 template<int N, class T>
866 struct get_policy_list_impl
868 template<class U>
869 struct inner
871 typedef typename U::head head;
872 typedef typename U::tail tail;
874 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
875 , policy_cons<head, typename get_policy_list_impl<N, tail>::type>
876 , typename get_policy_list_impl<N, tail>::type
877 >::type type;
880 template<>
881 struct inner<null_type>
883 typedef null_type type;
886 typedef typename inner<T>::type type;
888 #else
889 template<class List>
890 struct get_policy_list_impl
892 template<int N>
893 struct apply
895 typedef typename List::head head;
896 typedef typename List::tail tail;
898 typedef typename boost::mpl::if_<boost::mpl::equal_to<boost::mpl::integral_c<int, head::index>, boost::mpl::integral_c<int, N> >
899 , policy_cons<head, typename get_policy_list_impl<tail>::template apply<N>::type>
900 , typename get_policy_list_impl<tail>::template apply<N>::type
901 >::type type;
905 template<>
906 struct get_policy_list_impl<detail::null_type>
908 template<int N>
909 struct apply
911 typedef null_type type;
914 #endif
916 template<int N, class T>
917 struct get_policy_list
919 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
920 typedef typename get_policy_list_impl<N, T>::type type;
921 #else
922 typedef typename get_policy_list_impl<T>::template apply<N>::type type;
923 #endif
926 // ============== new policy system =================
928 template<int, class> struct find_conversion_policy;
930 template<bool IsConverter = false>
931 struct find_conversion_impl
933 template<int N, class Policies>
934 struct apply
936 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
940 template<>
941 struct find_conversion_impl<true>
943 template<int N, class Policies>
944 struct apply
946 typedef typename Policies::head head;
947 typedef typename Policies::tail tail;
949 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
951 typedef typename
952 boost::mpl::if_c<found
953 , head
954 , typename find_conversion_policy<N, tail>::type
955 >::type type;
959 template<class Policies>
960 struct find_conversion_impl2
962 template<int N>
963 struct apply
964 : find_conversion_impl<
965 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
966 >::template apply<N, Policies>
971 template<>
972 struct find_conversion_impl2<detail::null_type>
974 template<int N>
975 struct apply
977 typedef default_policy type;
981 template<int N, class Policies>
982 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
986 template<class List>
987 struct policy_list_postcall
989 typedef typename List::head head;
990 typedef typename List::tail tail;
992 static void apply(lua_State* L, const index_map& i)
994 head::postcall(L, i);
995 policy_list_postcall<tail>::apply(L, i);
999 template<>
1000 struct policy_list_postcall<detail::null_type>
1002 static void apply(lua_State*, const index_map&) {}
1005 /* template<int N>
1006 struct find_conversion_policy<N, detail::null_type>
1008 typedef default_policy type;
1009 };*/
1011 // ==================================================
1013 // ************** precall and postcall on policy_cons *********************
1016 template<class List>
1017 struct policy_precall
1019 typedef typename List::head head;
1020 typedef typename List::tail tail;
1022 static void apply(lua_State* L, int index)
1024 head::precall(L, index);
1025 policy_precall<tail>::apply(L, index);
1029 template<>
1030 struct policy_precall<detail::null_type>
1032 static void apply(lua_State*, int) {}
1035 template<class List>
1036 struct policy_postcall
1038 typedef typename List::head head;
1039 typedef typename List::tail tail;
1041 static void apply(lua_State* L, int index)
1043 head::postcall(L, index);
1044 policy_postcall<tail>::apply(L, index);
1048 template<>
1049 struct policy_postcall<detail::null_type>
1051 static void apply(lua_State*, int) {}
1055 struct pointer_only_converter
1057 template<class T>
1058 static const T* apply(lua_State* L, type<const T*>, int index)
1060 int a = index;
1064 struct only_one_converter_policy_can_be_used_per_index {};
1066 template<class List, class T> struct assert_converter_policy_impl;
1068 template<class List>
1069 struct assert_converter_policy
1071 template<class T>
1072 struct apply
1074 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, typename List::head>
1075 , only_one_converter_policy_can_be_used_per_index
1076 , typename assert_converter_policy_impl<typename List::tail, T>::type
1077 >::type type;
1081 template<>
1082 struct assert_converter_policy<detail::null_type>
1084 template<class T>
1085 struct apply
1087 typedef T type;
1091 template<class List, class T>
1092 struct assert_converter_policy_impl
1094 typedef typename assert_converter_policy<List>::template apply<T>::type type;
1097 template<class List>
1098 struct find_converter_policy_impl
1100 typedef typename List::head head;
1101 typedef typename List::tail tail;
1103 typedef typename boost::mpl::if_<boost::is_base_and_derived<converter_policy_tag, head>
1104 , typename assert_converter_policy_impl<tail, head>::type
1105 , typename find_converter_policy_impl<tail>::type
1106 >::type type;
1109 template<>
1110 struct find_converter_policy_impl<detail::null_type>
1112 typedef default_policy type;
1115 /* template<class List>
1116 struct find_converter_policy
1117 : find_converter_policy_impl<List>
1125 namespace luabind { namespace
1127 LUABIND_ANONYMOUS_FIX boost::arg<0> return_value;
1128 LUABIND_ANONYMOUS_FIX boost::arg<0> result;
1131 #include <luabind/detail/object_funs.hpp>
1133 #endif // LUABIND_POLICY_HPP_INCLUDED