Test object identity with shared_ptr_converter.
[luabind.git] / luabind / detail / policy.hpp
blobb6d880930f312d08ad3521fef3657ae69fc2af99
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/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>
70 namespace luabind
72 namespace detail
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);
84 class index_map
86 public:
87 index_map(const int* m): m_map(m) {}
89 int operator[](int index) const
91 return m_map[index];
94 private:
95 const int* m_map;
98 namespace detail
101 LUABIND_API int implicit_cast(const class_rep* crep, type_id const&, int& pointer_offset);
104 // template<class T> class functor;
105 class weak_ref;
108 namespace luabind { namespace detail
110 template<class H, class T>
111 struct policy_cons
113 typedef H head;
114 typedef T tail;
116 template<class U>
117 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
119 return policy_cons<U, policy_cons<H,T> >();
122 template<class U>
123 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
125 return policy_cons<U, policy_cons<H,T> >();
128 template<class U>
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
137 template<class T>
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(...);
146 template<class T>
147 struct is_policy_cons
149 static const T& t;
151 BOOST_STATIC_CONSTANT(bool, value =
152 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
154 typedef boost::mpl::bool_<value> type;
157 template<bool>
158 struct is_string_literal
160 static no_t helper(indirection_layer);
161 static yes_t helper(const char*);
164 template<>
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;
180 pointer_converter()
181 : result(0)
184 void* result;
186 int const consumed_args(...)
188 return 1;
191 template<class T>
192 void apply(lua_State* L, T* ptr)
194 if (ptr == 0)
196 lua_pushnil(L);
197 return;
200 if (luabind::get_back_reference(L, ptr))
201 return;
203 make_instance(L, ptr);
206 conversion_storage storage;
208 template<class T>
209 T* apply(lua_State* L, by_pointer<T>, int index)
211 return static_cast<T*>(result);
214 template<class T>
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;
221 if (obj->is_const())
222 return -1;
224 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
225 result = s.first;
226 return s.second;
229 template<class T>
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(...)
243 return 1;
246 template <class T>
247 void make(lua_State* L, T& x, mpl::false_)
249 std::auto_ptr<T> ptr(new T(x));
250 make_instance(L, ptr);
253 template <class T>
254 void make(lua_State* L, T& x, mpl::true_)
256 make_instance(L, x);
259 template<class T>
260 void apply(lua_State* L, T x)
262 if (luabind::get_back_reference(L, x))
263 return;
265 make(L, x, has_get_pointer<T>());
268 conversion_storage storage;
270 template<class T>
271 T apply(lua_State* L, by_value<T>, int index)
273 // preconditions:
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);
284 template<class T>
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))
289 return -1;
291 object_rep* obj = get_instance(L, index);
292 if (obj == 0) return -1;
294 return obj->get_instance(registered_class<T>::id).second;
297 template<class T>
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(...)
310 return 1;
313 const_pointer_converter()
314 : result(0)
317 void* result;
319 template<class T>
320 void apply(lua_State* L, const T* ptr)
322 if (ptr == 0)
324 lua_pushnil(L);
325 return;
328 if (luabind::get_back_reference(L, ptr))
329 return;
331 make_instance(L, ptr);
334 template<class T>
335 T const* apply(lua_State* L, by_const_pointer<T>, int index)
337 return static_cast<T const*>(result);
340 template<class T>
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())
348 s.second += 10;
349 result = s.first;
350 return s.second;
353 template<class T>
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(...)
366 return 1;
369 template<class T>
370 void apply(lua_State* L, T& ref)
372 if (luabind::get_back_reference(L, ref))
373 return;
375 make_instance(L, &ref);
378 template<class T>
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);
385 template<class T>
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);
392 template<class T>
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(...)
405 return 1;
408 const_ref_converter()
409 : result(0)
412 void* result;
414 template<class T>
415 void apply(lua_State* L, T const& ref)
417 if (luabind::get_back_reference(L, ref))
418 return;
420 make_instance(L, &ref);
423 conversion_storage storage;
425 template<class T>
426 T const& apply(lua_State* L, by_const_reference<T>, int index)
428 return *static_cast<T*>(result);
431 template<class T>
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())
439 s.second += 10;
440 result = s.first;
441 return s.second;
444 template<class T>
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(...)
459 return 1;
462 void apply(lua_State* L, int val)
464 lua_pushnumber(L, val);
467 template<class T>
468 T apply(lua_State* L, by_value<T>, int index)
470 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
473 template<class T>
474 static int match(lua_State* L, by_value<T>, int index)
476 if (lua_isnumber(L, index)) return 0; else return -1;
479 template<class T>
480 T apply(lua_State* L, by_const_reference<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_const_reference<T>, int index)
488 if (lua_isnumber(L, index)) return 0; else return -1;
491 template<class T>
492 void converter_postcall(lua_State*, T, int) {}
495 template <class U>
496 struct value_wrapper_converter
498 typedef value_wrapper_converter<U> type;
499 typedef mpl::true_ is_native;
501 int const consumed_args(...)
503 return 1;
506 template<class T>
507 T apply(lua_State* L, by_const_reference<T>, int index)
509 return T(from_stack(L, index));
512 template<class T>
513 T apply(lua_State* L, by_value<T>, int index)
515 return apply(L, by_const_reference<T>(), index);
518 template<class T>
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
523 : -1;
526 template<class T>
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(...) {}
534 template<class T>
535 void apply(lua_State* interpreter, T const& value_wrapper)
537 value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
541 template <class T>
542 struct default_converter_generator
543 : mpl::eval_if<
544 is_value_wrapper_arg<T>
545 , value_wrapper_converter<T>
546 , mpl::eval_if<
547 boost::is_enum<typename boost::remove_reference<T>::type>
548 , enum_converter
549 , mpl::eval_if<
550 is_nonconst_pointer<T>
551 , pointer_converter
552 , mpl::eval_if<
553 is_const_pointer<T>
554 , const_pointer_converter
555 , mpl::eval_if<
556 is_nonconst_reference<T>
557 , ref_converter
558 , mpl::eval_if<
559 is_const_reference<T>
560 , const_ref_converter
561 , value_converter
570 } // namespace detail
572 // *********** default_policy *****************
574 template <class T>
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(...)
586 return 1;
589 template <class U>
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);
628 Derived& derived()
630 return static_cast<Derived&>(*this);
634 # define LUABIND_NUMBER_CONVERTER(type) \
635 template <> \
636 struct default_converter<type> \
637 : native_converter_base<type> \
639 lua_Number result; \
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; \
645 }; \
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)); \
656 }; \
658 template <> \
659 struct default_converter<type const> \
660 : default_converter<type> \
661 {}; \
663 template <> \
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
683 template <>
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);
703 template <>
704 struct default_converter<bool const>
705 : default_converter<bool>
708 template <>
709 struct default_converter<bool const&>
710 : default_converter<bool>
713 template <>
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());
733 template <>
734 struct default_converter<std::string const>
735 : default_converter<std::string>
738 template <>
739 struct default_converter<std::string const&>
740 : default_converter<std::string>
743 template <>
744 struct default_converter<char const*>
746 typedef boost::mpl::true_ is_native;
748 int const consumed_args(...)
750 return 1;
753 template <class U>
754 static int match(lua_State* L, U, int index)
756 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
759 template <class U>
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);
770 template <class U>
771 void converter_postcall(lua_State*, U, int)
775 template <>
776 struct default_converter<const char* const>
777 : default_converter<char const*>
780 template <>
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*>
795 template <>
796 struct default_converter<lua_State*>
798 int const consumed_args(...)
800 return 0;
803 template <class U>
804 lua_State* apply(lua_State* L, U, int)
806 return L;
809 template <class U>
810 static int match(lua_State*, U, int)
812 return 0;
815 template <class U>
816 void converter_postcall(lua_State*, U, int) {}
819 namespace detail
822 struct default_policy : converter_policy_tag
824 BOOST_STATIC_CONSTANT(bool, has_arg = true);
826 template<class T>
827 static void precall(lua_State*, T, int) {}
829 template<class T, class Direction>
830 struct apply
832 typedef default_converter<T> type;
836 template<class T>
837 struct is_primitive
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>
849 struct apply
851 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
855 template<>
856 struct find_conversion_impl<true>
858 template<int N, class Policies>
859 struct apply
861 typedef typename Policies::head head;
862 typedef typename Policies::tail tail;
864 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
866 typedef typename
867 boost::mpl::if_c<found
868 , head
869 , typename find_conversion_policy<N, tail>::type
870 >::type type;
874 template<class Policies>
875 struct find_conversion_impl2
877 template<int N>
878 struct apply
879 : find_conversion_impl<
880 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
881 >::template apply<N, Policies>
886 template<>
887 struct find_conversion_impl2<detail::null_type>
889 template<int N>
890 struct apply
892 typedef default_policy type;
896 template<int N, class Policies>
897 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
901 template<class List>
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);
914 template<>
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 *********************
925 template<class List>
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);
938 template<>
939 struct policy_precall<detail::null_type>
941 static void apply(lua_State*, int) {}
944 template<class List>
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);
957 template<>
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>
984 #else
985 boost::arg<0> return_value;
986 boost::arg<0> result;
987 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
988 #endif
991 #endif // LUABIND_POLICY_HPP_INCLUDED