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>
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>
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
);
66 index_map(const int* m
): m_map(m
) {}
68 int operator[](int index
) const
70 return m_map
[index
+ 1];
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(...);
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
;
107 namespace luabind
{ namespace detail
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(...);
119 no_t
is_lua_functor_test(const T
&);
123 struct is_lua_functor
127 BOOST_STATIC_CONSTANT(bool, value
= sizeof(is_lua_functor_test(t
)) == sizeof(yes_t
));
132 static char msvc_fix
[64];
139 boost::mpl::if_
<is_primitive
<T
>
141 , typename
boost::mpl::apply_if
<boost::mpl::or_
<boost::is_reference
<T
>, boost::is_pointer
<T
> >
143 , boost::add_reference
<T
>
147 static inline result_type
get()
149 return reinterpret_cast<result_type
>(msvc_fix
);
153 template<class H
, class T
>
160 policy_cons
<U
, policy_cons
<H
,T
> > operator,(policy_cons
<U
,detail::null_type
>)
162 return policy_cons
<U
, policy_cons
<H
,T
> >();
166 policy_cons
<U
, policy_cons
<H
,T
> > operator+(policy_cons
<U
,detail::null_type
>)
168 return policy_cons
<U
, policy_cons
<H
,T
> >();
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
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(...);
189 struct is_policy_cons
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*);
201 struct is_primitive
/*: boost::mpl::bool_c<false>*/
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> {};
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
;
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");
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
); }
288 struct primitive_converter
<lua_to_cpp
>
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()*/);
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
)); }
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;}
361 static int match(lua_State
* L
, detail::by_const_reference
<T
>, int index
) { return match(L
, detail::by_value
<T
>(), index
); }
364 void converter_postcall(lua_State
*, T
, int) {}
369 // *********** default converters ***************
372 // ********** user defined converter ***********
374 template<class Direction
> struct user_defined_converter
;
377 struct user_defined_converter
<lua_to_cpp
>
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
);
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
);
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
);
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
);
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
);
415 static int match(lua_State
* L
, T
, int index
)
417 return converters::match_lua_to_cpp(L
, T(), index
);
421 void converter_postcall(lua_State
*, T
, int) {}
425 struct user_defined_converter
<cpp_to_lua
>
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
;
440 struct pointer_converter
<cpp_to_lua
>
443 void apply(lua_State
* L
, T
* ptr
)
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
; };
471 struct pointer_converter
<lua_to_cpp
>
474 typename make_pointer
<T
>::type
apply(lua_State
* L
, by_pointer
<T
>, int index
)
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;
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";
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;
508 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
512 void converter_postcall(lua_State
*, T
, int) {}
515 // ******* value converter *******
517 template<class Direction
> struct value_converter
;
520 struct value_converter
<cpp_to_lua
>
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
; };
551 struct value_converter
<lua_to_cpp
>
554 typename make_const_reference
<T
>::type
apply(lua_State
* L
, by_value
<T
>, int index
)
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");
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
));
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;
585 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
589 void converter_postcall(lua_State
*, T
, int) {}
592 // ******* const pointer converter *******
594 template<class Direction
> struct const_pointer_converter
;
597 struct const_pointer_converter
<cpp_to_lua
>
600 void apply(lua_State
* L
, const T
* ptr
)
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
; };
630 struct const_pointer_converter
<lua_to_cpp
>
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
);
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
646 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
650 void converter_postcall(lua_State
*, T
, int) {}
653 // ******* reference converter *******
655 template<class Direction
> struct ref_converter
;
658 struct ref_converter
<cpp_to_lua
>
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");
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
; };
685 struct ref_converter
<lua_to_cpp
>
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
);
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
);
701 void converter_postcall(lua_State
*, T
, int) {}
704 // ******** const reference converter *********
706 template<class Direction
> struct const_ref_converter
;
709 struct const_ref_converter
<cpp_to_lua
>
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);
737 struct const_ref_converter
<lua_to_cpp
>
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
);
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
);
753 void converter_postcall(lua_State
*, T
, int) {}
756 // ****** enum converter ********
758 template<class Direction
= cpp_to_lua
>
759 struct enum_converter
;
762 struct enum_converter
<lua_to_cpp
>
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
)));
772 static int match(lua_State
* L
, by_value
<T
>, int index
)
774 if (lua_isnumber(L
, index
)) return 0; else return -1;
778 void converter_postcall(lua_State
*, T
, int) {}
781 // ****** functor converter ********
783 template<class Direction
> struct functor_converter
;
786 struct functor_converter
<lua_to_cpp
>
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
);
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
);
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;
811 static int match(lua_State
* L
, by_value
<functor
<T
> >, int index
)
813 if (lua_isfunction(L
, index
)) return 0; else return -1;
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);
833 static void precall(lua_State
*, T
, int) {}
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
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
881 struct inner
<null_type
>
883 typedef null_type type
;
886 typedef typename inner
<T
>::type type
;
890 struct get_policy_list_impl
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
906 struct get_policy_list_impl
<detail::null_type
>
911 typedef null_type type
;
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
;
922 typedef typename get_policy_list_impl
<T
>::template apply
<N
>::type type
;
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
>
936 typedef typename find_conversion_policy
<N
, typename
Policies::tail
>::type type
;
941 struct find_conversion_impl
<true>
943 template<int N
, class Policies
>
946 typedef typename
Policies::head head
;
947 typedef typename
Policies::tail tail
;
949 BOOST_STATIC_CONSTANT(bool, found
= (N
== head::index
));
952 boost::mpl::if_c
<found
954 , typename find_conversion_policy
<N
, tail
>::type
959 template<class Policies
>
960 struct find_conversion_impl2
964 : find_conversion_impl
<
965 boost::is_base_and_derived
<conversion_policy_base
, typename
Policies::head
>::value
966 >::template apply
<N
, Policies
>
972 struct find_conversion_impl2
<detail::null_type
>
977 typedef default_policy type
;
981 template<int N
, class Policies
>
982 struct find_conversion_policy
: find_conversion_impl2
<Policies
>::template apply
<N
>
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
);
1000 struct policy_list_postcall
<detail::null_type
>
1002 static void apply(lua_State
*, const index_map
&) {}
1006 struct find_conversion_policy<N, detail::null_type>
1008 typedef default_policy type;
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
);
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
);
1049 struct policy_postcall
<detail::null_type
>
1051 static void apply(lua_State
*, int) {}
1055 struct pointer_only_converter
1058 static const T* apply(lua_State* L, type<const T*>, int 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
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
1082 struct assert_converter_policy
<detail::null_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
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