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>
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>
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
);
83 index_map(const int* m
): m_map(m
) {}
85 int operator[](int index
) const
97 LUABIND_API
int implicit_cast(const class_rep
* crep
, LUABIND_TYPE_INFO
const&, int& pointer_offset
);
100 // template<class T> class functor;
104 namespace luabind
{ namespace detail
106 template<class H
, class T
>
113 policy_cons
<U
, policy_cons
<H
,T
> > operator,(policy_cons
<U
,detail::null_type
>)
115 return policy_cons
<U
, policy_cons
<H
,T
> >();
119 policy_cons
<U
, policy_cons
<H
,T
> > operator+(policy_cons
<U
,detail::null_type
>)
121 return policy_cons
<U
, policy_cons
<H
,T
> >();
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
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(...);
143 struct is_policy_cons
147 BOOST_STATIC_CONSTANT(bool, value
=
148 sizeof(is_policy_cons_test(t
)) == sizeof(yes_t
));
150 typedef boost::mpl::bool_
<value
> type
;
154 struct is_string_literal
156 static no_t
helper(indirection_layer
);
157 static yes_t
helper(const char*);
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
;
177 void apply(lua_State
* L
, T
* ptr
)
185 if (luabind::get_back_reference(L
, ptr
))
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
;
207 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
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
));
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;
238 return implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
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
;
254 void apply(lua_State
* L
, const T
& ref
)
256 if (luabind::get_back_reference(L
, ref
))
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");
268 boost::tie(obj_rep
,held
) = crep
->allocate(L
);
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()))
280 flags
|= object_rep::constant
;
281 destructor
= crep
->const_holder_destructor();
283 else if (LUABIND_TYPE_INFO_EQUAL(LUABIND_TYPEID(T
), crep
->holder_type()))
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());
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
;
311 T
apply(lua_State
* L
, by_value
<T
>, int index
)
314 // lua_isuserdata(L, index);
315 // getmetatable().__lua_class is true
316 // object_rep->flags() & object_rep::constant == 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
);
329 obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
330 assert((obj
!= 0) && "internal error, please report"); // internal error
335 return *static_cast<T
*>(crep
->convert_to(LUABIND_TYPEID(T
), obj
, storage
));
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
))))
348 if ((LUABIND_TYPE_INFO_EQUAL(crep
->const_holder_type(), LUABIND_TYPEID(T
))))
353 object_rep
* obj
= is_class_object(L
, index
);
354 if (obj
== 0) return -1;
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
);
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
;
376 void apply(lua_State
* L
, const T
* ptr
)
384 if (luabind::get_back_reference(L
, ptr
))
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);
405 T
const* apply(lua_State
* L
, by_const_pointer
<T
>, int index
)
407 return pointer_converter::apply(L
, by_pointer
<T
>(), index
);
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
;
424 int points
= implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
425 return points
== -1 ? -1 : points
+ !const_
;
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 *******
439 typedef ref_converter type
;
440 typedef mpl::false_ is_native
;
443 void apply(lua_State
* L
, T
& ref
)
445 if (luabind::get_back_reference(L
, ref
))
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");
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);
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
);
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
);
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
;
492 void apply(lua_State
* L
, T
const& ref
)
494 if (luabind::get_back_reference(L
, ref
))
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");
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
;
518 T
const& apply(lua_State
* L
, by_const_reference
<T
>, int index
)
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
);
531 obj
= static_cast<object_rep
*>(lua_touserdata(L
, index
));
532 assert((obj
!= 0) && "internal error, please report"); // internal error
537 return *static_cast<T
*>(crep
->convert_to(LUABIND_TYPEID(T
), obj
, storage
));
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
))))
550 if ((LUABIND_TYPE_INFO_EQUAL(crep
->const_holder_type(), LUABIND_TYPEID(T
))))
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
;
565 int points
= implicit_cast(obj
->crep(), LUABIND_TYPEID(T
), d
);
566 return points
== -1 ? -1 : points
+ !const_
;
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
);
588 T
apply(lua_State
* L
, by_value
<T
>, int index
)
590 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
594 static int match(lua_State
* L
, by_value
<T
>, int index
)
596 if (lua_isnumber(L
, index
)) return 0; else return -1;
600 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
602 return static_cast<T
>(static_cast<int>(lua_tonumber(L
, index
)));
606 static int match(lua_State
* L
, by_const_reference
<T
>, int index
)
608 if (lua_isnumber(L
, index
)) return 0; else return -1;
612 void converter_postcall(lua_State
*, T
, int) {}
616 struct value_wrapper_converter
618 typedef value_wrapper_converter
<U
> type
;
619 typedef mpl::true_ is_native
;
622 T
apply(lua_State
* L
, by_const_reference
<T
>, int index
)
624 return T(from_stack(L
, index
));
628 T
apply(lua_State
* L
, by_value
<T
>, int index
)
630 return apply(L
, by_const_reference
<T
>(), index
);
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
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(...) {}
650 void apply(lua_State
* interpreter
, T
const& value_wrapper
)
652 value_wrapper_traits
<T
>::unwrap(interpreter
, value_wrapper
);
657 struct default_converter_generator
659 is_value_wrapper_arg
<T
>
660 , value_wrapper_converter
<T
>
662 boost::is_enum
<typename
boost::remove_reference
<T
>::type
>
665 is_nonconst_pointer
<T
>
669 , const_pointer_converter
671 is_nonconst_reference
<T
>
674 is_const_reference
<T
>
675 , const_ref_converter
685 } // namespace detail
687 // *********** default_policy *****************
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
;
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
);
740 return static_cast<Derived
&>(*this);
744 # define LUABIND_NUMBER_CONVERTER(type) \
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; \
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)); \
766 struct default_converter<type const> \
767 : default_converter<type> \
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
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
);
811 struct default_converter
<bool const>
812 : default_converter
<bool>
816 struct default_converter
<bool const&>
817 : default_converter
<bool>
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());
841 struct default_converter
<std::string
const>
842 : default_converter
<std::string
>
846 struct default_converter
<std::string
const&>
847 : default_converter
<std::string
>
851 struct default_converter
<char const*>
853 typedef boost::mpl::true_ is_native
;
856 static int match(lua_State
* L
, U
, int index
)
858 return lua_type(L
, index
) == LUA_TSTRING
? 0 : -1;
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
);
873 void converter_postcall(lua_State
*, U
, int)
878 struct default_converter
<const char* const>
879 : default_converter
<char const*>
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*>
900 struct default_policy
: converter_policy_tag
902 BOOST_STATIC_CONSTANT(bool, has_arg
= true);
905 static void precall(lua_State
*, T
, int) {}
907 template<class T
, class Direction
>
910 typedef default_converter
<T
> type
;
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
>
929 typedef typename find_conversion_policy
<N
, typename
Policies::tail
>::type type
;
934 struct find_conversion_impl
<true>
936 template<int N
, class Policies
>
939 typedef typename
Policies::head head
;
940 typedef typename
Policies::tail tail
;
942 BOOST_STATIC_CONSTANT(bool, found
= (N
== head::index
));
945 boost::mpl::if_c
<found
947 , typename find_conversion_policy
<N
, tail
>::type
952 template<class Policies
>
953 struct find_conversion_impl2
957 : find_conversion_impl
<
958 boost::is_base_and_derived
<conversion_policy_base
, typename
Policies::head
>::value
959 >::template apply
<N
, Policies
>
965 struct find_conversion_impl2
<detail::null_type
>
970 typedef default_policy type
;
974 template<int N
, class Policies
>
975 struct find_conversion_policy
: find_conversion_impl2
<Policies
>::template apply
<N
>
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
);
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
);
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
);
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>
1063 boost::arg
<0> return_value
;
1064 boost::arg
<0> result
;
1065 # define LUABIND_PLACEHOLDER_ARG(N) boost::arg<N>
1069 #endif // LUABIND_POLICY_HPP_INCLUDED