1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
2 
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:
9 
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 
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.
22 
23 
24 #ifndef LUABIND_POLICY_HPP_INCLUDED
25 #define LUABIND_POLICY_HPP_INCLUDED
26 
27 #include <luabind/config.hpp>
28 
29 #include <typeinfo>
30 #include <string>
31 #include <memory>
32 
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>
48 
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>
58 
59 #include <boost/type_traits/add_reference.hpp>
60 
61 #include <luabind/detail/decorate_type.hpp>
62 #include <luabind/weak_ref.hpp>
63 #include <luabind/back_reference_fwd.hpp>
64 
65 #include <luabind/value_wrapper.hpp>
66 #include <luabind/from_stack.hpp>
67 #include <luabind/typeid.hpp>
68 
69 namespace luabind
70 {
71 	namespace detail
72 	{
73 		struct conversion_policy_base {};
74 	}
75 
76 	template<int N, bool HasArg = true>
77 	struct conversion_policy : detail::conversion_policy_base
78 	{
79 		BOOST_STATIC_CONSTANT(int, index = N);
80 		BOOST_STATIC_CONSTANT(bool, has_arg = HasArg);
81 	};
82 
83 	class index_map
84 	{
85 	public:
index_map(const int * m)86 		index_map(const int* m): m_map(m) {}
87 
operator [](int index) const88 		int operator[](int index) const
89 		{
90 			return m_map[index];
91 		}
92 
93 	private:
94 		const int* m_map;
95 	};
96 
97 //	 template<class T> class functor;
98 	 class weak_ref;
99 }
100 
101 namespace luabind { namespace detail
102 {
103 	template<class H, class T>
104 	struct policy_cons
105 	{
106 		typedef H head;
107 		typedef T tail;
108 
109 		template<class U>
operator ,luabind::detail::policy_cons110 		policy_cons<U, policy_cons<H,T> > operator,(policy_cons<U,detail::null_type>)
111 		{
112 			return policy_cons<U, policy_cons<H,T> >();
113 		}
114 
115 		template<class U>
operator +luabind::detail::policy_cons116 		policy_cons<U, policy_cons<H,T> > operator+(policy_cons<U,detail::null_type>)
117 		{
118 			return policy_cons<U, policy_cons<H,T> >();
119 		}
120 
121 		template<class U>
operator |luabind::detail::policy_cons122 		policy_cons<U, policy_cons<H,T> > operator|(policy_cons<U,detail::null_type>)
123 		{
124 			return policy_cons<U, policy_cons<H,T> >();
125 		}
126 	};
127 
128 	struct indirection_layer
129 	{
130 		template<class T>
131 		indirection_layer(const T&);
132 	};
133 
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(...);
138 
139 	template<class T>
140 	struct is_policy_cons
141 	{
142 		static const T& t;
143 
144 		BOOST_STATIC_CONSTANT(bool, value =
145 			sizeof(is_policy_cons_test(t)) == sizeof(yes_t));
146 
147 		typedef boost::mpl::bool_<value> type;
148 	};
149 
150 	template<bool>
151 	struct is_string_literal
152 	{
153 		static no_t helper(indirection_layer);
154 		static yes_t helper(const char*);
155 	};
156 
157 	template<>
158 	struct is_string_literal<false>
159 	{
160 		static no_t helper(indirection_layer);
161 	};
162 
163 
164     namespace mpl = boost::mpl;
165 
166     template <class T, class Clone>
make_pointee_instance(lua_State * L,T & x,mpl::true_,Clone)167     void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone)
168     {
169         if (get_pointer(x))
170         {
171             make_instance(L, x);
172         }
173         else
174         {
175             lua_pushnil(L);
176         }
177     }
178 
179     template <class T>
make_pointee_instance(lua_State * L,T & x,mpl::false_,mpl::true_)180     void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_)
181     {
182         std::auto_ptr<T> ptr(new T(x));
183         make_instance(L, ptr);
184     }
185 
186     template <class T>
make_pointee_instance(lua_State * L,T & x,mpl::false_,mpl::false_)187     void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_)
188     {
189         make_instance(L, &x);
190     }
191 
192     template <class T, class Clone>
make_pointee_instance(lua_State * L,T & x,Clone)193     void make_pointee_instance(lua_State* L, T& x, Clone)
194     {
195         make_pointee_instance(L, x, has_get_pointer<T>(), Clone());
196     }
197 
198 // ********** pointer converter ***********
199 
200 	struct pointer_converter
201 	{
202 		typedef pointer_converter type;
203         typedef mpl::false_ is_native;
204 
pointer_converterluabind::detail::pointer_converter205         pointer_converter()
206           : result(0)
207         {}
208 
209         void* result;
210 
consumed_argsluabind::detail::pointer_converter211         int const consumed_args(...)
212         {
213             return 1;
214         }
215 
216 		template<class T>
applyluabind::detail::pointer_converter217 		void apply(lua_State* L, T* ptr)
218 		{
219 			if (ptr == 0)
220 			{
221 				lua_pushnil(L);
222 				return;
223 			}
224 
225 			if (luabind::get_back_reference(L, ptr))
226 				return;
227 
228             make_instance(L, ptr);
229 		}
230 
231 		template<class T>
applyluabind::detail::pointer_converter232 		T* apply(lua_State*, by_pointer<T>, int)
233 		{
234             return static_cast<T*>(result);
235 		}
236 
237 		template<class T>
matchluabind::detail::pointer_converter238 		int match(lua_State* L, by_pointer<T>, int index)
239 		{
240 			if (lua_isnil(L, index)) return 0;
241 			object_rep* obj = get_instance(L, index);
242 			if (obj == 0) return -1;
243 
244             if (obj->is_const())
245                 return -1;
246 
247             std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
248             result = s.first;
249             return s.second;
250 		}
251 
252 		template<class T>
converter_postcallluabind::detail::pointer_converter253 		void converter_postcall(lua_State*, by_pointer<T>, int)
254 		{}
255 	};
256 
257 // ******* value converter *******
258 
259 	struct value_converter
260 	{
261 		typedef value_converter type;
262         typedef mpl::false_ is_native;
263 
consumed_argsluabind::detail::value_converter264         int const consumed_args(...)
265         {
266             return 1;
267         }
268 
value_converterluabind::detail::value_converter269         value_converter()
270           : result(0)
271         {}
272 
273         void* result;
274 
275 		template<class T>
applyluabind::detail::value_converter276 		void apply(lua_State* L, T x)
277 		{
278 			if (luabind::get_back_reference(L, x))
279 				return;
280 
281             make_pointee_instance(L, x, mpl::true_());
282 		}
283 
284 		template<class T>
applyluabind::detail::value_converter285 		T apply(lua_State*, by_value<T>, int)
286 		{
287             return *static_cast<T*>(result);
288 		}
289 
290 		template<class T>
matchluabind::detail::value_converter291 		int match(lua_State* L, by_value<T>, int index)
292 		{
293 			// special case if we get nil in, try to match the holder type
294 			if (lua_isnil(L, index))
295 				return -1;
296 
297 			object_rep* obj = get_instance(L, index);
298 			if (obj == 0) return -1;
299 
300             std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
301             result = s.first;
302             return s.second;
303 		}
304 
305 		template<class T>
converter_postcallluabind::detail::value_converter306 		void converter_postcall(lua_State*, T, int) {}
307 	};
308 
309 // ******* const pointer converter *******
310 
311     struct const_pointer_converter
312 	{
313 		typedef const_pointer_converter type;
314         typedef mpl::false_ is_native;
315 
consumed_argsluabind::detail::const_pointer_converter316         int const consumed_args(...)
317         {
318             return 1;
319         }
320 
const_pointer_converterluabind::detail::const_pointer_converter321         const_pointer_converter()
322           : result(0)
323         {}
324 
325         void* result;
326 
327 		template<class T>
applyluabind::detail::const_pointer_converter328 		void apply(lua_State* L, const T* ptr)
329 		{
330 			if (ptr == 0)
331 			{
332 				lua_pushnil(L);
333 				return;
334 			}
335 
336 			if (luabind::get_back_reference(L, ptr))
337 				return;
338 
339             make_instance(L, ptr);
340 		}
341 
342 		template<class T>
applyluabind::detail::const_pointer_converter343 		T const* apply(lua_State*, by_const_pointer<T>, int)
344 		{
345 			return static_cast<T const*>(result);
346 		}
347 
348 		template<class T>
matchluabind::detail::const_pointer_converter349 		int match(lua_State* L, by_const_pointer<T>, int index)
350 		{
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;
359 		}
360 
361         template<class T>
converter_postcallluabind::detail::const_pointer_converter362         void converter_postcall(lua_State*, T, int) {}
363 	};
364 
365 // ******* reference converter *******
366 
367     struct ref_converter : pointer_converter
368 	{
369 		typedef ref_converter type;
370         typedef mpl::false_ is_native;
371 
consumed_argsluabind::detail::ref_converter372         int const consumed_args(...)
373         {
374             return 1;
375         }
376 
377 		template<class T>
applyluabind::detail::ref_converter378 		void apply(lua_State* L, T& ref)
379 		{
380 			if (luabind::get_back_reference(L, ref))
381 				return;
382 
383             make_pointee_instance(L, ref, mpl::false_());
384 		}
385 
386 		template<class T>
applyluabind::detail::ref_converter387 		T& apply(lua_State* L, by_reference<T>, int index)
388 		{
389 			assert(!lua_isnil(L, index));
390             return *pointer_converter::apply(L, by_pointer<T>(), index);
391 		}
392 
393 		template<class T>
matchluabind::detail::ref_converter394 		int match(lua_State* L, by_reference<T>, int index)
395 		{
396             object_rep* obj = get_instance(L, index);
397             if (obj == 0) return -1;
398 
399             if (obj->is_const())
400                 return -1;
401 
402             std::pair<void*, int> s = obj->get_instance(registered_class<T>::id);
403             result = s.first;
404             return s.second;
405 		}
406 
407 		template<class T>
converter_postcallluabind::detail::ref_converter408 		void converter_postcall(lua_State*, T, int) {}
409 	};
410 
411 // ******** const reference converter *********
412 
413 	struct const_ref_converter
414 	{
415 		typedef const_ref_converter type;
416         typedef mpl::false_ is_native;
417 
consumed_argsluabind::detail::const_ref_converter418         int const consumed_args(...)
419         {
420             return 1;
421         }
422 
const_ref_converterluabind::detail::const_ref_converter423         const_ref_converter()
424           : result(0)
425         {}
426 
427         void* result;
428 
429 		template<class T>
applyluabind::detail::const_ref_converter430 		void apply(lua_State* L, T const& ref)
431 		{
432 			if (luabind::get_back_reference(L, ref))
433 				return;
434 
435             make_pointee_instance(L, ref, mpl::false_());
436 		}
437 
438 		template<class T>
applyluabind::detail::const_ref_converter439 		T const& apply(lua_State*, by_const_reference<T>, int)
440 		{
441 			return *static_cast<T*>(result);
442 		}
443 
444 		template<class T>
matchluabind::detail::const_ref_converter445 		int match(lua_State* L, by_const_reference<T>, int index)
446 		{
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
449 
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;
455 		}
456 
457 		template<class T>
converter_postcallluabind::detail::const_ref_converter458 		void converter_postcall(lua_State*, by_const_reference<T>, int)
459 		{
460 		}
461 	};
462 
463 	// ****** enum converter ********
464 
465 	struct enum_converter
466 	{
467 		typedef enum_converter type;
468         typedef mpl::true_ is_native;
469 
consumed_argsluabind::detail::enum_converter470         int const consumed_args(...)
471         {
472             return 1;
473         }
474 
applyluabind::detail::enum_converter475 		void apply(lua_State* L, int val)
476 		{
477 			lua_pushnumber(L, val);
478 		}
479 
480 		template<class T>
applyluabind::detail::enum_converter481 		T apply(lua_State* L, by_value<T>, int index)
482 		{
483 			return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
484 		}
485 
486 		template<class T>
matchluabind::detail::enum_converter487 		static int match(lua_State* L, by_value<T>, int index)
488 		{
489 			if (lua_isnumber(L, index)) return 0; else return -1;
490 		}
491 
492 		template<class T>
applyluabind::detail::enum_converter493 		T apply(lua_State* L, by_const_reference<T>, int index)
494 		{
495 			return static_cast<T>(static_cast<int>(lua_tonumber(L, index)));
496 		}
497 
498 		template<class T>
matchluabind::detail::enum_converter499 		static int match(lua_State* L, by_const_reference<T>, int index)
500 		{
501 			if (lua_isnumber(L, index)) return 0; else return -1;
502 		}
503 
504 		template<class T>
converter_postcallluabind::detail::enum_converter505 		void converter_postcall(lua_State*, T, int) {}
506 	};
507 
508 	template <class U>
509 	struct value_wrapper_converter
510 	{
511 		typedef value_wrapper_converter<U> type;
512 		typedef mpl::true_ is_native;
513 
consumed_argsluabind::detail::value_wrapper_converter514         int const consumed_args(...)
515         {
516             return 1;
517         }
518 
519 		template<class T>
applyluabind::detail::value_wrapper_converter520 		T apply(lua_State* L, by_const_reference<T>, int index)
521 		{
522 			return T(from_stack(L, index));
523 		}
524 
525 		template<class T>
applyluabind::detail::value_wrapper_converter526 		T apply(lua_State* L, by_value<T>, int index)
527 		{
528 			return apply(L, by_const_reference<T>(), index);
529 		}
530 
531 		template<class T>
matchluabind::detail::value_wrapper_converter532 		static int match(lua_State* L, by_const_reference<T>, int index)
533 		{
534 			return value_wrapper_traits<T>::check(L, index)
535                 ? (std::numeric_limits<int>::max)() / LUABIND_MAX_ARITY
536                 : -1;
537 		}
538 
539 		template<class T>
matchluabind::detail::value_wrapper_converter540 		static int match(lua_State* L, by_value<T>, int index)
541 		{
542 			return match(L, by_const_reference<T>(), index);
543 		}
544 
converter_postcallluabind::detail::value_wrapper_converter545 		void converter_postcall(...) {}
546 
547 		template<class T>
applyluabind::detail::value_wrapper_converter548 		void apply(lua_State* interpreter, T const& value_wrapper)
549 		{
550 			value_wrapper_traits<T>::unwrap(interpreter, value_wrapper);
551 		}
552     };
553 
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
575                             >
576                         >
577                     >
578                 >
579             >
580         >
581     {};
582 
583 } // namespace detail
584 
585 // *********** default_policy *****************
586 
587 template <class T>
588 struct default_converter
589   : detail::default_converter_generator<T>::type
590 {};
591 
592 template <class T, class Derived = default_converter<T> >
593 struct native_converter_base
594 {
595     typedef boost::mpl::true_ is_native;
596 
consumed_argsluabind::native_converter_base597     int const consumed_args(...)
598     {
599         return 1;
600     }
601 
602     template <class U>
converter_postcallluabind::native_converter_base603     void converter_postcall(lua_State*, U const&, int)
604     {}
605 
matchluabind::native_converter_base606     int match(lua_State* L, detail::by_value<T>, int index)
607     {
608         return derived().compute_score(L, index);
609     }
610 
matchluabind::native_converter_base611     int match(lua_State* L, detail::by_value<T const>, int index)
612     {
613         return derived().compute_score(L, index);
614     }
615 
matchluabind::native_converter_base616     int match(lua_State* L, detail::by_const_reference<T>, int index)
617     {
618         return derived().compute_score(L, index);
619     }
620 
applyluabind::native_converter_base621     T apply(lua_State* L, detail::by_value<T>, int index)
622     {
623         return derived().from(L, index);
624     }
625 
applyluabind::native_converter_base626     T apply(lua_State* L, detail::by_value<T const>, int index)
627     {
628         return derived().from(L, index);
629     }
630 
applyluabind::native_converter_base631     T apply(lua_State* L, detail::by_const_reference<T>, int index)
632     {
633         return derived().from(L, index);
634     }
635 
applyluabind::native_converter_base636     void apply(lua_State* L, T const& value)
637     {
638         derived().to(L, value);
639     }
640 
derivedluabind::native_converter_base641     Derived& derived()
642     {
643         return static_cast<Derived&>(*this);
644     }
645 };
646 
647 template <class T>
as_lua_integer(T v)648 lua_Integer as_lua_integer(T v)
649 {
650     return static_cast<lua_Integer>(v);
651 }
652 
653 template <class T>
as_lua_number(T v)654 lua_Number as_lua_number(T v)
655 {
656     return static_cast<lua_Number>(v);
657 }
658 
659 # define LUABIND_NUMBER_CONVERTER(type, kind) \
660     template <> \
661 struct default_converter<type> \
662   : native_converter_base<type> \
663 { \
664     int compute_score(lua_State* L, int index) \
665     { \
666         return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \
667     }; \
668     \
669     type from(lua_State* L, int index) \
670     { \
671         return static_cast<type>(BOOST_PP_CAT(lua_to, kind)(L, index)); \
672     } \
673     \
674     void to(lua_State* L, type const& value) \
675     { \
676         BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \
677     } \
678 }; \
679 \
680 template <> \
681 struct default_converter<type const> \
682   : default_converter<type> \
683 {}; \
684 \
685 template <> \
686 struct default_converter<type const&> \
687   : default_converter<type> \
688 {};
689 
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)
696 
697 LUABIND_NUMBER_CONVERTER(unsigned int, number)
698 LUABIND_NUMBER_CONVERTER(unsigned long, number)
699 
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)
704 
705 # undef LUABIND_NUMBER_CONVERTER
706 
707 template <>
708 struct default_converter<bool>
709   : native_converter_base<bool>
710 {
compute_scoreluabind::default_converter711     static int compute_score(lua_State* L, int index)
712     {
713         return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1;
714     }
715 
fromluabind::default_converter716     bool from(lua_State* L, int index)
717     {
718         return lua_toboolean(L, index) == 1;
719     }
720 
toluabind::default_converter721     void to(lua_State* L, bool value)
722     {
723         lua_pushboolean(L, value);
724     }
725 };
726 
727 template <>
728 struct default_converter<bool const>
729   : default_converter<bool>
730 {};
731 
732 template <>
733 struct default_converter<bool const&>
734   : default_converter<bool>
735 {};
736 
737 template <>
738 struct default_converter<std::string>
739   : native_converter_base<std::string>
740 {
compute_scoreluabind::default_converter741     static int compute_score(lua_State* L, int index)
742     {
743         return lua_type(L, index) == LUA_TSTRING ? 0 : -1;
744     }
745 
fromluabind::default_converter746     std::string from(lua_State* L, int index)
747     {
748         return std::string(lua_tostring(L, index), lua_strlen(L, index));
749     }
750 
toluabind::default_converter751     void to(lua_State* L, std::string const& value)
752     {
753         lua_pushlstring(L, value.data(), value.size());
754     }
755 };
756 
757 template <>
758 struct default_converter<std::string const>
759   : default_converter<std::string>
760 {};
761 
762 template <>
763 struct default_converter<std::string const&>
764   : default_converter<std::string>
765 {};
766 
767 template <>
768 struct default_converter<char const*>
769 {
770     typedef boost::mpl::true_ is_native;
771 
consumed_argsluabind::default_converter772     int const consumed_args(...)
773     {
774         return 1;
775     }
776 
777     template <class U>
matchluabind::default_converter778     static int match(lua_State* L, U, int index)
779     {
780         int type = lua_type(L, index);
781         return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1;
782     }
783 
784     template <class U>
applyluabind::default_converter785     char const* apply(lua_State* L, U, int index)
786     {
787         return lua_tostring(L, index);
788     }
789 
applyluabind::default_converter790     void apply(lua_State* L, char const* str)
791     {
792         lua_pushstring(L, str);
793     }
794 
795     template <class U>
converter_postcallluabind::default_converter796     void converter_postcall(lua_State*, U, int)
797     {}
798 };
799 
800 template <>
801 struct default_converter<const char* const>
802   : default_converter<char const*>
803 {};
804 
805 template <>
806 struct default_converter<char*>
807   : default_converter<char const*>
808 {};
809 
810 template <std::size_t N>
811 struct default_converter<char const[N]>
812   : default_converter<char const*>
813 {};
814 
815 template <std::size_t N>
816 struct default_converter<char[N]>
817   : default_converter<char const*>
818 {};
819 
820 template <>
821 struct default_converter<lua_State*>
822 {
consumed_argsluabind::default_converter823     int const consumed_args(...)
824     {
825         return 0;
826     }
827 
828     template <class U>
applyluabind::default_converter829     lua_State* apply(lua_State* L, U, int)
830     {
831         return L;
832     }
833 
834     template <class U>
matchluabind::default_converter835     static int match(lua_State*, U, int)
836     {
837         return 0;
838     }
839 
840     template <class U>
converter_postcallluabind::default_converter841     void converter_postcall(lua_State*, U, int) {}
842 };
843 
844 namespace detail
845 {
846 
847 	struct default_policy : converter_policy_tag
848 	{
849 		BOOST_STATIC_CONSTANT(bool, has_arg = true);
850 
851 		template<class T>
precallluabind::detail::default_policy852 		static void precall(lua_State*, T, int) {}
853 
854 		template<class T, class Direction>
855 		struct apply
856 		{
857             typedef default_converter<T> type;
858         };
859 	};
860 
861     template<class T>
862     struct is_primitive
863       : default_converter<T>::is_native
864     {};
865 
866 // ============== new policy system =================
867 
868 	template<int, class> struct find_conversion_policy;
869 
870 	template<bool IsConverter = false>
871 	struct find_conversion_impl
872 	{
873 		template<int N, class Policies>
874 		struct apply
875 		{
876 			typedef typename find_conversion_policy<N, typename Policies::tail>::type type;
877 		};
878 	};
879 
880 	template<>
881 	struct find_conversion_impl<true>
882 	{
883 		template<int N, class Policies>
884 		struct apply
885 		{
886 			typedef typename Policies::head head;
887 			typedef typename Policies::tail tail;
888 
889 			BOOST_STATIC_CONSTANT(bool, found = (N == head::index));
890 
891 			typedef typename
892 				boost::mpl::if_c<found
893 					, head
894 					, typename find_conversion_policy<N, tail>::type
895 				>::type type;
896 		};
897 	};
898 
899 	template<class Policies>
900 	struct find_conversion_impl2
901 	{
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>
907 		{
908 		};
909 	};
910 
911 	template<>
912 	struct find_conversion_impl2<detail::null_type>
913 	{
914 		template<int N>
915 		struct apply
916 		{
917 			typedef default_policy type;
918 		};
919 	};
920 
921 	template<int N, class Policies>
922 	struct find_conversion_policy : find_conversion_impl2<Policies>::template apply<N>
923 	{
924 	};
925 
926 	template<class List>
927 	struct policy_list_postcall
928 	{
929 		typedef typename List::head head;
930 		typedef typename List::tail tail;
931 
applyluabind::detail::policy_list_postcall932 		static void apply(lua_State* L, const index_map& i)
933 		{
934 			head::postcall(L, i);
935 			policy_list_postcall<tail>::apply(L, i);
936 		}
937 	};
938 
939 	template<>
940 	struct policy_list_postcall<detail::null_type>
941 	{
applyluabind::detail::policy_list_postcall942 		static void apply(lua_State*, const index_map&) {}
943 	};
944 
945 // ==================================================
946 
947 // ************** precall and postcall on policy_cons *********************
948 
949 
950 	template<class List>
951 	struct policy_precall
952 	{
953 		typedef typename List::head head;
954 		typedef typename List::tail tail;
955 
applyluabind::detail::policy_precall956 		static void apply(lua_State* L, int index)
957 		{
958 			head::precall(L, index);
959 			policy_precall<tail>::apply(L, index);
960 		}
961 	};
962 
963 	template<>
964 	struct policy_precall<detail::null_type>
965 	{
applyluabind::detail::policy_precall966 		static void apply(lua_State*, int) {}
967 	};
968 
969 	template<class List>
970 	struct policy_postcall
971 	{
972 		typedef typename List::head head;
973 		typedef typename List::tail tail;
974 
applyluabind::detail::policy_postcall975 		static void apply(lua_State* L, int index)
976 		{
977 			head::postcall(L, index);
978 			policy_postcall<tail>::apply(L, index);
979 		}
980 	};
981 
982 	template<>
983 	struct policy_postcall<detail::null_type>
984 	{
applyluabind::detail::policy_postcall985 		static void apply(lua_State*, int) {}
986 	};
987 
988 }} // namespace luabind::detail
989 
990 
991 namespace luabind { namespace
992 {
993 #if defined(__GNUC__) && ( \
994     (BOOST_VERSION < 103500) \
995  || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \
996  || (__GNUC__ * 100 + __GNUC_MINOR__ < 400))
return_value()997   static inline boost::arg<0> return_value()
998   {
999 	  return boost::arg<0>();
1000   }
1001 
result()1002   static inline boost::arg<0> result()
1003   {
1004 	  return boost::arg<0>();
1005   }
1006 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>(*)()
1007 #elif defined(BOOST_MSVC) || defined(__MWERKS__) \
1008   || (BOOST_VERSION >= 103900 && defined(__GNUC__) \
1009         && (__GNUC__ * 100 + __GNUC_MINOR__ == 400))
1010   static boost::arg<0> return_value;
1011   static boost::arg<0> result;
1012 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1013 #else
1014   boost::arg<0> return_value;
1015   boost::arg<0> result;
1016 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1017 #endif
1018 }}
1019 
1020 #endif // LUABIND_POLICY_HPP_INCLUDED
1021 
1022