Cache conversion result from the scoring stage.
[luabind.git] / luabind / detail / policy.hpp
blobb21b6649fc40c88ebf9705c3f8f8ec8b0f9847a6
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>
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 // ********** pointer converter ***********
174 template <class P>
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());
185 catch (...)
187 instance.deallocate(storage);
188 throw;
191 instance.set_instance((holder_type*)storage);
194 struct pointer_converter
196 typedef pointer_converter type;
197 typedef mpl::false_ is_native;
199 pointer_converter()
200 : result(0)
203 void* result;
205 int const consumed_args(...)
207 return 1;
210 template<class T>
211 void apply(lua_State* L, T* ptr)
213 if (ptr == 0)
215 lua_pushnil(L);
216 return;
219 if (luabind::get_back_reference(L, ptr))
220 return;
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;
234 template<class T>
235 T* apply(lua_State* L, by_pointer<T>, int index)
237 return static_cast<T*>(result);
240 template<class T>
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;
247 if (obj->is_const())
248 return -1;
250 std::pair<void*, int> s = obj->get_instance(typeid(T));
251 result = s.first;
252 return s.second;
255 template<class 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;
267 template <class T>
268 void install(T& x, object_rep& instance, mpl::false_)
270 std::auto_ptr<T> ptr(new T(x));
271 install_instance(ptr, instance);
274 template <class T>
275 void install(T& x, object_rep& instance, mpl::true_)
277 install_instance(x, instance);
280 template <class T>
281 class_rep* get_class(T const*, lua_State* L, mpl::false_)
283 return get_class_rep<T>(L);
286 template <class T>
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(...)
294 return 1;
297 template<class T>
298 void apply(lua_State* L, T x)
300 if (luabind::get_back_reference(L, x))
301 return;
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;
315 template<class T>
316 T apply(lua_State* L, by_value<T>, int index)
318 // preconditions:
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);
328 template<class T>
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))
333 return -1;
335 object_rep* obj = get_instance(L, index);
336 if (obj == 0) return -1;
338 return obj->get_instance(typeid(T)).second;
341 template<class T>
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;
351 template<class T>
352 void apply(lua_State* L, const T* ptr)
354 if (ptr == 0)
356 lua_pushnil(L);
357 return;
360 if (luabind::get_back_reference(L, ptr))
361 return;
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);
373 template<class T>
374 T const* apply(lua_State* L, by_const_pointer<T>, int index)
376 return pointer_converter::apply(L, by_pointer<T>(), index);
379 template<class T>
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())
388 score += 10;
390 return score;
393 template<class T>
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(...)
409 return 1;
412 template<class T>
413 void apply(lua_State* L, T& ref)
415 if (luabind::get_back_reference(L, ref))
416 return;
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);
428 template<class T>
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);
435 template<class T>
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);
442 template<class T>
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(...)
455 return 1;
458 const_ref_converter()
459 : result(0)
462 void* result;
464 template<class T>
465 void apply(lua_State* L, T const& ref)
467 if (luabind::get_back_reference(L, ref))
468 return;
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;
483 template<class T>
484 T const& apply(lua_State* L, by_const_reference<T>, int index)
486 return *static_cast<T*>(result);
489 template<class T>
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())
497 s.second += 10;
498 result = s.first;
499 return s.second;
502 template<class T>
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(...)
517 return 1;
520 void apply(lua_State* L, int val)
522 lua_pushnumber(L, val);
525 template<class T>
526 T apply(lua_State* L, by_value<T>, int index)
528 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
531 template<class T>
532 static int match(lua_State* L, by_value<T>, int index)
534 if (lua_isnumber(L, index)) return 0; else return -1;
537 template<class T>
538 T apply(lua_State* L, by_const_reference<T>, int index)
540 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
543 template<class T>
544 static int match(lua_State* L, by_const_reference<T>, int index)
546 if (lua_isnumber(L, index)) return 0; else return -1;
549 template<class T>
550 void converter_postcall(lua_State*, T, int) {}
553 template <class U>
554 struct value_wrapper_converter
556 typedef value_wrapper_converter<U> type;
557 typedef mpl::true_ is_native;
559 int const consumed_args(...)
561 return 1;
564 template<class T>
565 T apply(lua_State* L, by_const_reference<T>, int index)
567 return T(from_stack(L, index));
570 template<class T>
571 T apply(lua_State* L, by_value<T>, int index)
573 return apply(L, by_const_reference<T>(), index);
576 template<class T>
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
581 : -1;
584 template<class T>
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(...) {}
592 template<class T>
593 void apply(lua_State* interpreter, T const& value_wrapper)
595 value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
599 template <class T>
600 struct default_converter_generator
601 : mpl::eval_if<
602 is_value_wrapper_arg<T>
603 , value_wrapper_converter<T>
604 , mpl::eval_if<
605 boost::is_enum<typename boost::remove_reference<T>::type>
606 , enum_converter
607 , mpl::eval_if<
608 is_nonconst_pointer<T>
609 , pointer_converter
610 , mpl::eval_if<
611 is_const_pointer<T>
612 , const_pointer_converter
613 , mpl::eval_if<
614 is_nonconst_reference<T>
615 , ref_converter
616 , mpl::eval_if<
617 is_const_reference<T>
618 , const_ref_converter
619 , value_converter
628 } // namespace detail
630 // *********** default_policy *****************
632 template <class T>
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(...)
644 return 1;
647 template <class U>
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);
686 Derived& derived()
688 return static_cast<Derived&>(*this);
692 # define LUABIND_NUMBER_CONVERTER(type) \
693 template <> \
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; \
700 }; \
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)); \
711 }; \
713 template <> \
714 struct default_converter<type const> \
715 : default_converter<type> \
716 {}; \
718 template <> \
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
738 template <>
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);
758 template <>
759 struct default_converter<bool const>
760 : default_converter<bool>
763 template <>
764 struct default_converter<bool const&>
765 : default_converter<bool>
768 template <>
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());
788 template <>
789 struct default_converter<std::string const>
790 : default_converter<std::string>
793 template <>
794 struct default_converter<std::string const&>
795 : default_converter<std::string>
798 template <>
799 struct default_converter<char const*>
801 typedef boost::mpl::true_ is_native;
803 int const consumed_args(...)
805 return 1;
808 template <class U>
809 static int match(lua_State* L, U, int index)
811 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
814 template <class U>
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);
825 template <class U>
826 void converter_postcall(lua_State*, U, int)
830 template <>
831 struct default_converter<const char* const>
832 : default_converter<char const*>
835 template <>
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*>
850 template <>
851 struct default_converter<lua_State*>
853 int const consumed_args(...)
855 return 0;
858 template <class U>
859 lua_State* apply(lua_State* L, U, int)
861 return L;
864 template <class U>
865 static int match(lua_State*, U, int)
867 return 0;
870 template <class U>
871 void converter_postcall(lua_State*, U, int) {}
874 namespace detail
877 struct default_policy : converter_policy_tag
879 BOOST_STATIC_CONSTANT(bool, has_arg = true);
881 template<class T>
882 static void precall(lua_State*, T, int) {}
884 template<class T, class Direction>
885 struct apply
887 typedef default_converter<T> type;
891 template<class T>
892 struct is_primitive
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>
904 struct apply
906 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
910 template<>
911 struct find_conversion_impl<true>
913 template<int N, class Policies>
914 struct apply
916 typedef typename Policies::head head;
917 typedef typename Policies::tail tail;
919 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
921 typedef typename
922 boost::mpl::if_c<found
923 , head
924 , typename find_conversion_policy<N, tail>::type
925 >::type type;
929 template<class Policies>
930 struct find_conversion_impl2
932 template<int N>
933 struct apply
934 : find_conversion_impl<
935 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
936 >::template apply<N, Policies>
941 template<>
942 struct find_conversion_impl2<detail::null_type>
944 template<int N>
945 struct apply
947 typedef default_policy type;
951 template<int N, class Policies>
952 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
956 template<class List>
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);
969 template<>
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 *********************
980 template<class List>
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);
993 template<>
994 struct policy_precall<detail::null_type>
996 static void apply(lua_State*, int) {}
999 template<class List>
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);
1012 template<>
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>
1039 #else
1040 boost::arg<0> return_value;
1041 boost::arg<0> result;
1042 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1043 #endif
1046 #endif // LUABIND_POLICY_HPP_INCLUDED