Always use lua_tonumber() for unsigned int/long.
[luabind.git] / luabind / detail / policy.hpp
blob11159691b4ea49364817cc86dd7ca944d854110c
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>
30 #include <string>
31 #include <memory>
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/has_get_pointer.hpp>
57 #include <luabind/detail/make_instance.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>
69 namespace luabind
71 namespace detail
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);
83 class index_map
85 public:
86 index_map(const int* m): m_map(m) {}
88 int operator[](int index) const
90 return m_map[index];
93 private:
94 const int* m_map;
97 namespace detail
100 LUABIND_API int implicit_cast(const class_rep* crep, type_id const&, int& pointer_offset);
103 // template<class T> class functor;
104 class weak_ref;
107 namespace luabind { namespace detail
109 template<class H, class T>
110 struct policy_cons
112 typedef H head;
113 typedef T tail;
115 template<class U>
116 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
118 return policy_cons<U, policy_cons<H,T> >();
121 template<class U>
122 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
124 return policy_cons<U, policy_cons<H,T> >();
127 template<class U>
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
136 template<class T>
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(...);
145 template<class T>
146 struct is_policy_cons
148 static const T& t;
150 BOOST_STATIC_CONSTANT(bool, value =
151 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
153 typedef boost::mpl::bool_<value> type;
156 template<bool>
157 struct is_string_literal
159 static no_t helper(indirection_layer);
160 static yes_t helper(const char*);
163 template<>
164 struct is_string_literal<false>
166 static no_t helper(indirection_layer);
170 namespace mpl = boost::mpl;
172 template <class T, class Clone>
173 void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone)
175 if (get_pointer(x))
177 make_instance(L, x);
179 else
181 lua_pushnil(L);
185 template <class T>
186 void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_)
188 std::auto_ptr<T> ptr(new T(x));
189 make_instance(L, ptr);
192 template <class T>
193 void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_)
195 make_instance(L, &x);
198 template <class T, class Clone>
199 void make_pointee_instance(lua_State* L, T& x, Clone)
201 make_pointee_instance(L, x, has_get_pointer<T>(), Clone());
204 // ********** pointer converter ***********
206 struct pointer_converter
208 typedef pointer_converter type;
209 typedef mpl::false_ is_native;
211 pointer_converter()
212 : result(0)
215 void* result;
217 int const consumed_args(...)
219 return 1;
222 template<class T>
223 void apply(lua_State* L, T* ptr)
225 if (ptr == 0)
227 lua_pushnil(L);
228 return;
231 if (luabind::get_back_reference(L, ptr))
232 return;
234 make_instance(L, ptr);
237 template<class T>
238 T* apply(lua_State*, by_pointer<T>, int)
240 return static_cast<T*>(result);
243 template<class T>
244 int match(lua_State* L, by_pointer<T>, int index)
246 if (lua_isnil(L, index)) return 0;
247 object_rep* obj = get_instance(L, index);
248 if (obj == 0) return -1;
250 if (obj->is_const())
251 return -1;
253 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
254 result = s.first;
255 return s.second;
258 template<class T>
259 void converter_postcall(lua_State*, by_pointer<T>, int)
263 // ******* value converter *******
265 struct value_converter
267 typedef value_converter type;
268 typedef mpl::false_ is_native;
270 int const consumed_args(...)
272 return 1;
275 value_converter()
276 : result(0)
279 void* result;
281 template<class T>
282 void apply(lua_State* L, T x)
284 if (luabind::get_back_reference(L, x))
285 return;
287 make_pointee_instance(L, x, mpl::true_());
290 template<class T>
291 T apply(lua_State*, by_value<T>, int)
293 return *static_cast<T*>(result);
296 template<class T>
297 int match(lua_State* L, by_value<T>, int index)
299 // special case if we get nil in, try to match the holder type
300 if (lua_isnil(L, index))
301 return -1;
303 object_rep* obj = get_instance(L, index);
304 if (obj == 0) return -1;
306 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
307 result = s.first;
308 return s.second;
311 template<class T>
312 void converter_postcall(lua_State*, T, int) {}
315 // ******* const pointer converter *******
317 struct const_pointer_converter
319 typedef const_pointer_converter type;
320 typedef mpl::false_ is_native;
322 int const consumed_args(...)
324 return 1;
327 const_pointer_converter()
328 : result(0)
331 void* result;
333 template<class T>
334 void apply(lua_State* L, const T* ptr)
336 if (ptr == 0)
338 lua_pushnil(L);
339 return;
342 if (luabind::get_back_reference(L, ptr))
343 return;
345 make_instance(L, ptr);
348 template<class T>
349 T const* apply(lua_State*, by_const_pointer<T>, int)
351 return static_cast<T const*>(result);
354 template<class T>
355 int match(lua_State* L, by_const_pointer<T>, int index)
357 if (lua_isnil(L, index)) return 0;
358 object_rep* obj = get_instance(L, index);
359 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
360 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
361 if (s.second >= 0 && !obj->is_const())
362 s.second += 10;
363 result = s.first;
364 return s.second;
367 template<class T>
368 void converter_postcall(lua_State*, T, int) {}
371 // ******* reference converter *******
373 struct ref_converter : pointer_converter
375 typedef ref_converter type;
376 typedef mpl::false_ is_native;
378 int const consumed_args(...)
380 return 1;
383 template<class T>
384 void apply(lua_State* L, T& ref)
386 if (luabind::get_back_reference(L, ref))
387 return;
389 make_pointee_instance(L, ref, mpl::false_());
392 template<class T>
393 T& apply(lua_State* L, by_reference<T>, int index)
395 assert(!lua_isnil(L, index));
396 return *pointer_converter::apply(L, by_pointer<T>(), index);
399 template<class T>
400 int match(lua_State* L, by_reference<T>, int index)
402 if (lua_isnil(L, index)) return -1;
403 return pointer_converter::match(L, by_pointer<T>(), index);
406 template<class T>
407 void converter_postcall(lua_State*, T, int) {}
410 // ******** const reference converter *********
412 struct const_ref_converter
414 typedef const_ref_converter type;
415 typedef mpl::false_ is_native;
417 int const consumed_args(...)
419 return 1;
422 const_ref_converter()
423 : result(0)
426 void* result;
428 template<class T>
429 void apply(lua_State* L, T const& ref)
431 if (luabind::get_back_reference(L, ref))
432 return;
434 make_pointee_instance(L, ref, mpl::false_());
437 template<class T>
438 T const& apply(lua_State*, by_const_reference<T>, int)
440 return *static_cast<T*>(result);
443 template<class T>
444 int match(lua_State* L, by_const_reference<T>, int index)
446 object_rep* obj = get_instance(L, index);
447 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
449 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
450 if (s.second >= 0 && !obj->is_const())
451 s.second += 10;
452 result = s.first;
453 return s.second;
456 template<class T>
457 void converter_postcall(lua_State*, by_const_reference<T>, int)
462 // ****** enum converter ********
464 struct enum_converter
466 typedef enum_converter type;
467 typedef mpl::true_ is_native;
469 int const consumed_args(...)
471 return 1;
474 void apply(lua_State* L, int val)
476 lua_pushnumber(L, val);
479 template<class T>
480 T apply(lua_State* L, by_value<T>, int index)
482 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
485 template<class T>
486 static int match(lua_State* L, by_value<T>, int index)
488 if (lua_isnumber(L, index)) return 0; else return -1;
491 template<class T>
492 T apply(lua_State* L, by_const_reference<T>, int index)
494 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
497 template<class T>
498 static int match(lua_State* L, by_const_reference<T>, int index)
500 if (lua_isnumber(L, index)) return 0; else return -1;
503 template<class T>
504 void converter_postcall(lua_State*, T, int) {}
507 template <class U>
508 struct value_wrapper_converter
510 typedef value_wrapper_converter<U> type;
511 typedef mpl::true_ is_native;
513 int const consumed_args(...)
515 return 1;
518 template<class T>
519 T apply(lua_State* L, by_const_reference<T>, int index)
521 return T(from_stack(L, index));
524 template<class T>
525 T apply(lua_State* L, by_value<T>, int index)
527 return apply(L, by_const_reference<T>(), index);
530 template<class T>
531 static int match(lua_State* L, by_const_reference<T>, int index)
533 return value_wrapper_traits<T>::check(L, index)
534 ? (std::numeric_limits<int>::max)() / LUABIND_MAX_ARITY
535 : -1;
538 template<class T>
539 static int match(lua_State* L, by_value<T>, int index)
541 return match(L, by_const_reference<T>(), index);
544 void converter_postcall(...) {}
546 template<class T>
547 void apply(lua_State* interpreter, T const& value_wrapper)
549 value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
553 template <class T>
554 struct default_converter_generator
555 : mpl::eval_if<
556 is_value_wrapper_arg<T>
557 , value_wrapper_converter<T>
558 , mpl::eval_if<
559 boost::is_enum<typename boost::remove_reference<T>::type>
560 , enum_converter
561 , mpl::eval_if<
562 is_nonconst_pointer<T>
563 , pointer_converter
564 , mpl::eval_if<
565 is_const_pointer<T>
566 , const_pointer_converter
567 , mpl::eval_if<
568 is_nonconst_reference<T>
569 , ref_converter
570 , mpl::eval_if<
571 is_const_reference<T>
572 , const_ref_converter
573 , value_converter
582 } // namespace detail
584 // *********** default_policy *****************
586 template <class T>
587 struct default_converter
588 : detail::default_converter_generator<T>::type
591 template <class T, class Derived = default_converter<T> >
592 struct native_converter_base
594 typedef boost::mpl::true_ is_native;
596 int const consumed_args(...)
598 return 1;
601 template <class U>
602 void converter_postcall(lua_State*, U const&, int)
605 int match(lua_State* L, detail::by_value<T>, int index)
607 return derived().compute_score(L, index);
610 int match(lua_State* L, detail::by_value<T const>, int index)
612 return derived().compute_score(L, index);
615 int match(lua_State* L, detail::by_const_reference<T>, int index)
617 return derived().compute_score(L, index);
620 T apply(lua_State* L, detail::by_value<T>, int index)
622 return derived().from(L, index);
625 T apply(lua_State* L, detail::by_value<T const>, int index)
627 return derived().from(L, index);
630 T apply(lua_State* L, detail::by_const_reference<T>, int index)
632 return derived().from(L, index);
635 void apply(lua_State* L, T const& value)
637 derived().to(L, value);
640 Derived& derived()
642 return static_cast<Derived&>(*this);
646 template <class T>
647 lua_Integer as_lua_integer(T v)
649 return static_cast<lua_Integer>(v);
652 template <class T>
653 lua_Number as_lua_number(T v)
655 return static_cast<lua_Number>(v);
658 # define LUABIND_NUMBER_CONVERTER(type, kind) \
659 template <> \
660 struct default_converter<type> \
661 : native_converter_base<type> \
663 int compute_score(lua_State* L, int index) \
665 return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
666 }; \
668 type from(lua_State* L, int index) \
670 return static_cast<type>(BOOST_PP_CAT(lua_to, kind)(L, index)); \
673 void to(lua_State* L, type const& value) \
675 BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \
677 }; \
679 template <> \
680 struct default_converter<type const> \
681 : default_converter<type> \
682 {}; \
684 template <> \
685 struct default_converter<type const&> \
686 : default_converter<type> \
689 LUABIND_NUMBER_CONVERTER(char, integer)
690 LUABIND_NUMBER_CONVERTER(signed char, integer)
691 LUABIND_NUMBER_CONVERTER(unsigned char, integer)
692 LUABIND_NUMBER_CONVERTER(signed short, integer)
693 LUABIND_NUMBER_CONVERTER(unsigned short, integer)
694 LUABIND_NUMBER_CONVERTER(signed int, integer)
696 LUABIND_NUMBER_CONVERTER(unsigned int, number)
697 LUABIND_NUMBER_CONVERTER(unsigned long, number)
699 LUABIND_NUMBER_CONVERTER(signed long, integer)
700 LUABIND_NUMBER_CONVERTER(float, number)
701 LUABIND_NUMBER_CONVERTER(double, number)
702 LUABIND_NUMBER_CONVERTER(long double, number)
704 # undef LUABIND_NUMBER_CONVERTER
706 template <>
707 struct default_converter<bool>
708 : native_converter_base<bool>
710 static int compute_score(lua_State* L, int index)
712 return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1;
715 bool from(lua_State* L, int index)
717 return lua_toboolean(L, index) == 1;
720 void to(lua_State* L, bool value)
722 lua_pushboolean(L, value);
726 template <>
727 struct default_converter<bool const>
728 : default_converter<bool>
731 template <>
732 struct default_converter<bool const&>
733 : default_converter<bool>
736 template <>
737 struct default_converter<std::string>
738 : native_converter_base<std::string>
740 static int compute_score(lua_State* L, int index)
742 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
745 std::string from(lua_State* L, int index)
747 return std::string(lua_tostring(L, index), lua_strlen(L, index));
750 void to(lua_State* L, std::string const& value)
752 lua_pushlstring(L, value.data(), value.size());
756 template <>
757 struct default_converter<std::string const>
758 : default_converter<std::string>
761 template <>
762 struct default_converter<std::string const&>
763 : default_converter<std::string>
766 template <>
767 struct default_converter<char const*>
769 typedef boost::mpl::true_ is_native;
771 int const consumed_args(...)
773 return 1;
776 template <class U>
777 static int match(lua_State* L, U, int index)
779 int type = lua_type(L, index);
780 return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1;
783 template <class U>
784 char const* apply(lua_State* L, U, int index)
786 return lua_tostring(L, index);
789 void apply(lua_State* L, char const* str)
791 lua_pushstring(L, str);
794 template <class U>
795 void converter_postcall(lua_State*, U, int)
799 template <>
800 struct default_converter<const char* const>
801 : default_converter<char const*>
804 template <>
805 struct default_converter<char*>
806 : default_converter<char const*>
809 template <std::size_t N>
810 struct default_converter<char const[N]>
811 : default_converter<char const*>
814 template <std::size_t N>
815 struct default_converter<char[N]>
816 : default_converter<char const*>
819 template <>
820 struct default_converter<lua_State*>
822 int const consumed_args(...)
824 return 0;
827 template <class U>
828 lua_State* apply(lua_State* L, U, int)
830 return L;
833 template <class U>
834 static int match(lua_State*, U, int)
836 return 0;
839 template <class U>
840 void converter_postcall(lua_State*, U, int) {}
843 namespace detail
846 struct default_policy : converter_policy_tag
848 BOOST_STATIC_CONSTANT(bool, has_arg = true);
850 template<class T>
851 static void precall(lua_State*, T, int) {}
853 template<class T, class Direction>
854 struct apply
856 typedef default_converter<T> type;
860 template<class T>
861 struct is_primitive
862 : default_converter<T>::is_native
865 // ============== new policy system =================
867 template<int, class> struct find_conversion_policy;
869 template<bool IsConverter = false>
870 struct find_conversion_impl
872 template<int N, class Policies>
873 struct apply
875 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
879 template<>
880 struct find_conversion_impl<true>
882 template<int N, class Policies>
883 struct apply
885 typedef typename Policies::head head;
886 typedef typename Policies::tail tail;
888 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
890 typedef typename
891 boost::mpl::if_c<found
892 , head
893 , typename find_conversion_policy<N, tail>::type
894 >::type type;
898 template<class Policies>
899 struct find_conversion_impl2
901 template<int N>
902 struct apply
903 : find_conversion_impl<
904 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
905 >::template apply<N, Policies>
910 template<>
911 struct find_conversion_impl2<detail::null_type>
913 template<int N>
914 struct apply
916 typedef default_policy type;
920 template<int N, class Policies>
921 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
925 template<class List>
926 struct policy_list_postcall
928 typedef typename List::head head;
929 typedef typename List::tail tail;
931 static void apply(lua_State* L, const index_map& i)
933 head::postcall(L, i);
934 policy_list_postcall<tail>::apply(L, i);
938 template<>
939 struct policy_list_postcall<detail::null_type>
941 static void apply(lua_State*, const index_map&) {}
944 // ==================================================
946 // ************** precall and postcall on policy_cons *********************
949 template<class List>
950 struct policy_precall
952 typedef typename List::head head;
953 typedef typename List::tail tail;
955 static void apply(lua_State* L, int index)
957 head::precall(L, index);
958 policy_precall<tail>::apply(L, index);
962 template<>
963 struct policy_precall<detail::null_type>
965 static void apply(lua_State*, int) {}
968 template<class List>
969 struct policy_postcall
971 typedef typename List::head head;
972 typedef typename List::tail tail;
974 static void apply(lua_State* L, int index)
976 head::postcall(L, index);
977 policy_postcall<tail>::apply(L, index);
981 template<>
982 struct policy_postcall<detail::null_type>
984 static void apply(lua_State*, int) {}
987 }} // namespace luabind::detail
990 namespace luabind { namespace
992 #if defined(__GNUC__) && \
993 (__GNUC__ * 100 + __GNUC_MINOR__ < 400 || BOOST_VERSION <= 103401)
994 static inline boost::arg<0> return_value()
996 return boost::arg<0>();
999 static inline boost::arg<0> result()
1001 return boost::arg<0>();
1003 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
1004 #elif defined(BOOST_MSVC) || defined(__MWERKS__)
1005 static boost::arg<0> return_value;
1006 static boost::arg<0> result;
1007 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1008 #else
1009 boost::arg<0> return_value;
1010 boost::arg<0> result;
1011 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1012 #endif
1015 #endif // LUABIND_POLICY_HPP_INCLUDED