Add missing converter for unsigned char.
[luabind.git] / luabind / detail / policy.hpp
blobd011db8f1ee62063cb09edf7948121a3d0daf4d8
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>
32 #include <boost/type_traits/is_enum.hpp>
33 #include <boost/type_traits/is_array.hpp>
34 #include <boost/mpl/bool.hpp>
35 #include <boost/mpl/integral_c.hpp>
36 #include <boost/mpl/equal_to.hpp>
37 #include <boost/mpl/eval_if.hpp>
38 #include <boost/mpl/or.hpp>
39 #include <boost/type_traits/add_reference.hpp>
40 #include <boost/type_traits/remove_reference.hpp>
41 #include <boost/type_traits/is_pointer.hpp>
42 #include <boost/type_traits/is_base_and_derived.hpp>
43 #include <boost/bind/arg.hpp>
44 #include <boost/limits.hpp>
45 #include <boost/tuple/tuple.hpp>
46 #include <boost/version.hpp>
48 #include <luabind/detail/class_registry.hpp>
49 #include <luabind/detail/primitives.hpp>
50 #include <luabind/detail/object_rep.hpp>
51 #include <luabind/detail/typetraits.hpp>
52 #include <luabind/detail/class_cache.hpp>
53 #include <luabind/detail/debug.hpp>
54 #include <luabind/detail/class_rep.hpp>
55 #include <luabind/detail/conversion_storage.hpp>
57 #include <boost/type_traits/add_reference.hpp>
59 #include <luabind/detail/decorate_type.hpp>
60 #include <luabind/weak_ref.hpp>
61 #include <luabind/back_reference_fwd.hpp>
63 #include <luabind/value_wrapper.hpp>
64 #include <luabind/from_stack.hpp>
66 namespace luabind
68 namespace detail
70 struct conversion_policy_base {};
73 template<int N, bool HasArg = true>
74 struct conversion_policy : detail::conversion_policy_base
76 BOOST_STATIC_CONSTANT(int, index = N);
77 BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
80 class index_map
82 public:
83 index_map(const int* m): m_map(m) {}
85 int operator[](int index) const
87 return m_map[index];
90 private:
91 const int* m_map;
94 namespace detail
97 LUABIND_API int implicit_cast(const class_rep* crep, LUABIND_TYPE_INFO const&, int& pointer_offset);
100 // template<class T> class functor;
101 class weak_ref;
104 namespace luabind { namespace detail
106 template<class H, class T>
107 struct policy_cons
109 typedef H head;
110 typedef T tail;
112 template<class U>
113 policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
115 return policy_cons<U, policy_cons<H,T> >();
118 template<class U>
119 policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
121 return policy_cons<U, policy_cons<H,T> >();
124 template<class U>
125 policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
127 return policy_cons<U, policy_cons<H,T> >();
131 struct indirection_layer
133 template<class T>
134 indirection_layer(const T&);
137 yes_t is_policy_cons_test(const null_type&);
138 template<class H, class T>
139 yes_t is_policy_cons_test(const policy_cons<H,T>&);
140 no_t is_policy_cons_test(...);
142 template<class T>
143 struct is_policy_cons
145 static const T& t;
147 BOOST_STATIC_CONSTANT(bool, value =
148 sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
150 typedef boost::mpl::bool_<value> type;
153 template<bool>
154 struct is_string_literal
156 static no_t helper(indirection_layer);
157 static yes_t helper(const char*);
160 template<>
161 struct is_string_literal<false>
163 static no_t helper(indirection_layer);
167 namespace mpl = boost::mpl;
169 // ********** pointer converter ***********
171 struct pointer_converter
173 typedef pointer_converter type;
174 typedef mpl::false_ is_native;
176 template<class T>
177 void apply(lua_State* L, T* ptr)
179 if (ptr == 0)
181 lua_pushnil(L);
182 return;
185 if (luabind::get_back_reference(L, ptr))
186 return;
188 class_rep* crep = get_class_rep<T>(L);
190 // if you get caught in this assert you are
191 // trying to use an unregistered type
192 assert(crep && "you are trying to use an unregistered type");
194 // create the struct to hold the object
195 void* obj = lua_newuserdata(L, sizeof(object_rep));
196 //new(obj) object_rep(ptr, crep, object_rep::owner, destructor_s<T>::apply);
197 new(obj) object_rep(ptr, crep, 0, 0);
199 // set the meta table
200 detail::getref(L, crep->metatable_ref());
201 lua_setmetatable(L, -2);
204 conversion_storage storage;
206 template<class T>
207 T* apply(lua_State* L, by_pointer<T>, int index)
209 // preconditions:
210 // lua_isuserdata(L, index);
211 // getmetatable().__lua_class is true
212 // object_rep->flags() & object_rep::constant == 0
214 if (lua_isnil(L, index)) return 0;
216 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, index));
217 assert((obj != 0) && "internal error, please report"); // internal error
218 const class_rep* crep = obj->crep();
220 return static_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, storage));
223 template<class T>
224 static int match(lua_State* L, by_pointer<T>, int index)
226 if (lua_isnil(L, index)) return 0;
227 object_rep* obj = is_class_object(L, index);
228 if (obj == 0) return -1;
229 // cannot cast a constant object to nonconst
230 if (obj->flags() & object_rep::constant) return -1;
232 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
233 return (obj->flags() & object_rep::constant)?-1:0;
234 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
235 return (obj->flags() & object_rep::constant)?0:1;
237 int d;
238 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
241 template<class T>
242 void converter_postcall(lua_State*, by_pointer<T>, int)
246 // ******* value converter *******
248 struct value_converter
250 typedef value_converter type;
251 typedef mpl::false_ is_native;
253 template<class T>
254 void apply(lua_State* L, const T& ref)
256 if (luabind::get_back_reference(L, ref))
257 return;
259 class_rep* crep = get_class_rep<T>(L);
261 // if you get caught in this assert you are
262 // trying to use an unregistered type
263 assert(crep && "you are trying to use an unregistered type");
265 void* obj_rep;
266 void* held;
268 boost::tie(obj_rep,held) = crep->allocate(L);
270 void* object_ptr;
271 void(*destructor)(void*);
272 destructor = crep->destructor();
273 int flags = object_rep::owner;
274 if (crep->has_holder())
276 if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->const_holder_type()))
278 new(held) T(ref);
279 object_ptr = held;
280 flags |= object_rep::constant;
281 destructor = crep->const_holder_destructor();
283 else if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->holder_type()))
285 new(held) T(ref);
286 object_ptr = held;
288 else
290 assert(LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T), crep->type()));
291 std::auto_ptr<T> obj(new T(ref));
292 crep->construct_holder()(held, obj.get());
293 object_ptr = held;
294 obj.release();
297 else
299 object_ptr = new T(ref);
301 new(obj_rep) object_rep(object_ptr, crep, flags, destructor);
303 // set the meta table
304 detail::getref(L, crep->metatable_ref());
305 lua_setmetatable(L, -2);
308 conversion_storage storage;
310 template<class T>
311 T apply(lua_State* L, by_value<T>, int index)
313 // preconditions:
314 // lua_isuserdata(L, index);
315 // getmetatable().__lua_class is true
316 // object_rep->flags() & object_rep::constant == 0
318 object_rep* obj = 0;
319 const class_rep* crep = 0;
321 // special case if we get nil in, try to convert the holder type
322 if (lua_isnil(L, index))
324 crep = get_class_rep<T>(L);
325 assert(crep);
327 else
329 obj = static_cast<object_rep*>(lua_touserdata(L, index));
330 assert((obj != 0) && "internal error, please report"); // internal error
331 crep = obj->crep();
333 assert(crep);
335 return *static_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, storage));
338 template<class T>
339 static int match(lua_State* L, by_value<T>, int index)
341 // special case if we get nil in, try to match the holder type
342 if (lua_isnil(L, index))
344 class_rep* crep = get_class_rep<T>(L);
345 if (crep == 0) return -1;
346 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
347 return 0;
348 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
349 return 0;
350 return -1;
353 object_rep* obj = is_class_object(L, index);
354 if (obj == 0) return -1;
355 int d;
357 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
358 return (obj->flags() & object_rep::constant)?-1:0;
359 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
360 return (obj->flags() & object_rep::constant)?0:1;
362 return implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
365 template<class T>
366 void converter_postcall(lua_State*, T, int) {}
369 // ******* const pointer converter *******
371 struct const_pointer_converter : pointer_converter
373 typedef const_pointer_converter type;
375 template<class T>
376 void apply(lua_State* L, const T* ptr)
378 if (ptr == 0)
380 lua_pushnil(L);
381 return;
384 if (luabind::get_back_reference(L, ptr))
385 return;
387 class_rep* crep = get_class_rep<T>(L);
389 // if you get caught in this assert you are
390 // trying to use an unregistered type
391 assert(crep && "you are trying to use an unregistered type");
393 // create the struct to hold the object
394 void* obj = lua_newuserdata(L, sizeof(object_rep));
395 assert(obj && "internal error, please report");
396 // we send 0 as destructor since we know it will never be called
397 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
399 // set the meta table
400 detail::getref(L, crep->metatable_ref());
401 lua_setmetatable(L, -2);
404 template<class T>
405 T const* apply(lua_State* L, by_const_pointer<T>, int index)
407 return pointer_converter::apply(L, by_pointer<T>(), index);
410 template<class T>
411 static int match(lua_State* L, by_const_pointer<T>, int index)
413 if (lua_isnil(L, index)) return 0;
414 object_rep* obj = is_class_object(L, index);
415 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
417 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
418 return (obj->flags() & object_rep::constant)?-1:0;
419 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
420 return (obj->flags() & object_rep::constant)?0:1;
422 bool const_ = obj->flags() & object_rep::constant;
423 int d;
424 int points = implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
425 return points == -1 ? -1 : points + !const_;
428 template<class T>
429 void converter_postcall(lua_State* L, by_const_pointer<T>, int index)
431 pointer_converter::converter_postcall(L, by_pointer<T>(), index);
435 // ******* reference converter *******
437 struct ref_converter
439 typedef ref_converter type;
440 typedef mpl::false_ is_native;
442 template<class T>
443 void apply(lua_State* L, T& ref)
445 if (luabind::get_back_reference(L, ref))
446 return;
448 class_rep* crep = get_class_rep<T>(L);
450 // if you get caught in this assert you are
451 // trying to use an unregistered type
452 assert(crep && "you are trying to use an unregistered type");
454 T* ptr = &ref;
456 // create the struct to hold the object
457 void* obj = lua_newuserdata(L, sizeof(object_rep));
458 assert(obj && "internal error, please report");
459 new(obj) object_rep(ptr, crep, 0, 0);
461 // set the meta table
462 detail::getref(L, crep->metatable_ref());
463 lua_setmetatable(L, -2);
466 template<class T>
467 T& apply(lua_State* L, by_reference<T>, int index)
469 assert(!lua_isnil(L, index));
470 return *pointer_converter().apply(L, by_pointer<T>(), index);
473 template<class T>
474 static int match(lua_State* L, by_reference<T>, int index)
476 if (lua_isnil(L, index)) return -1;
477 return pointer_converter::match(L, by_pointer<T>(), index);
480 template<class T>
481 void converter_postcall(lua_State*, T, int) {}
484 // ******** const reference converter *********
486 struct const_ref_converter
488 typedef const_ref_converter type;
489 typedef mpl::false_ is_native;
491 template<class T>
492 void apply(lua_State* L, T const& ref)
494 if (luabind::get_back_reference(L, ref))
495 return;
497 class_rep* crep = get_class_rep<T>(L);
499 // if you get caught in this assert you are
500 // trying to use an unregistered type
501 assert(crep && "you are trying to use an unregistered type");
503 T const* ptr = &ref;
505 // create the struct to hold the object
506 void* obj = lua_newuserdata(L, sizeof(object_rep));
507 assert(obj && "internal error, please report");
508 new(obj) object_rep(const_cast<T*>(ptr), crep, object_rep::constant, 0);
510 // set the meta table
511 detail::getref(L, crep->metatable_ref());
512 lua_setmetatable(L, -2);
515 conversion_storage storage;
517 template<class T>
518 T const& apply(lua_State* L, by_const_reference<T>, int index)
520 object_rep* obj = 0;
521 class_rep const * crep = 0;
523 // special case if we get nil in, try to convert the holder type
524 if (lua_isnil(L, index))
526 crep = get_class_rep<T>(L);
527 assert(crep);
529 else
531 obj = static_cast<object_rep*>(lua_touserdata(L, index));
532 assert((obj != 0) && "internal error, please report"); // internal error
533 crep = obj->crep();
535 assert(crep);
537 return *static_cast<T*>(crep->convert_to(LUABIND_TYPEID(T), obj, storage));
540 template<class T>
541 static int match(lua_State* L, by_const_reference<T>, int index)
543 // special case if we get nil in, try to match the holder type
544 if (lua_isnil(L, index))
546 class_rep* crep = get_class_rep<T>(L);
547 if (crep == 0) return -1;
548 if ((LUABIND_TYPE_INFO_EQUAL(crep->holder_type(), LUABIND_TYPEID(T))))
549 return 0;
550 if ((LUABIND_TYPE_INFO_EQUAL(crep->const_holder_type(), LUABIND_TYPEID(T))))
551 return 0;
552 return -1;
555 object_rep* obj = is_class_object(L, index);
556 if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match
558 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->holder_type(), LUABIND_TYPEID(T))))
559 return (obj->flags() & object_rep::constant)?-1:0;
560 if ((LUABIND_TYPE_INFO_EQUAL(obj->crep()->const_holder_type(), LUABIND_TYPEID(T))))
561 return (obj->flags() & object_rep::constant)?0:1;
563 bool const_ = obj->flags() & object_rep::constant;
564 int d;
565 int points = implicit_cast(obj->crep(), LUABIND_TYPEID(T), d);
566 return points == -1 ? -1 : points + !const_;
569 template<class T>
570 void converter_postcall(lua_State* L, by_const_reference<T>, int index)
575 // ****** enum converter ********
577 struct enum_converter
579 typedef enum_converter type;
580 typedef mpl::true_ is_native;
582 void apply(lua_State* L, int val)
584 lua_pushnumber(L, val);
587 template<class T>
588 T apply(lua_State* L, by_value<T>, int index)
590 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
593 template<class T>
594 static int match(lua_State* L, by_value<T>, int index)
596 if (lua_isnumber(L, index)) return 0; else return -1;
599 template<class T>
600 T apply(lua_State* L, by_const_reference<T>, int index)
602 return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
605 template<class T>
606 static int match(lua_State* L, by_const_reference<T>, int index)
608 if (lua_isnumber(L, index)) return 0; else return -1;
611 template<class T>
612 void converter_postcall(lua_State*, T, int) {}
615 template <class U>
616 struct value_wrapper_converter
618 typedef value_wrapper_converter<U> type;
619 typedef mpl::true_ is_native;
621 template<class T>
622 T apply(lua_State* L, by_const_reference<T>, int index)
624 return T(from_stack(L, index));
627 template<class T>
628 T apply(lua_State* L, by_value<T>, int index)
630 return apply(L, by_const_reference<T>(), index);
633 template<class T>
634 static int match(lua_State* L, by_const_reference<T>, int index)
636 return value_wrapper_traits<T>::check(L, index)
637 ? (std::numeric_limits<int>::max)() / LUABIND_MAX_ARITY
638 : -1;
641 template<class T>
642 static int match(lua_State* L, by_value<T>, int index)
644 return match(L, by_const_reference<T>(), index);
647 void converter_postcall(...) {}
649 template<class T>
650 void apply(lua_State* interpreter, T const& value_wrapper)
652 value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
656 template <class T>
657 struct default_converter_generator
658 : mpl::eval_if<
659 is_value_wrapper_arg<T>
660 , value_wrapper_converter<T>
661 , mpl::eval_if<
662 boost::is_enum<typename boost::remove_reference<T>::type>
663 , enum_converter
664 , mpl::eval_if<
665 is_nonconst_pointer<T>
666 , pointer_converter
667 , mpl::eval_if<
668 is_const_pointer<T>
669 , const_pointer_converter
670 , mpl::eval_if<
671 is_nonconst_reference<T>
672 , ref_converter
673 , mpl::eval_if<
674 is_const_reference<T>
675 , const_ref_converter
676 , value_converter
685 } // namespace detail
687 // *********** default_policy *****************
689 template <class T>
690 struct default_converter
691 : detail::default_converter_generator<T>::type
694 template <class T, class Derived = default_converter<T> >
695 struct native_converter_base
697 typedef boost::mpl::true_ is_native;
699 template <class U>
700 void converter_postcall(lua_State*, U const&, int)
703 static int match(lua_State* L, detail::by_value<T>, int index)
705 return Derived::compute_score(L, index);
708 static int match(lua_State* L, detail::by_value<T const>, int index)
710 return Derived::compute_score(L, index);
713 static int match(lua_State* L, detail::by_const_reference<T>, int index)
715 return Derived::compute_score(L, index);
718 T apply(lua_State* L, detail::by_value<T>, int index)
720 return derived().from(L, index);
723 T apply(lua_State* L, detail::by_value<T const>, int index)
725 return derived().from(L, index);
728 T apply(lua_State* L, detail::by_const_reference<T>, int index)
730 return derived().from(L, index);
733 void apply(lua_State* L, T const& value)
735 derived().to(L, value);
738 Derived& derived()
740 return static_cast<Derived&>(*this);
744 # define LUABIND_NUMBER_CONVERTER(type) \
745 template <> \
746 struct default_converter<type> \
747 : native_converter_base<type> \
749 static int compute_score(lua_State* L, int index) \
751 return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
752 }; \
754 type from(lua_State* L, int index) \
756 return static_cast<type>(lua_tonumber(L, index)); \
759 void to(lua_State* L, type const& value) \
761 lua_pushnumber(L, static_cast<lua_Number>(value)); \
763 }; \
765 template <> \
766 struct default_converter<type const> \
767 : default_converter<type> \
768 {}; \
770 template <> \
771 struct default_converter<type const&> \
772 : default_converter<type> \
775 LUABIND_NUMBER_CONVERTER(char)
776 LUABIND_NUMBER_CONVERTER(signed char)
777 LUABIND_NUMBER_CONVERTER(unsigned char)
778 LUABIND_NUMBER_CONVERTER(signed short)
779 LUABIND_NUMBER_CONVERTER(unsigned short)
780 LUABIND_NUMBER_CONVERTER(signed int)
781 LUABIND_NUMBER_CONVERTER(unsigned int)
782 LUABIND_NUMBER_CONVERTER(signed long)
783 LUABIND_NUMBER_CONVERTER(unsigned long)
784 LUABIND_NUMBER_CONVERTER(float)
785 LUABIND_NUMBER_CONVERTER(double)
786 LUABIND_NUMBER_CONVERTER(long double)
788 # undef LUABIND_NUMBER_CONVERTER
790 template <>
791 struct default_converter<bool>
792 : native_converter_base<bool>
794 static int compute_score(lua_State* L, int index)
796 return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1;
799 bool from(lua_State* L, int index)
801 return lua_toboolean(L, index) == 1;
804 void to(lua_State* L, bool value)
806 lua_pushboolean(L, value);
810 template <>
811 struct default_converter<bool const>
812 : default_converter<bool>
815 template <>
816 struct default_converter<bool const&>
817 : default_converter<bool>
820 template <>
821 struct default_converter<std::string>
822 : native_converter_base<std::string>
824 static int compute_score(lua_State* L, int index)
826 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
829 std::string from(lua_State* L, int index)
831 return std::string(lua_tostring(L, index), lua_strlen(L, index));
834 void to(lua_State* L, std::string const& value)
836 lua_pushlstring(L, value.data(), value.size());
840 template <>
841 struct default_converter<std::string const>
842 : default_converter<std::string>
845 template <>
846 struct default_converter<std::string const&>
847 : default_converter<std::string>
850 template <>
851 struct default_converter<char const*>
853 typedef boost::mpl::true_ is_native;
855 template <class U>
856 static int match(lua_State* L, U, int index)
858 return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
861 template <class U>
862 char const* apply(lua_State* L, U, int index)
864 return lua_tostring(L, index);
867 void apply(lua_State* L, char const* str)
869 lua_pushstring(L, str);
872 template <class U>
873 void converter_postcall(lua_State*, U, int)
877 template <>
878 struct default_converter<const char* const>
879 : default_converter<char const*>
882 template <>
883 struct default_converter<char*>
884 : default_converter<char const*>
887 template <std::size_t N>
888 struct default_converter<char const[N]>
889 : default_converter<char const*>
892 template <std::size_t N>
893 struct default_converter<char[N]>
894 : default_converter<char const*>
897 namespace detail
900 struct default_policy : converter_policy_tag
902 BOOST_STATIC_CONSTANT(bool, has_arg = true);
904 template<class T>
905 static void precall(lua_State*, T, int) {}
907 template<class T, class Direction>
908 struct apply
910 typedef default_converter<T> type;
914 template<class T>
915 struct is_primitive
916 : default_converter<T>::is_native
919 // ============== new policy system =================
921 template<int, class> struct find_conversion_policy;
923 template<bool IsConverter = false>
924 struct find_conversion_impl
926 template<int N, class Policies>
927 struct apply
929 typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
933 template<>
934 struct find_conversion_impl<true>
936 template<int N, class Policies>
937 struct apply
939 typedef typename Policies::head head;
940 typedef typename Policies::tail tail;
942 BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
944 typedef typename
945 boost::mpl::if_c<found
946 , head
947 , typename find_conversion_policy<N, tail>::type
948 >::type type;
952 template<class Policies>
953 struct find_conversion_impl2
955 template<int N>
956 struct apply
957 : find_conversion_impl<
958 boost::is_base_and_derived<conversion_policy_base, typename Policies::head>::value
959 >::template apply<N, Policies>
964 template<>
965 struct find_conversion_impl2<detail::null_type>
967 template<int N>
968 struct apply
970 typedef default_policy type;
974 template<int N, class Policies>
975 struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
979 template<class List>
980 struct policy_list_postcall
982 typedef typename List::head head;
983 typedef typename List::tail tail;
985 static void apply(lua_State* L, const index_map& i)
987 head::postcall(L, i);
988 policy_list_postcall<tail>::apply(L, i);
992 template<>
993 struct policy_list_postcall<detail::null_type>
995 static void apply(lua_State*, const index_map&) {}
998 // ==================================================
1000 // ************** precall and postcall on policy_cons *********************
1003 template<class List>
1004 struct policy_precall
1006 typedef typename List::head head;
1007 typedef typename List::tail tail;
1009 static void apply(lua_State* L, int index)
1011 head::precall(L, index);
1012 policy_precall<tail>::apply(L, index);
1016 template<>
1017 struct policy_precall<detail::null_type>
1019 static void apply(lua_State*, int) {}
1022 template<class List>
1023 struct policy_postcall
1025 typedef typename List::head head;
1026 typedef typename List::tail tail;
1028 static void apply(lua_State* L, int index)
1030 head::postcall(L, index);
1031 policy_postcall<tail>::apply(L, index);
1035 template<>
1036 struct policy_postcall<detail::null_type>
1038 static void apply(lua_State*, int) {}
1041 }} // namespace luabind::detail
1044 namespace luabind { namespace
1046 #if defined(__GNUC__) && \
1047 (__GNUC__ * 100 + __GNUC_MINOR__ <= 400 || BOOST_VERSION <= 103401)
1048 static inline boost::arg<0> return_value()
1050 return boost::arg<0>();
1053 static inline boost::arg<0> result()
1055 return boost::arg<0>();
1057 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
1058 #elif defined(BOOST_MSVC) || defined(__MWERKS__)
1059 static boost::arg<0> return_value;
1060 static boost::arg<0> result;
1061 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1062 #else
1063 boost::arg<0> return_value;
1064 boost::arg<0> result;
1065 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1066 #endif
1069 #endif // LUABIND_POLICY_HPP_INCLUDED