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>
33 #include <boost/type_traits/is_enum.hpp>
34 #include <boost/type_traits/is_array.hpp>
35 #include <boost/mpl/bool.hpp>
36 #include <boost/mpl/integral_c.hpp>
37 #include <boost/mpl/equal_to.hpp>
38 #include <boost/mpl/eval_if.hpp>
39 #include <boost/mpl/or.hpp>
40 #include <boost/type_traits/add_reference.hpp>
41 #include <boost/type_traits/remove_reference.hpp>
42 #include <boost/type_traits/is_pointer.hpp>
43 #include <boost/type_traits/is_base_and_derived.hpp>
44 #include <boost/bind/arg.hpp>
45 #include <boost/limits.hpp>
46 #include <boost/tuple/tuple.hpp>
47 #include <boost/version.hpp>
49 #include <luabind/detail/class_registry.hpp>
50 #include <luabind/detail/primitives.hpp>
51 #include <luabind/detail/object_rep.hpp>
52 #include <luabind/detail/typetraits.hpp>
53 #include <luabind/detail/class_cache.hpp>
54 #include <luabind/detail/debug.hpp>
55 #include <luabind/detail/class_rep.hpp>
56 #include <luabind/detail/conversion_storage.hpp>
57 #include <luabind/detail/has_get_pointer.hpp>
59 #include <boost/type_traits/add_reference.hpp>
61 #include <luabind/detail/decorate_type.hpp>
62 #include <luabind/weak_ref.hpp>
63 #include <luabind/back_reference_fwd.hpp>
65 #include <luabind/value_wrapper.hpp>
66 #include <luabind/from_stack.hpp>
67 #include <luabind/typeid.hpp>
73 struct conversion_policy_base
{};
76 template<int N
, bool HasArg
= true>
77 struct conversion_policy
: detail::conversion_policy_base
79 BOOST_STATIC_CONSTANT(int, index
= N
);
80 BOOST_STATIC_CONSTANT(bool, has_arg
= HasArg
);
86 index_map(const int* m
): m_map(m
) {}
88 int operator[](int index
) const
100 LUABIND_API
int implicit_cast(const class_rep
* crep
, type_id
const&, int& pointer_offset
);
103 // template<class T> class functor;
107 namespace luabind
{ namespace detail
109 template<class H
, class T
>
116 policy_cons
<U
, policy_cons
<H
,T
> > operator,(policy_cons
<U
,detail::null_type
>)
118 return policy_cons
<U
, policy_cons
<H
,T
> >();
122 policy_cons
<U
, policy_cons
<H
,T
> > operator+(policy_cons
<U
,detail::null_type
>)
124 return policy_cons
<U
, policy_cons
<H
,T
> >();
128 policy_cons
<U
, policy_cons
<H
,T
> > operator|(policy_cons
<U
,detail::null_type
>)
130 return policy_cons
<U
, policy_cons
<H
,T
> >();
134 struct indirection_layer
137 indirection_layer(const T
&);
140 yes_t
is_policy_cons_test(const null_type
&);
141 template<class H
, class T
>
142 yes_t
is_policy_cons_test(const policy_cons
<H
,T
>&);
143 no_t
is_policy_cons_test(...);
146 struct is_policy_cons
150 BOOST_STATIC_CONSTANT(bool, value
=
151 sizeof(is_policy_cons_test(t
)) == sizeof(yes_t
));
153 typedef boost::mpl::bool_
<value
> type
;
157 struct is_string_literal
159 static no_t
helper(indirection_layer
);
160 static yes_t
helper(const char*);
164 struct is_string_literal
<false>
166 static no_t
helper(indirection_layer
);
170 namespace mpl
= boost::mpl
;
172 // ********** pointer converter ***********
175 void install_instance(P ptr
, object_rep
& instance
)
177 typedef pointer_holder
<P
> holder_type
;
179 void* storage
= instance
.allocate(sizeof(holder_type
));
183 new (storage
) holder_type(ptr
, instance
.crep());
187 instance
.deallocate(storage
);
191 instance
.set_instance((holder_type
*)storage
);
194 struct pointer_converter
196 typedef pointer_converter type
;
197 typedef mpl::false_ is_native
;
205 int const consumed_args(...)
211 void apply(lua_State
* L
, T
* ptr
)
219 if (luabind::get_back_reference(L
, ptr
))
222 class_rep
* crep
= get_class_rep
<T
>(L
);
224 // if you get caught in this assert you are
225 // trying to use an unregistered type
226 assert(crep
&& "you are trying to use an unregistered type");
228 object_rep
* instance
= push_new_instance(L
, crep
);
229 install_instance(ptr
, *instance
);
232 conversion_storage storage
;
235 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
237 return static_cast<T
*>(result
);
241 int match(lua_State
* L
, by_pointer
<T
>, int index
)
243 if (lua_isnil(L
, index
)) return 0;
244 object_rep
* obj
= get_instance(L
, index
);
245 if (obj
== 0) return -1;
250 std::pair
<void*, int> s
= obj
->get_instance(typeid(T
));
256 void converter_postcall(lua_State
*, by_pointer
<T
>, int)
260 // ******* value converter *******
262 struct value_converter
264 typedef value_converter type
;
265 typedef mpl::false_ is_native
;
268 void install(T
& x
, object_rep
& instance
, mpl::false_
)
270 std::auto_ptr
<T
> ptr(new T(x
));
271 install_instance(ptr
, instance
);
275 void install(T
& x
, object_rep
& instance
, mpl::true_
)
277 install_instance(x
, instance
);
281 class_rep
* get_class(T
const*, lua_State
* L
, mpl::false_
)
283 return get_class_rep
<T
>(L
);
287 class_rep
* get_class(T
const* x
, lua_State
* L
, mpl::true_
)
289 return get_class(get_pointer(*x
), L
, mpl::false_());
292 int const consumed_args(...)
298 void apply(lua_State
* L
, T x
)
300 if (luabind::get_back_reference(L
, x
))
303 class_rep
* crep
= get_class(&x
, L
, has_get_pointer
<T
>());
305 // if you get caught in this assert you are
306 // trying to use an unregistered type
307 assert(crep
&& "you are trying to use an unregistered type");
309 object_rep
* instance
= push_new_instance(L
, crep
);
310 install(x
, *instance
, has_get_pointer
<T
>());
313 conversion_storage storage
;
316 T
apply(lua_State
* L
, by_value
<T
>, int index
)
319 // lua_isuserdata(L, index);
320 // getmetatable().__lua_class is true
322 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
323 assert((obj
!= 0) && "internal error, please report"); // internal error
325 return *static_cast<T
*>(obj
->get_instance(typeid(T
)).first
);
329 static int match(lua_State
* L
, by_value
<T
>, int index
)
331 // special case if we get nil in, try to match the holder type
332 if (lua_isnil(L
, index
))
335 object_rep
* obj
= get_instance(L
, index
);
336 if (obj
== 0) return -1;
338 return obj
->get_instance(typeid(T
)).second
;
342 void converter_postcall(lua_State
*, T
, int) {}
345 // ******* const pointer converter *******
347 struct const_pointer_converter
: pointer_converter
349 typedef const_pointer_converter type
;
352 void apply(lua_State
* L
, const T
* ptr
)
360 if (luabind::get_back_reference(L
, ptr
))
363 class_rep
* crep
= get_class_rep
<T
>(L
);
365 // if you get caught in this assert you are
366 // trying to use an unregistered type
367 assert(crep
&& "you are trying to use an unregistered type");
369 object_rep
* instance
= push_new_instance(L
, crep
);
370 install_instance(ptr
, *instance
);
374 T
const* apply(lua_State
* L
, by_const_pointer
<T
>, int index
)
376 return pointer_converter::apply(L
, by_pointer
<T
>(), index
);
380 static int match(lua_State
* L
, by_const_pointer
<T
>, int index
)
382 if (lua_isnil(L
, index
)) return 0;
383 object_rep
* obj
= get_instance(L
, index
);
384 if (obj
== 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
385 int score
= obj
->get_instance(typeid(T
)).second
;
387 if (score
>= 0 && !obj
->is_const())
394 void converter_postcall(lua_State
* L
, by_const_pointer
<T
>, int index
)
396 pointer_converter::converter_postcall(L
, by_pointer
<T
>(), index
);
400 // ******* reference converter *******
402 struct ref_converter
: pointer_converter
404 typedef ref_converter type
;
405 typedef mpl::false_ is_native
;
407 int const consumed_args(...)
413 void apply(lua_State
* L
, T
& ref
)
415 if (luabind::get_back_reference(L
, ref
))
418 class_rep
* crep
= get_class_rep
<T
>(L
);
420 // if you get caught in this assert you are
421 // trying to use an unregistered type
422 assert(crep
&& "you are trying to use an unregistered type");
424 object_rep
* instance
= push_new_instance(L
, crep
);
425 install_instance(&ref
, *instance
);
429 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
431 assert(!lua_isnil(L
, index
));
432 return *pointer_converter::apply(L
, by_pointer
<T
>(), index
);
436 int match(lua_State
* L
, by_reference
<T
>, int index
)
438 if (lua_isnil(L
, index
)) return -1;
439 return pointer_converter::match(L
, by_pointer
<T
>(), index
);
443 void converter_postcall(lua_State
*, T
, int) {}
446 // ******** const reference converter *********
448 struct const_ref_converter
450 typedef const_ref_converter type
;
451 typedef mpl::false_ is_native
;
453 int const consumed_args(...)
458 const_ref_converter()
465 void apply(lua_State
* L
, T
const& ref
)
467 if (luabind::get_back_reference(L
, ref
))
470 class_rep
* crep
= get_class_rep
<T
>(L
);
472 // if you get caught in this assert you are
473 // trying to use an unregistered type
474 assert(crep
&& "you are trying to use an unregistered type");
476 // create the struct to hold the object
477 object_rep
* instance
= push_new_instance(L
, crep
);
478 install_instance(&ref
, *instance
);
481 conversion_storage storage
;
484 T
const& apply(lua_State
* L
, by_const_reference
<T
>, int index
)
486 return *static_cast<T
*>(result
);
490 int match(lua_State
* L
, by_const_reference
<T
>, int index
)
492 object_rep
* obj
= get_instance(L
, index
);
493 if (obj
== 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
495 std::pair
<void*, int> s
= obj
->get_instance(typeid(T
));
496 if (s
.second
>= 0 && !obj
->is_const())
503 void converter_postcall(lua_State
* L
, by_const_reference
<T
>, int index
)
508 // ****** enum converter ********
510 struct enum_converter
512 typedef enum_converter type
;
513 typedef mpl::true_ is_native
;
515 int const consumed_args(...)
520 void apply(lua_State
* L
, int val
)
522 lua_pushnumber(L
, val
);
526 T
apply(lua_State
* L
, by_value
<T
>, int index
)
528 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
532 static int match(lua_State
* L
, by_value
<T
>, int index
)
534 if (lua_isnumber(L
, index
)) return 0; else return -1;
538 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
540 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
544 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
546 if (lua_isnumber(L
, index
)) return 0; else return -1;
550 void converter_postcall(lua_State
*, T
, int) {}
554 struct value_wrapper_converter
556 typedef value_wrapper_converter
<U
> type
;
557 typedef mpl::true_ is_native
;
559 int const consumed_args(...)
565 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
567 return T(from_stack(L
, index
));
571 T
apply(lua_State
* L
, by_value
<T
>, int index
)
573 return apply(L
, by_const_reference
<T
>(), index
);
577 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
579 return value_wrapper_traits
<T
>::check(L
, index
)
580 ? (std::numeric_limits
<int>::max
)() / LUABIND_MAX_ARITY
585 static int match(lua_State
* L
, by_value
<T
>, int index
)
587 return match(L
, by_const_reference
<T
>(), index
);
590 void converter_postcall(...) {}
593 void apply(lua_State
* interpreter
, T
const& value_wrapper
)
595 value_wrapper_traits
<T
>::unwrap(interpreter
, value_wrapper
);
600 struct default_converter_generator
602 is_value_wrapper_arg
<T
>
603 , value_wrapper_converter
<T
>
605 boost::is_enum
<typename
boost::remove_reference
<T
>::type
>
608 is_nonconst_pointer
<T
>
612 , const_pointer_converter
614 is_nonconst_reference
<T
>
617 is_const_reference
<T
>
618 , const_ref_converter
628 } // namespace detail
630 // *********** default_policy *****************
633 struct default_converter
634 : detail::default_converter_generator
<T
>::type
637 template <class T
, class Derived
= default_converter
<T
> >
638 struct native_converter_base
640 typedef boost::mpl::true_ is_native
;
642 int const consumed_args(...)
648 void converter_postcall(lua_State
*, U
const&, int)
651 static int match(lua_State
* L
, detail::by_value
<T
>, int index
)
653 return Derived::compute_score(L
, index
);
656 static int match(lua_State
* L
, detail::by_value
<T
const>, int index
)
658 return Derived::compute_score(L
, index
);
661 static int match(lua_State
* L
, detail::by_const_reference
<T
>, int index
)
663 return Derived::compute_score(L
, index
);
666 T
apply(lua_State
* L
, detail::by_value
<T
>, int index
)
668 return derived().from(L
, index
);
671 T
apply(lua_State
* L
, detail::by_value
<T
const>, int index
)
673 return derived().from(L
, index
);
676 T
apply(lua_State
* L
, detail::by_const_reference
<T
>, int index
)
678 return derived().from(L
, index
);
681 void apply(lua_State
* L
, T
const& value
)
683 derived().to(L
, value
);
688 return static_cast<Derived
&>(*this);
692 # define LUABIND_NUMBER_CONVERTER(type) \
694 struct default_converter<type> \
695 : native_converter_base<type> \
697 static int compute_score(lua_State* L, int index) \
699 return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
702 type from(lua_State* L, int index) \
704 return static_cast<type>(lua_tonumber(L, index)); \
707 void to(lua_State* L, type const& value) \
709 lua_pushnumber(L, static_cast<lua_Number>(value)); \
714 struct default_converter<type const> \
715 : default_converter<type> \
719 struct default_converter<type const&> \
720 : default_converter<type> \
723 LUABIND_NUMBER_CONVERTER(char)
724 LUABIND_NUMBER_CONVERTER(signed char)
725 LUABIND_NUMBER_CONVERTER(unsigned char)
726 LUABIND_NUMBER_CONVERTER(signed short)
727 LUABIND_NUMBER_CONVERTER(unsigned short)
728 LUABIND_NUMBER_CONVERTER(signed int)
729 LUABIND_NUMBER_CONVERTER(unsigned int)
730 LUABIND_NUMBER_CONVERTER(signed long)
731 LUABIND_NUMBER_CONVERTER(unsigned long)
732 LUABIND_NUMBER_CONVERTER(float)
733 LUABIND_NUMBER_CONVERTER(double)
734 LUABIND_NUMBER_CONVERTER(long double)
736 # undef LUABIND_NUMBER_CONVERTER
739 struct default_converter
<bool>
740 : native_converter_base
<bool>
742 static int compute_score(lua_State
* L
, int index
)
744 return lua_type(L
, index
) == LUA_TBOOLEAN
? 0 : -1;
747 bool from(lua_State
* L
, int index
)
749 return lua_toboolean(L
, index
) == 1;
752 void to(lua_State
* L
, bool value
)
754 lua_pushboolean(L
, value
);
759 struct default_converter
<bool const>
760 : default_converter
<bool>
764 struct default_converter
<bool const&>
765 : default_converter
<bool>
769 struct default_converter
<std::string
>
770 : native_converter_base
<std::string
>
772 static int compute_score(lua_State
* L
, int index
)
774 return lua_type(L
, index
) == LUA_TSTRING
? 0 : -1;
777 std::string
from(lua_State
* L
, int index
)
779 return std::string(lua_tostring(L
, index
), lua_strlen(L
, index
));
782 void to(lua_State
* L
, std::string
const& value
)
784 lua_pushlstring(L
, value
.data(), value
.size());
789 struct default_converter
<std::string
const>
790 : default_converter
<std::string
>
794 struct default_converter
<std::string
const&>
795 : default_converter
<std::string
>
799 struct default_converter
<char const*>
801 typedef boost::mpl::true_ is_native
;
803 int const consumed_args(...)
809 static int match(lua_State
* L
, U
, int index
)
811 return lua_type(L
, index
) == LUA_TSTRING
? 0 : -1;
815 char const* apply(lua_State
* L
, U
, int index
)
817 return lua_tostring(L
, index
);
820 void apply(lua_State
* L
, char const* str
)
822 lua_pushstring(L
, str
);
826 void converter_postcall(lua_State
*, U
, int)
831 struct default_converter
<const char* const>
832 : default_converter
<char const*>
836 struct default_converter
<char*>
837 : default_converter
<char const*>
840 template <std::size_t N
>
841 struct default_converter
<char const[N
]>
842 : default_converter
<char const*>
845 template <std::size_t N
>
846 struct default_converter
<char[N
]>
847 : default_converter
<char const*>
851 struct default_converter
<lua_State
*>
853 int const consumed_args(...)
859 lua_State
* apply(lua_State
* L
, U
, int)
865 static int match(lua_State
*, U
, int)
871 void converter_postcall(lua_State
*, U
, int) {}
877 struct default_policy
: converter_policy_tag
879 BOOST_STATIC_CONSTANT(bool, has_arg
= true);
882 static void precall(lua_State
*, T
, int) {}
884 template<class T
, class Direction
>
887 typedef default_converter
<T
> type
;
893 : default_converter
<T
>::is_native
896 // ============== new policy system =================
898 template<int, class> struct find_conversion_policy
;
900 template<bool IsConverter
= false>
901 struct find_conversion_impl
903 template<int N
, class Policies
>
906 typedef typename find_conversion_policy
<N
, typename
Policies::tail
>::type type
;
911 struct find_conversion_impl
<true>
913 template<int N
, class Policies
>
916 typedef typename
Policies::head head
;
917 typedef typename
Policies::tail tail
;
919 BOOST_STATIC_CONSTANT(bool, found
= (N
== head::index
));
922 boost::mpl::if_c
<found
924 , typename find_conversion_policy
<N
, tail
>::type
929 template<class Policies
>
930 struct find_conversion_impl2
934 : find_conversion_impl
<
935 boost::is_base_and_derived
<conversion_policy_base
, typename
Policies::head
>::value
936 >::template apply
<N
, Policies
>
942 struct find_conversion_impl2
<detail::null_type
>
947 typedef default_policy type
;
951 template<int N
, class Policies
>
952 struct find_conversion_policy
: find_conversion_impl2
<Policies
>::template apply
<N
>
957 struct policy_list_postcall
959 typedef typename
List::head head
;
960 typedef typename
List::tail tail
;
962 static void apply(lua_State
* L
, const index_map
& i
)
964 head::postcall(L
, i
);
965 policy_list_postcall
<tail
>::apply(L
, i
);
970 struct policy_list_postcall
<detail::null_type
>
972 static void apply(lua_State
*, const index_map
&) {}
975 // ==================================================
977 // ************** precall and postcall on policy_cons *********************
981 struct policy_precall
983 typedef typename
List::head head
;
984 typedef typename
List::tail tail
;
986 static void apply(lua_State
* L
, int index
)
988 head::precall(L
, index
);
989 policy_precall
<tail
>::apply(L
, index
);
994 struct policy_precall
<detail::null_type
>
996 static void apply(lua_State
*, int) {}
1000 struct policy_postcall
1002 typedef typename
List::head head
;
1003 typedef typename
List::tail tail
;
1005 static void apply(lua_State
* L
, int index
)
1007 head::postcall(L
, index
);
1008 policy_postcall
<tail
>::apply(L
, index
);
1013 struct policy_postcall
<detail::null_type
>
1015 static void apply(lua_State
*, int) {}
1018 }} // namespace luabind::detail
1021 namespace luabind
{ namespace
1023 #if defined(__GNUC__) && \
1024 (__GNUC__ * 100 + __GNUC_MINOR__ <= 400 || BOOST_VERSION <= 103401)
1025 static inline boost::arg
<0> return_value()
1027 return boost::arg
<0>();
1030 static inline boost::arg
<0> result()
1032 return boost::arg
<0>();
1034 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
1035 #elif defined(BOOST_MSVC) || defined(__MWERKS__)
1036 static boost::arg
<0> return_value
;
1037 static boost::arg
<0> result
;
1038 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1040 boost::arg
<0> return_value
;
1041 boost::arg
<0> result
;
1042 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1046 #endif // LUABIND_POLICY_HPP_INCLUDED