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>
58 #include <luabind/detail/make_instance.hpp>
60 #include <boost/type_traits/add_reference.hpp>
62 #include <luabind/detail/decorate_type.hpp>
63 #include <luabind/weak_ref.hpp>
64 #include <luabind/back_reference_fwd.hpp>
66 #include <luabind/value_wrapper.hpp>
67 #include <luabind/from_stack.hpp>
68 #include <luabind/typeid.hpp>
74 struct conversion_policy_base
{};
77 template<int N
, bool HasArg
= true>
78 struct conversion_policy
: detail::conversion_policy_base
80 BOOST_STATIC_CONSTANT(int, index
= N
);
81 BOOST_STATIC_CONSTANT(bool, has_arg
= HasArg
);
87 index_map(const int* m
): m_map(m
) {}
89 int operator[](int index
) const
101 LUABIND_API
int implicit_cast(const class_rep
* crep
, type_id
const&, int& pointer_offset
);
104 // template<class T> class functor;
108 namespace luabind
{ namespace detail
110 template<class H
, class T
>
117 policy_cons
<U
, policy_cons
<H
,T
> > operator,(policy_cons
<U
,detail::null_type
>)
119 return policy_cons
<U
, policy_cons
<H
,T
> >();
123 policy_cons
<U
, policy_cons
<H
,T
> > operator+(policy_cons
<U
,detail::null_type
>)
125 return policy_cons
<U
, policy_cons
<H
,T
> >();
129 policy_cons
<U
, policy_cons
<H
,T
> > operator|(policy_cons
<U
,detail::null_type
>)
131 return policy_cons
<U
, policy_cons
<H
,T
> >();
135 struct indirection_layer
138 indirection_layer(const T
&);
141 yes_t
is_policy_cons_test(const null_type
&);
142 template<class H
, class T
>
143 yes_t
is_policy_cons_test(const policy_cons
<H
,T
>&);
144 no_t
is_policy_cons_test(...);
147 struct is_policy_cons
151 BOOST_STATIC_CONSTANT(bool, value
=
152 sizeof(is_policy_cons_test(t
)) == sizeof(yes_t
));
154 typedef boost::mpl::bool_
<value
> type
;
158 struct is_string_literal
160 static no_t
helper(indirection_layer
);
161 static yes_t
helper(const char*);
165 struct is_string_literal
<false>
167 static no_t
helper(indirection_layer
);
171 namespace mpl
= boost::mpl
;
173 // ********** pointer converter ***********
175 struct pointer_converter
177 typedef pointer_converter type
;
178 typedef mpl::false_ is_native
;
186 int const consumed_args(...)
192 void apply(lua_State
* L
, T
* ptr
)
200 if (luabind::get_back_reference(L
, ptr
))
203 make_instance(L
, ptr
);
206 conversion_storage storage
;
209 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
211 return static_cast<T
*>(result
);
215 int match(lua_State
* L
, by_pointer
<T
>, int index
)
217 if (lua_isnil(L
, index
)) return 0;
218 object_rep
* obj
= get_instance(L
, index
);
219 if (obj
== 0) return -1;
224 std::pair
<void*, int> s
= obj
->get_instance(registered_class
<T
>::id
);
230 void converter_postcall(lua_State
*, by_pointer
<T
>, int)
234 // ******* value converter *******
236 struct value_converter
238 typedef value_converter type
;
239 typedef mpl::false_ is_native
;
241 int const consumed_args(...)
247 void make(lua_State
* L
, T
& x
, mpl::false_
)
249 std::auto_ptr
<T
> ptr(new T(x
));
250 make_instance(L
, ptr
);
254 void make(lua_State
* L
, T
& x
, mpl::true_
)
260 void apply(lua_State
* L
, T x
)
262 if (luabind::get_back_reference(L
, x
))
265 make(L
, x
, has_get_pointer
<T
>());
268 conversion_storage storage
;
271 T
apply(lua_State
* L
, by_value
<T
>, int index
)
274 // lua_isuserdata(L, index);
275 // getmetatable().__lua_class is true
277 object_rep
* obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
278 assert((obj
!= 0) && "internal error, please report"); // internal error
280 return *static_cast<T
*>(obj
->get_instance(
281 registered_class
<T
>::id
).first
);
285 static int match(lua_State
* L
, by_value
<T
>, int index
)
287 // special case if we get nil in, try to match the holder type
288 if (lua_isnil(L
, index
))
291 object_rep
* obj
= get_instance(L
, index
);
292 if (obj
== 0) return -1;
294 return obj
->get_instance(registered_class
<T
>::id
).second
;
298 void converter_postcall(lua_State
*, T
, int) {}
301 // ******* const pointer converter *******
303 struct const_pointer_converter
305 typedef const_pointer_converter type
;
306 typedef mpl::false_ is_native
;
308 int const consumed_args(...)
313 const_pointer_converter()
320 void apply(lua_State
* L
, const T
* ptr
)
328 if (luabind::get_back_reference(L
, ptr
))
331 make_instance(L
, ptr
);
335 T
const* apply(lua_State
* L
, by_const_pointer
<T
>, int index
)
337 return static_cast<T
const*>(result
);
341 int match(lua_State
* L
, by_const_pointer
<T
>, int index
)
343 if (lua_isnil(L
, index
)) return 0;
344 object_rep
* obj
= get_instance(L
, index
);
345 if (obj
== 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
346 std::pair
<void*, int> s
= obj
->get_instance(registered_class
<T
>::id
);
347 if (s
.second
>= 0 && !obj
->is_const())
354 void converter_postcall(lua_State
*, T
, int) {}
357 // ******* reference converter *******
359 struct ref_converter
: pointer_converter
361 typedef ref_converter type
;
362 typedef mpl::false_ is_native
;
364 int const consumed_args(...)
370 void apply(lua_State
* L
, T
& ref
)
372 if (luabind::get_back_reference(L
, ref
))
375 make_instance(L
, &ref
);
379 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
381 assert(!lua_isnil(L
, index
));
382 return *pointer_converter::apply(L
, by_pointer
<T
>(), index
);
386 int match(lua_State
* L
, by_reference
<T
>, int index
)
388 if (lua_isnil(L
, index
)) return -1;
389 return pointer_converter::match(L
, by_pointer
<T
>(), index
);
393 void converter_postcall(lua_State
*, T
, int) {}
396 // ******** const reference converter *********
398 struct const_ref_converter
400 typedef const_ref_converter type
;
401 typedef mpl::false_ is_native
;
403 int const consumed_args(...)
408 const_ref_converter()
415 void apply(lua_State
* L
, T
const& ref
)
417 if (luabind::get_back_reference(L
, ref
))
420 make_instance(L
, &ref
);
423 conversion_storage storage
;
426 T
const& apply(lua_State
* L
, by_const_reference
<T
>, int index
)
428 return *static_cast<T
*>(result
);
432 int match(lua_State
* L
, by_const_reference
<T
>, int index
)
434 object_rep
* obj
= get_instance(L
, index
);
435 if (obj
== 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
437 std::pair
<void*, int> s
= obj
->get_instance(registered_class
<T
>::id
);
438 if (s
.second
>= 0 && !obj
->is_const())
445 void converter_postcall(lua_State
* L
, by_const_reference
<T
>, int index
)
450 // ****** enum converter ********
452 struct enum_converter
454 typedef enum_converter type
;
455 typedef mpl::true_ is_native
;
457 int const consumed_args(...)
462 void apply(lua_State
* L
, int val
)
464 lua_pushnumber(L
, val
);
468 T
apply(lua_State
* L
, by_value
<T
>, int index
)
470 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
474 static int match(lua_State
* L
, by_value
<T
>, int index
)
476 if (lua_isnumber(L
, index
)) return 0; else return -1;
480 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
482 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
486 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
488 if (lua_isnumber(L
, index
)) return 0; else return -1;
492 void converter_postcall(lua_State
*, T
, int) {}
496 struct value_wrapper_converter
498 typedef value_wrapper_converter
<U
> type
;
499 typedef mpl::true_ is_native
;
501 int const consumed_args(...)
507 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
509 return T(from_stack(L
, index
));
513 T
apply(lua_State
* L
, by_value
<T
>, int index
)
515 return apply(L
, by_const_reference
<T
>(), index
);
519 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
521 return value_wrapper_traits
<T
>::check(L
, index
)
522 ? (std::numeric_limits
<int>::max
)() / LUABIND_MAX_ARITY
527 static int match(lua_State
* L
, by_value
<T
>, int index
)
529 return match(L
, by_const_reference
<T
>(), index
);
532 void converter_postcall(...) {}
535 void apply(lua_State
* interpreter
, T
const& value_wrapper
)
537 value_wrapper_traits
<T
>::unwrap(interpreter
, value_wrapper
);
542 struct default_converter_generator
544 is_value_wrapper_arg
<T
>
545 , value_wrapper_converter
<T
>
547 boost::is_enum
<typename
boost::remove_reference
<T
>::type
>
550 is_nonconst_pointer
<T
>
554 , const_pointer_converter
556 is_nonconst_reference
<T
>
559 is_const_reference
<T
>
560 , const_ref_converter
570 } // namespace detail
572 // *********** default_policy *****************
575 struct default_converter
576 : detail::default_converter_generator
<T
>::type
579 template <class T
, class Derived
= default_converter
<T
> >
580 struct native_converter_base
582 typedef boost::mpl::true_ is_native
;
584 int const consumed_args(...)
590 void converter_postcall(lua_State
*, U
const&, int)
593 int match(lua_State
* L
, detail::by_value
<T
>, int index
)
595 return derived().compute_score(L
, index
);
598 int match(lua_State
* L
, detail::by_value
<T
const>, int index
)
600 return derived().compute_score(L
, index
);
603 int match(lua_State
* L
, detail::by_const_reference
<T
>, int index
)
605 return derived().compute_score(L
, index
);
608 T
apply(lua_State
* L
, detail::by_value
<T
>, int index
)
610 return derived().from(L
, index
);
613 T
apply(lua_State
* L
, detail::by_value
<T
const>, int index
)
615 return derived().from(L
, index
);
618 T
apply(lua_State
* L
, detail::by_const_reference
<T
>, int index
)
620 return derived().from(L
, index
);
623 void apply(lua_State
* L
, T
const& value
)
625 derived().to(L
, value
);
630 return static_cast<Derived
&>(*this);
634 # define LUABIND_NUMBER_CONVERTER(type) \
636 struct default_converter<type> \
637 : native_converter_base<type> \
641 int compute_score(lua_State* L, int index) \
643 result = lua_tonumber(L, index); \
644 return (result != 0 || lua_isnumber(L, index)) ? 0 : -1; \
647 type from(lua_State* L, int index) \
649 return static_cast<type>(result); \
652 void to(lua_State* L, type const& value) \
654 lua_pushnumber(L, static_cast<lua_Number>(value)); \
659 struct default_converter<type const> \
660 : default_converter<type> \
664 struct default_converter<type const&> \
665 : default_converter<type> \
668 LUABIND_NUMBER_CONVERTER(char)
669 LUABIND_NUMBER_CONVERTER(signed char)
670 LUABIND_NUMBER_CONVERTER(unsigned char)
671 LUABIND_NUMBER_CONVERTER(signed short)
672 LUABIND_NUMBER_CONVERTER(unsigned short)
673 LUABIND_NUMBER_CONVERTER(signed int)
674 LUABIND_NUMBER_CONVERTER(unsigned int)
675 LUABIND_NUMBER_CONVERTER(signed long)
676 LUABIND_NUMBER_CONVERTER(unsigned long)
677 LUABIND_NUMBER_CONVERTER(float)
678 LUABIND_NUMBER_CONVERTER(double)
679 LUABIND_NUMBER_CONVERTER(long double)
681 # undef LUABIND_NUMBER_CONVERTER
684 struct default_converter
<bool>
685 : native_converter_base
<bool>
687 static int compute_score(lua_State
* L
, int index
)
689 return lua_type(L
, index
) == LUA_TBOOLEAN
? 0 : -1;
692 bool from(lua_State
* L
, int index
)
694 return lua_toboolean(L
, index
) == 1;
697 void to(lua_State
* L
, bool value
)
699 lua_pushboolean(L
, value
);
704 struct default_converter
<bool const>
705 : default_converter
<bool>
709 struct default_converter
<bool const&>
710 : default_converter
<bool>
714 struct default_converter
<std::string
>
715 : native_converter_base
<std::string
>
717 static int compute_score(lua_State
* L
, int index
)
719 return lua_type(L
, index
) == LUA_TSTRING
? 0 : -1;
722 std::string
from(lua_State
* L
, int index
)
724 return std::string(lua_tostring(L
, index
), lua_strlen(L
, index
));
727 void to(lua_State
* L
, std::string
const& value
)
729 lua_pushlstring(L
, value
.data(), value
.size());
734 struct default_converter
<std::string
const>
735 : default_converter
<std::string
>
739 struct default_converter
<std::string
const&>
740 : default_converter
<std::string
>
744 struct default_converter
<char const*>
746 typedef boost::mpl::true_ is_native
;
748 int const consumed_args(...)
754 static int match(lua_State
* L
, U
, int index
)
756 return lua_type(L
, index
) == LUA_TSTRING
? 0 : -1;
760 char const* apply(lua_State
* L
, U
, int index
)
762 return lua_tostring(L
, index
);
765 void apply(lua_State
* L
, char const* str
)
767 lua_pushstring(L
, str
);
771 void converter_postcall(lua_State
*, U
, int)
776 struct default_converter
<const char* const>
777 : default_converter
<char const*>
781 struct default_converter
<char*>
782 : default_converter
<char const*>
785 template <std::size_t N
>
786 struct default_converter
<char const[N
]>
787 : default_converter
<char const*>
790 template <std::size_t N
>
791 struct default_converter
<char[N
]>
792 : default_converter
<char const*>
796 struct default_converter
<lua_State
*>
798 int const consumed_args(...)
804 lua_State
* apply(lua_State
* L
, U
, int)
810 static int match(lua_State
*, U
, int)
816 void converter_postcall(lua_State
*, U
, int) {}
822 struct default_policy
: converter_policy_tag
824 BOOST_STATIC_CONSTANT(bool, has_arg
= true);
827 static void precall(lua_State
*, T
, int) {}
829 template<class T
, class Direction
>
832 typedef default_converter
<T
> type
;
838 : default_converter
<T
>::is_native
841 // ============== new policy system =================
843 template<int, class> struct find_conversion_policy
;
845 template<bool IsConverter
= false>
846 struct find_conversion_impl
848 template<int N
, class Policies
>
851 typedef typename find_conversion_policy
<N
, typename
Policies::tail
>::type type
;
856 struct find_conversion_impl
<true>
858 template<int N
, class Policies
>
861 typedef typename
Policies::head head
;
862 typedef typename
Policies::tail tail
;
864 BOOST_STATIC_CONSTANT(bool, found
= (N
== head::index
));
867 boost::mpl::if_c
<found
869 , typename find_conversion_policy
<N
, tail
>::type
874 template<class Policies
>
875 struct find_conversion_impl2
879 : find_conversion_impl
<
880 boost::is_base_and_derived
<conversion_policy_base
, typename
Policies::head
>::value
881 >::template apply
<N
, Policies
>
887 struct find_conversion_impl2
<detail::null_type
>
892 typedef default_policy type
;
896 template<int N
, class Policies
>
897 struct find_conversion_policy
: find_conversion_impl2
<Policies
>::template apply
<N
>
902 struct policy_list_postcall
904 typedef typename
List::head head
;
905 typedef typename
List::tail tail
;
907 static void apply(lua_State
* L
, const index_map
& i
)
909 head::postcall(L
, i
);
910 policy_list_postcall
<tail
>::apply(L
, i
);
915 struct policy_list_postcall
<detail::null_type
>
917 static void apply(lua_State
*, const index_map
&) {}
920 // ==================================================
922 // ************** precall and postcall on policy_cons *********************
926 struct policy_precall
928 typedef typename
List::head head
;
929 typedef typename
List::tail tail
;
931 static void apply(lua_State
* L
, int index
)
933 head::precall(L
, index
);
934 policy_precall
<tail
>::apply(L
, index
);
939 struct policy_precall
<detail::null_type
>
941 static void apply(lua_State
*, int) {}
945 struct policy_postcall
947 typedef typename
List::head head
;
948 typedef typename
List::tail tail
;
950 static void apply(lua_State
* L
, int index
)
952 head::postcall(L
, index
);
953 policy_postcall
<tail
>::apply(L
, index
);
958 struct policy_postcall
<detail::null_type
>
960 static void apply(lua_State
*, int) {}
963 }} // namespace luabind::detail
966 namespace luabind
{ namespace
968 #if defined(__GNUC__) && \
969 (__GNUC__ * 100 + __GNUC_MINOR__ <= 400 || BOOST_VERSION <= 103401)
970 static inline boost::arg
<0> return_value()
972 return boost::arg
<0>();
975 static inline boost::arg
<0> result()
977 return boost::arg
<0>();
979 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
980 #elif defined(BOOST_MSVC) || defined(__MWERKS__)
981 static boost::arg
<0> return_value
;
982 static boost::arg
<0> result
;
983 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
985 boost::arg
<0> return_value
;
986 boost::arg
<0> result
;
987 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
991 #endif // LUABIND_POLICY_HPP_INCLUDED