Initial C++0x support.
[luabind.git] / luabind / detail / policy.hpp
blob77de6404a09fffd94041c8a968b9ca0aa8251127
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/bind/placeholders.hpp>
46 #include <boost/limits.hpp>
47 #include <boost/tuple/tuple.hpp>
48 #include <boost/version.hpp>
50 #include <luabind/detail/class_registry.hpp>
51 #include <luabind/detail/primitives.hpp>
52 #include <luabind/detail/object_rep.hpp>
53 #include <luabind/detail/typetraits.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 // template<class T> class functor;
98 class weak_ref;
101 namespace luabind { namespace detail
103 template<class H, class T>
104 struct policy_cons
106 typedef H head;
107 typedef T tail;
109 template<class U>
110 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
112 return policy_cons<U, policy_cons<H,T> >();
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> >();
128 struct indirection_layer
130 template<class T>
131 indirection_layer(const T&);
134 yes_t is_policy_cons_test(const null_type&);
135 template<class H, class T>
136 yes_t is_policy_cons_test(const policy_cons<H,T>&);
137 no_t is_policy_cons_test(...);
139 template<class T>
140 struct is_policy_cons
142 static const T& t;
144 BOOST_STATIC_CONSTANT(bool, value =
145 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
147 typedef boost::mpl::bool_<value> type;
150 template<bool>
151 struct is_string_literal
153 static no_t helper(indirection_layer);
154 static yes_t helper(const char*);
157 template<>
158 struct is_string_literal<false>
160 static no_t helper(indirection_layer);
164 namespace mpl = boost::mpl;
166 template <class T, class Clone>
167 void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone)
169 if (get_pointer(x))
171 make_instance(L, x);
173 else
175 lua_pushnil(L);
179 template <class T>
180 void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_)
182 std::auto_ptr<T> ptr(new T(x));
183 make_instance(L, ptr);
186 template <class T>
187 void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_)
189 make_instance(L, &x);
192 template <class T, class Clone>
193 void make_pointee_instance(lua_State* L, T& x, Clone)
195 make_pointee_instance(L, x, has_get_pointer<T>(), Clone());
198 // ********** pointer converter ***********
200 struct pointer_converter
202 typedef pointer_converter type;
203 typedef mpl::false_ is_native;
205 pointer_converter()
206 : result(0)
209 void* result;
211 int const consumed_args(...)
213 return 1;
216 template<class T>
217 void apply(lua_State* L, T* ptr)
219 if (ptr == 0)
221 lua_pushnil(L);
222 return;
225 if (luabind::get_back_reference(L, ptr))
226 return;
228 make_instance(L, ptr);
231 template<class T>
232 T* apply(lua_State*, by_pointer<T>, int)
234 return static_cast<T*>(result);
237 template<class T>
238 int match(lua_State* L, by_pointer<T>, int index)
240 if (lua_isnil(L, index)) return 0;
241 object_rep* obj = get_instance(L, index);
242 if (obj == 0) return -1;
244 if (obj->is_const())
245 return -1;
247 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
248 result = s.first;
249 return s.second;
252 template<class T>
253 void converter_postcall(lua_State*, by_pointer<T>, int)
257 // ******* value converter *******
259 struct value_converter
261 typedef value_converter type;
262 typedef mpl::false_ is_native;
264 int const consumed_args(...)
266 return 1;
269 value_converter()
270 : result(0)
273 void* result;
275 template<class T>
276 void apply(lua_State* L, T x)
278 if (luabind::get_back_reference(L, x))
279 return;
281 make_pointee_instance(L, x, mpl::true_());
284 template<class T>
285 T apply(lua_State*, by_value<T>, int)
287 return *static_cast<T*>(result);
290 template<class T>
291 int match(lua_State* L, by_value<T>, int index)
293 // special case if we get nil in, try to match the holder type
294 if (lua_isnil(L, index))
295 return -1;
297 object_rep* obj = get_instance(L, index);
298 if (obj == 0) return -1;
300 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
301 result = s.first;
302 return s.second;
305 template<class T>
306 void converter_postcall(lua_State*, T, int) {}
309 // ******* const pointer converter *******
311 struct const_pointer_converter
313 typedef const_pointer_converter type;
314 typedef mpl::false_ is_native;
316 int const consumed_args(...)
318 return 1;
321 const_pointer_converter()
322 : result(0)
325 void* result;
327 template<class T>
328 void apply(lua_State* L, const T* ptr)
330 if (ptr == 0)
332 lua_pushnil(L);
333 return;
336 if (luabind::get_back_reference(L, ptr))
337 return;
339 make_instance(L, ptr);
342 template<class T>
343 T const* apply(lua_State*, by_const_pointer<T>, int)
345 return static_cast<T const*>(result);
348 template<class T>
349 int match(lua_State* L, by_const_pointer<T>, int index)
351 if (lua_isnil(L, index)) return 0;
352 object_rep* obj = get_instance(L, index);
353 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
354 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
355 if (s.second >= 0 && !obj->is_const())
356 s.second += 10;
357 result = s.first;
358 return s.second;
361 template<class T>
362 void converter_postcall(lua_State*, T, int) {}
365 // ******* reference converter *******
367 struct ref_converter : pointer_converter
369 typedef ref_converter type;
370 typedef mpl::false_ is_native;
372 int const consumed_args(...)
374 return 1;
377 template<class T>
378 void apply(lua_State* L, T& ref)
380 if (luabind::get_back_reference(L, ref))
381 return;
383 make_pointee_instance(L, ref, mpl::false_());
386 template<class T>
387 T& apply(lua_State* L, by_reference<T>, int index)
389 assert(!lua_isnil(L, index));
390 return *pointer_converter::apply(L, by_pointer<T>(), index);
393 template<class T>
394 int match(lua_State* L, by_reference<T>, int index)
396 object_rep* obj = get_instance(L, index);
397 if (obj == 0) return -1;
399 if (obj->is_const())
400 return -1;
402 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
403 result = s.first;
404 return s.second;
407 template<class T>
408 void converter_postcall(lua_State*, T, int) {}
411 // ******** const reference converter *********
413 struct const_ref_converter
415 typedef const_ref_converter type;
416 typedef mpl::false_ is_native;
418 int const consumed_args(...)
420 return 1;
423 const_ref_converter()
424 : result(0)
427 void* result;
429 template<class T>
430 void apply(lua_State* L, T const& ref)
432 if (luabind::get_back_reference(L, ref))
433 return;
435 make_pointee_instance(L, ref, mpl::false_());
438 template<class T>
439 T const& apply(lua_State*, by_const_reference<T>, int)
441 return *static_cast<T*>(result);
444 template<class T>
445 int match(lua_State* L, by_const_reference<T>, int index)
447 object_rep* obj = get_instance(L, index);
448 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
450 std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
451 if (s.second >= 0 && !obj->is_const())
452 s.second += 10;
453 result = s.first;
454 return s.second;
457 template<class T>
458 void converter_postcall(lua_State*, by_const_reference<T>, int)
463 // ****** enum converter ********
465 struct enum_converter
467 typedef enum_converter type;
468 typedef mpl::true_ is_native;
470 int const consumed_args(...)
472 return 1;
475 void apply(lua_State* L, int val)
477 lua_pushnumber(L, val);
480 template<class T>
481 T apply(lua_State* L, by_value<T>, int index)
483 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
486 template<class T>
487 static int match(lua_State* L, by_value<T>, int index)
489 if (lua_isnumber(L, index)) return 0; else return -1;
492 template<class T>
493 T apply(lua_State* L, by_const_reference<T>, int index)
495 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
498 template<class T>
499 static int match(lua_State* L, by_const_reference<T>, int index)
501 if (lua_isnumber(L, index)) return 0; else return -1;
504 template<class T>
505 void converter_postcall(lua_State*, T, int) {}
508 template <class U>
509 struct value_wrapper_converter
511 typedef value_wrapper_converter<U> type;
512 typedef mpl::true_ is_native;
514 int const consumed_args(...)
516 return 1;
519 template<class T>
520 T apply(lua_State* L, by_const_reference<T>, int index)
522 return T(from_stack(L, index));
525 template<class T>
526 T apply(lua_State* L, by_value<T>, int index)
528 return apply(L, by_const_reference<T>(), index);
531 template<class T>
532 static int match(lua_State* L, by_const_reference<T>, int index)
534 return value_wrapper_traits<T>::check(L, index)
535 ? (std::numeric_limits<int>::max)() / LUABIND_MAX_ARITY
536 : -1;
539 template<class T>
540 static int match(lua_State* L, by_value<T>, int index)
542 return match(L, by_const_reference<T>(), index);
545 void converter_postcall(...) {}
547 template<class T>
548 void apply(lua_State* interpreter, T const& value_wrapper)
550 value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
554 template <class T>
555 struct default_converter_generator
556 : mpl::eval_if<
557 is_value_wrapper_arg<T>
558 , value_wrapper_converter<T>
559 , mpl::eval_if<
560 boost::is_enum<typename boost::remove_reference<T>::type>
561 , enum_converter
562 , mpl::eval_if<
563 is_nonconst_pointer<T>
564 , pointer_converter
565 , mpl::eval_if<
566 is_const_pointer<T>
567 , const_pointer_converter
568 , mpl::eval_if<
569 is_nonconst_reference<T>
570 , ref_converter
571 , mpl::eval_if<
572 is_const_reference<T>
573 , const_ref_converter
574 , value_converter
583 } // namespace detail
585 // *********** default_policy *****************
587 template <class T>
588 struct default_converter
589 : detail::default_converter_generator<T>::type
592 template <class T, class Derived = default_converter<T> >
593 struct native_converter_base
595 typedef boost::mpl::true_ is_native;
597 int const consumed_args(...)
599 return 1;
602 template <class U>
603 void converter_postcall(lua_State*, U const&, int)
606 int match(lua_State* L, detail::by_value<T>, int index)
608 return derived().compute_score(L, index);
611 int match(lua_State* L, detail::by_value<T const>, int index)
613 return derived().compute_score(L, index);
616 int match(lua_State* L, detail::by_const_reference<T>, int index)
618 return derived().compute_score(L, index);
621 T apply(lua_State* L, detail::by_value<T>, int index)
623 return derived().from(L, index);
626 T apply(lua_State* L, detail::by_value<T const>, int index)
628 return derived().from(L, index);
631 T apply(lua_State* L, detail::by_const_reference<T>, int index)
633 return derived().from(L, index);
636 void apply(lua_State* L, T const& value)
638 derived().to(L, value);
641 Derived& derived()
643 return static_cast<Derived&>(*this);
647 template <class T>
648 lua_Integer as_lua_integer(T v)
650 return static_cast<lua_Integer>(v);
653 template <class T>
654 lua_Number as_lua_number(T v)
656 return static_cast<lua_Number>(v);
659 # define LUABIND_NUMBER_CONVERTER(type, kind) \
660 template <> \
661 struct default_converter<type> \
662 : native_converter_base<type> \
664 int compute_score(lua_State* L, int index) \
666 return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
667 }; \
669 type from(lua_State* L, int index) \
671 return static_cast<type>(BOOST_PP_CAT(lua_to, kind)(L, index)); \
674 void to(lua_State* L, type const& value) \
676 BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \
678 }; \
680 template <> \
681 struct default_converter<type const> \
682 : default_converter<type> \
683 {}; \
685 template <> \
686 struct default_converter<type const&> \
687 : default_converter<type> \
690 LUABIND_NUMBER_CONVERTER(char, integer)
691 LUABIND_NUMBER_CONVERTER(signed char, integer)
692 LUABIND_NUMBER_CONVERTER(unsigned char, integer)
693 LUABIND_NUMBER_CONVERTER(signed short, integer)
694 LUABIND_NUMBER_CONVERTER(unsigned short, integer)
695 LUABIND_NUMBER_CONVERTER(signed int, integer)
697 LUABIND_NUMBER_CONVERTER(unsigned int, number)
698 LUABIND_NUMBER_CONVERTER(unsigned long, number)
700 LUABIND_NUMBER_CONVERTER(signed long, integer)
701 LUABIND_NUMBER_CONVERTER(float, number)
702 LUABIND_NUMBER_CONVERTER(double, number)
703 LUABIND_NUMBER_CONVERTER(long double, number)
705 # undef LUABIND_NUMBER_CONVERTER
707 template <>
708 struct default_converter<bool>
709 : native_converter_base<bool>
711 static int compute_score(lua_State* L, int index)
713 return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1;
716 bool from(lua_State* L, int index)
718 return lua_toboolean(L, index) == 1;
721 void to(lua_State* L, bool value)
723 lua_pushboolean(L, value);
727 template <>
728 struct default_converter<bool const>
729 : default_converter<bool>
732 template <>
733 struct default_converter<bool const&>
734 : default_converter<bool>
737 template <>
738 struct default_converter<std::string>
739 : native_converter_base<std::string>
741 static int compute_score(lua_State* L, int index)
743 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
746 std::string from(lua_State* L, int index)
748 return std::string(lua_tostring(L, index), lua_strlen(L, index));
751 void to(lua_State* L, std::string const& value)
753 lua_pushlstring(L, value.data(), value.size());
757 template <>
758 struct default_converter<std::string const>
759 : default_converter<std::string>
762 template <>
763 struct default_converter<std::string const&>
764 : default_converter<std::string>
767 template <>
768 struct default_converter<char const*>
770 typedef boost::mpl::true_ is_native;
772 int const consumed_args(...)
774 return 1;
777 template <class U>
778 static int match(lua_State* L, U, int index)
780 int type = lua_type(L, index);
781 return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1;
784 template <class U>
785 char const* apply(lua_State* L, U, int index)
787 return lua_tostring(L, index);
790 void apply(lua_State* L, char const* str)
792 lua_pushstring(L, str);
795 template <class U>
796 void converter_postcall(lua_State*, U, int)
800 template <>
801 struct default_converter<const char* const>
802 : default_converter<char const*>
805 template <>
806 struct default_converter<char*>
807 : default_converter<char const*>
810 template <std::size_t N>
811 struct default_converter<char const[N]>
812 : default_converter<char const*>
815 template <std::size_t N>
816 struct default_converter<char[N]>
817 : default_converter<char const*>
820 template <>
821 struct default_converter<lua_State*>
823 int const consumed_args(...)
825 return 0;
828 template <class U>
829 lua_State* apply(lua_State* L, U, int)
831 return L;
834 template <class U>
835 static int match(lua_State*, U, int)
837 return 0;
840 template <class U>
841 void converter_postcall(lua_State*, U, int) {}
844 namespace detail
847 struct default_policy : converter_policy_tag
849 BOOST_STATIC_CONSTANT(bool, has_arg = true);
851 template<class T>
852 static void precall(lua_State*, T, int) {}
854 template<class T, class Direction>
855 struct apply
857 typedef default_converter<T> type;
861 template<class T>
862 struct is_primitive
863 : default_converter<T>::is_native
866 // ============== new policy system =================
868 template<int, class> struct find_conversion_policy;
870 template<bool IsConverter = false>
871 struct find_conversion_impl
873 template<int N, class Policies>
874 struct apply
876 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
880 template<>
881 struct find_conversion_impl<true>
883 template<int N, class Policies>
884 struct apply
886 typedef typename Policies::head head;
887 typedef typename Policies::tail tail;
889 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
891 typedef typename
892 boost::mpl::if_c<found
893 , head
894 , typename find_conversion_policy<N, tail>::type
895 >::type type;
899 template<class Policies>
900 struct find_conversion_impl2
902 template<int N>
903 struct apply
904 : find_conversion_impl<
905 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
906 >::template apply<N, Policies>
911 template<>
912 struct find_conversion_impl2<detail::null_type>
914 template<int N>
915 struct apply
917 typedef default_policy type;
921 template<int N, class Policies>
922 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
926 template<class List>
927 struct policy_list_postcall
929 typedef typename List::head head;
930 typedef typename List::tail tail;
932 static void apply(lua_State* L, const index_map& i)
934 head::postcall(L, i);
935 policy_list_postcall<tail>::apply(L, i);
939 template<>
940 struct policy_list_postcall<detail::null_type>
942 static void apply(lua_State*, const index_map&) {}
945 // ==================================================
947 // ************** precall and postcall on policy_cons *********************
950 template<class List>
951 struct policy_precall
953 typedef typename List::head head;
954 typedef typename List::tail tail;
956 static void apply(lua_State* L, int index)
958 head::precall(L, index);
959 policy_precall<tail>::apply(L, index);
963 template<>
964 struct policy_precall<detail::null_type>
966 static void apply(lua_State*, int) {}
969 template<class List>
970 struct policy_postcall
972 typedef typename List::head head;
973 typedef typename List::tail tail;
975 static void apply(lua_State* L, int index)
977 head::postcall(L, index);
978 policy_postcall<tail>::apply(L, index);
982 template<>
983 struct policy_postcall<detail::null_type>
985 static void apply(lua_State*, int) {}
988 template <class Policies, class Sought>
989 struct has_policy
990 : mpl::if_<
991 boost::is_same<typename Policies::head, Sought>
992 , mpl::true_
993 , has_policy<typename Policies::tail, Sought>
994 >::type
997 template <class Sought>
998 struct has_policy<null_type, Sought>
999 : mpl::false_
1002 }} // namespace luabind::detail
1005 namespace luabind { namespace
1007 #if defined(__GNUC__) && ( \
1008 (BOOST_VERSION < 103500) \
1009 || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \
1010 || (__GNUC__ * 100 + __GNUC_MINOR__ < 400))
1011 static inline boost::arg<0> return_value()
1013 return boost::arg<0>();
1016 static inline boost::arg<0> result()
1018 return boost::arg<0>();
1020 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
1021 #elif defined(BOOST_MSVC) || defined(__MWERKS__) \
1022 || (BOOST_VERSION >= 103900 && defined(__GNUC__) \
1023 && (__GNUC__ * 100 + __GNUC_MINOR__ == 400))
1024 static boost::arg<0> return_value;
1025 static boost::arg<0> result;
1026 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1027 #else
1028 boost::arg<0> return_value;
1029 boost::arg<0> result;
1030 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1031 #endif
1034 #endif // LUABIND_POLICY_HPP_INCLUDED