1 // Copyright (c) 2005 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.
23 #ifndef LUABIND_OBJECT_050419_HPP
24 #define LUABIND_OBJECT_050419_HPP
26 #include <boost/implicit_cast.hpp> // detail::push()
27 #include <boost/ref.hpp> // detail::push()
28 #include <boost/mpl/bool.hpp> // value_wrapper_traits specializations
29 #include <boost/mpl/apply_wrap.hpp>
33 # include <boost/tuple/tuple.hpp>
35 #include <boost/optional.hpp>
37 #include <luabind/nil.hpp>
38 #include <luabind/value_wrapper.hpp>
39 #include <luabind/detail/pcall.hpp>
40 #include <luabind/handle.hpp>
41 #include <luabind/from_stack.hpp>
42 #include <luabind/detail/policy.hpp>
43 #include <luabind/detail/stack_utils.hpp>
44 #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
45 #include <luabind/typeid.hpp>
47 #include <boost/iterator/iterator_facade.hpp> // iterator
50 #include <boost/preprocessor/iteration/iterate.hpp>
52 #include <boost/utility/enable_if.hpp>
58 namespace mpl
= boost::mpl
;
60 template<class T
, class ConverterGenerator
>
61 void push_aux(lua_State
* interpreter
, T
& value
, ConverterGenerator
*)
63 typedef typename
boost::mpl::if_
<
64 boost::is_reference_wrapper
<T
>
65 , BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
67 >::type unwrapped_type
;
69 typename
mpl::apply_wrap2
<
70 ConverterGenerator
,unwrapped_type
,cpp_to_lua
75 , boost::implicit_cast
<
76 BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
81 template<class T
, class Policies
>
82 void push(lua_State
* interpreter
, T
& value
, Policies
const&)
84 typedef typename find_conversion_policy
<
87 >::type converter_policy
;
89 push_aux(interpreter
, value
, (converter_policy
*)0);
93 void push(lua_State
* interpreter
, T
& value
)
95 push(interpreter
, value
, null_type());
102 namespace mpl
= boost::mpl
;
105 class object_interface
;
107 namespace is_object_interface_aux
109 typedef char (&yes
)[1];
110 typedef char (&no
)[2];
113 yes
check(object_interface
<T
>*);
119 BOOST_STATIC_CONSTANT(bool, value
=
120 sizeof(is_object_interface_aux::check((T
*)0)) == sizeof(yes
)
123 typedef mpl::bool_
<value
> type
;
126 } // namespace detail
129 struct is_object_interface
130 : is_object_interface_aux::impl
<T
>::type
133 template <class R
, class T
, class U
>
135 # ifndef BOOST_NO_SFINAE
138 is_object_interface
<T
>
139 , is_object_interface
<U
>
150 template<class T
, class U
>
151 int binary_interpreter(lua_State
*& L
, T
const& lhs
, U
const& rhs
152 , boost::mpl::true_
, boost::mpl::true_
)
154 L
= value_wrapper_traits
<T
>::interpreter(lhs
);
155 lua_State
* L2
= value_wrapper_traits
<U
>::interpreter(rhs
);
157 // you are comparing objects with different interpreters
158 // that's not allowed.
159 assert(L
== L2
|| L
== 0 || L2
== 0);
161 // if the two objects we compare have different interpreters
164 if (L
!= L2
) return -1;
165 if (L
== 0) return 1;
169 template<class T
, class U
>
170 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const&
171 , boost::mpl::true_
, boost::mpl::false_
)
173 L
= value_wrapper_traits
<T
>::interpreter(x
);
177 template<class T
, class U
>
178 int binary_interpreter(lua_State
*& L
, T
const&, U
const& x
, boost::mpl::false_
, boost::mpl::true_
)
180 L
= value_wrapper_traits
<U
>::interpreter(x
);
184 template<class T
, class U
>
185 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const& y
)
187 return binary_interpreter(
191 , is_value_wrapper
<T
>()
192 , is_value_wrapper
<U
>()
196 #define LUABIND_BINARY_OP_DEF(op, fn) \
197 template<class LHS, class RHS> \
198 typename enable_binary<bool,LHS,RHS>::type \
199 operator op(LHS const& lhs, RHS const& rhs) \
202 switch (binary_interpreter(L, lhs, rhs)) \
212 detail::stack_pop pop1(L, 1); \
213 detail::push(L, lhs); \
214 detail::stack_pop pop2(L, 1); \
215 detail::push(L, rhs); \
217 return fn(L, -1, -2) != 0; \
220 LUABIND_BINARY_OP_DEF(==, lua_equal
)
221 LUABIND_BINARY_OP_DEF(<, lua_lessthan
)
223 template<class ValueWrapper
>
224 std::ostream
& operator<<(std::ostream
& os
225 , object_interface
<ValueWrapper
> const& v
)
227 using namespace luabind
;
228 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
229 static_cast<ValueWrapper
const&>(v
));
230 detail::stack_pop
pop(interpreter
, 1);
231 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
232 , static_cast<ValueWrapper
const&>(v
));
233 char const* p
= lua_tostring(interpreter
, -1);
234 std::size_t len
= lua_strlen(interpreter
, -1);
235 std::copy(p
, p
+ len
, std::ostream_iterator
<char>(os
));
239 #undef LUABIND_BINARY_OP_DEF
241 template<class LHS
, class RHS
>
242 typename enable_binary
<bool,LHS
,RHS
>::type
243 operator>(LHS
const& lhs
, RHS
const& rhs
)
245 return !(lhs
< rhs
|| lhs
== rhs
);
248 template<class LHS
, class RHS
>
249 typename enable_binary
<bool,LHS
,RHS
>::type
250 operator<=(LHS
const& lhs
, RHS
const& rhs
)
252 return lhs
< rhs
|| lhs
== rhs
;
255 template<class LHS
, class RHS
>
256 typename enable_binary
<bool,LHS
,RHS
>::type
257 operator>=(LHS
const& lhs
, RHS
const& rhs
)
262 template<class LHS
, class RHS
>
263 typename enable_binary
<bool,LHS
,RHS
>::type
264 operator!=(LHS
const& lhs
, RHS
const& rhs
)
266 return !(lhs
== rhs
);
269 template<class ValueWrapper
, class Arguments
>
277 template<class Derived
>
278 class object_interface
280 struct safe_bool_type
{};
282 ~object_interface() {}
284 # ifdef LUABIND_CPP0x
286 template <class... Args
>
288 Derived
, std::tuple
<Args
const*...>
289 > operator()(Args
const& ...args
)
291 typedef std::tuple
<Args
const*...> arguments
;
292 return call_proxy
<Derived
, arguments
>(derived(), arguments(&args
...));
297 call_proxy
<Derived
, boost::tuples::tuple
<> > operator()();
302 , boost::tuples::tuple
<A0
const*>
303 > operator()(A0
const& a0
)
305 typedef boost::tuples::tuple
<A0
const*> arguments
;
307 return call_proxy
<Derived
, arguments
>(
313 template<class A0
, class A1
>
316 , boost::tuples::tuple
<A0
const*, A1
const*>
317 > operator()(A0
const& a0
, A1
const& a1
)
319 typedef boost::tuples::tuple
<A0
const*, A1
const*> arguments
;
321 return call_proxy
<Derived
, arguments
>(
323 , arguments(&a0
, &a1
)
327 // The rest of the overloads are PP-generated.
328 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
329 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
330 #include BOOST_PP_ITERATE()
332 # endif // LUABIND_CPP0x
334 operator safe_bool_type
*() const
336 lua_State
* L
= value_wrapper_traits
<Derived
>::interpreter(derived());
341 value_wrapper_traits
<Derived
>::unwrap(L
, derived());
342 detail::stack_pop
pop(L
, 1);
344 return lua_toboolean(L
, -1) == 1 ? (safe_bool_type
*)1 : 0;
350 return *static_cast<Derived
*>(this);
353 Derived
const& derived() const
355 return *static_cast<Derived
const*>(this);
359 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
360 struct iterator_proxy_tag
;
363 template<class AccessPolicy
>
365 : public object_interface
<iterator_proxy
<AccessPolicy
> >
368 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
369 typedef iterator_proxy_tag value_wrapper_tag
;
372 iterator_proxy(lua_State
* interpreter
, handle
const& table
, handle
const& key
)
373 : m_interpreter(interpreter
)
374 , m_table_index(lua_gettop(interpreter
) + 1)
375 , m_key_index(m_table_index
+ 1)
377 table
.push(m_interpreter
);
378 key
.push(m_interpreter
);
381 iterator_proxy(iterator_proxy
const& other
)
382 : m_interpreter(other
.m_interpreter
)
383 , m_table_index(other
.m_table_index
)
384 , m_key_index(other
.m_key_index
)
386 other
.m_interpreter
= 0;
392 lua_pop(m_interpreter
, 2);
395 // this will set the value to nil
396 iterator_proxy
& operator=(luabind::detail::nil_type
)
398 lua_pushvalue(m_interpreter
, m_key_index
);
399 lua_pushnil(m_interpreter
);
400 AccessPolicy::set(m_interpreter
, m_table_index
);
405 iterator_proxy
& operator=(T
const& value
)
407 lua_pushvalue(m_interpreter
, m_key_index
);
408 detail::push(m_interpreter
, value
);
409 AccessPolicy::set(m_interpreter
, m_table_index
);
414 index_proxy
<iterator_proxy
<AccessPolicy
> > operator[](Key
const& key
)
416 return index_proxy
<iterator_proxy
<AccessPolicy
> >(
417 *this, m_interpreter
, key
421 // This is non-const to prevent conversion on lvalues.
424 lua_State
* interpreter() const
426 return m_interpreter
;
429 // TODO: Why is it non-const?
430 void push(lua_State
* interpreter
)
432 assert(interpreter
== m_interpreter
);
433 lua_pushvalue(m_interpreter
, m_key_index
);
434 AccessPolicy::get(m_interpreter
, m_table_index
);
438 mutable lua_State
* m_interpreter
;
449 static void set(lua_State
* interpreter
, int table
)
451 lua_settable(interpreter
, table
);
454 static void get(lua_State
* interpreter
, int table
)
456 lua_gettable(interpreter
, table
);
462 static void set(lua_State
* interpreter
, int table
)
464 lua_rawset(interpreter
, table
);
467 static void get(lua_State
* interpreter
, int table
)
469 lua_rawget(interpreter
, table
);
473 template<class AccessPolicy
>
475 : public boost::iterator_facade
<
476 basic_iterator
<AccessPolicy
>
477 , adl::iterator_proxy
<AccessPolicy
>
478 , boost::single_pass_traversal_tag
479 , adl::iterator_proxy
<AccessPolicy
>
487 template<class ValueWrapper
>
488 explicit basic_iterator(ValueWrapper
const& value_wrapper
)
490 value_wrapper_traits
<ValueWrapper
>::interpreter(value_wrapper
)
493 detail::stack_pop
pop(m_interpreter
, 1);
494 value_wrapper_traits
<ValueWrapper
>::unwrap(m_interpreter
, value_wrapper
);
496 lua_pushnil(m_interpreter
);
497 if (lua_next(m_interpreter
, -2) != 0)
499 detail::stack_pop
pop(m_interpreter
, 2);
500 handle(m_interpreter
, -2).swap(m_key
);
508 handle(m_interpreter
, -1).swap(m_table
);
511 adl::object
key() const;
514 friend class boost::iterator_core_access
;
518 m_table
.push(m_interpreter
);
519 m_key
.push(m_interpreter
);
521 detail::stack_pop
pop(m_interpreter
, 1);
523 if (lua_next(m_interpreter
, -2) != 0)
525 m_key
.replace(m_interpreter
, -2);
526 lua_pop(m_interpreter
, 2);
531 handle().swap(m_table
);
532 handle().swap(m_key
);
536 bool equal(basic_iterator
const& other
) const
538 if (m_interpreter
== 0 && other
.m_interpreter
== 0)
541 if (m_interpreter
!= other
.m_interpreter
)
544 detail::stack_pop
pop(m_interpreter
, 2);
545 m_key
.push(m_interpreter
);
546 other
.m_key
.push(m_interpreter
);
547 return lua_equal(m_interpreter
, -2, -1) != 0;
550 adl::iterator_proxy
<AccessPolicy
> dereference() const
552 return adl::iterator_proxy
<AccessPolicy
>(m_interpreter
, m_table
, m_key
);
555 lua_State
* m_interpreter
;
560 // Needed because of some strange ADL issues.
562 #define LUABIND_OPERATOR_ADL_WKND(op) \
563 inline bool operator op( \
564 basic_iterator<basic_access> const& x \
565 , basic_iterator<basic_access> const& y) \
567 return boost::operator op(x, y); \
570 inline bool operator op( \
571 basic_iterator<raw_access> const& x \
572 , basic_iterator<raw_access> const& y) \
574 return boost::operator op(x, y); \
577 LUABIND_OPERATOR_ADL_WKND(==)
578 LUABIND_OPERATOR_ADL_WKND(!=)
580 #undef LUABIND_OPERATOR_ADL_WKND
582 } // namespace detail
587 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
588 struct index_proxy_tag
;
593 : public object_interface
<index_proxy
<Next
> >
596 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
597 typedef index_proxy_tag value_wrapper_tag
;
600 typedef index_proxy
<Next
> this_type
;
603 index_proxy(Next
const& next
, lua_State
* interpreter
, Key
const& key
)
604 : m_interpreter(interpreter
)
605 , m_key_index(lua_gettop(interpreter
) + 1)
608 detail::push(m_interpreter
, key
);
611 index_proxy(index_proxy
const& other
)
612 : m_interpreter(other
.m_interpreter
)
613 , m_key_index(other
.m_key_index
)
614 , m_next(other
.m_next
)
616 other
.m_interpreter
= 0;
622 lua_pop(m_interpreter
, 1);
625 // This is non-const to prevent conversion on lvalues.
628 // this will set the value to nil
629 this_type
& operator=(luabind::detail::nil_type
)
631 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
632 detail::stack_pop
pop(m_interpreter
, 1);
634 lua_pushvalue(m_interpreter
, m_key_index
);
635 lua_pushnil(m_interpreter
);
636 lua_settable(m_interpreter
, -3);
641 this_type
& operator=(T
const& value
)
643 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
644 detail::stack_pop
pop(m_interpreter
, 1);
646 lua_pushvalue(m_interpreter
, m_key_index
);
647 detail::push(m_interpreter
, value
);
648 lua_settable(m_interpreter
, -3);
652 this_type
& operator=(this_type
const& value
)
654 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
655 detail::stack_pop
pop(m_interpreter
, 1);
657 lua_pushvalue(m_interpreter
, m_key_index
);
658 detail::push(m_interpreter
, value
);
659 lua_settable(m_interpreter
, -3);
664 index_proxy
<this_type
> operator[](T
const& key
)
666 return index_proxy
<this_type
>(*this, m_interpreter
, key
);
669 void push(lua_State
* interpreter
);
671 lua_State
* interpreter() const
673 return m_interpreter
;
677 struct hidden_type
{};
679 // this_type& operator=(index_proxy<Next> const&);
681 mutable lua_State
* m_interpreter
;
689 typedef detail::basic_iterator
<detail::basic_access
> iterator
;
690 typedef detail::basic_iterator
<detail::raw_access
> raw_iterator
;
692 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
694 struct value_wrapper_traits
<adl::index_proxy
<T
> >
697 struct value_wrapper_traits
<adl::index_proxy_tag
>
700 typedef boost::mpl::true_ is_specialized
;
703 static lua_State
* interpreter(adl::index_proxy
<Next
> const& proxy
)
705 return proxy
.interpreter();
709 static void unwrap(lua_State
* interpreter
, adl::index_proxy
<Next
> const& proxy
)
711 const_cast<adl::index_proxy
<Next
>&>(proxy
).push(interpreter
);
715 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
716 template<class AccessPolicy
>
717 struct value_wrapper_traits
<adl::iterator_proxy
<AccessPolicy
> >
720 struct value_wrapper_traits
<adl::iterator_proxy_tag
>
723 typedef boost::mpl::true_ is_specialized
;
725 template<class Proxy
>
726 static lua_State
* interpreter(Proxy
const& p
)
728 return p
.interpreter();
731 template<class Proxy
>
732 static void unwrap(lua_State
* interpreter
, Proxy
const& p
)
734 // TODO: Why const_cast?
735 const_cast<Proxy
&>(p
).push(interpreter
);
742 // An object holds a reference to a Lua value residing
744 class object
: public object_interface
<object
>
750 explicit object(handle
const& other
)
754 explicit object(from_stack
const& stack_reference
)
755 : m_handle(stack_reference
.interpreter
, stack_reference
.index
)
760 object(lua_State
* interpreter
, T
const& value
)
762 detail::push(interpreter
, value
);
763 detail::stack_pop
pop(interpreter
, 1);
764 handle(interpreter
, -1).swap(m_handle
);
767 template<class T
, class Policies
>
768 object(lua_State
* interpreter
, T
const& value
, Policies
const&)
770 detail::push(interpreter
, value
, Policies());
771 detail::stack_pop
pop(interpreter
, 1);
772 handle(interpreter
, -1).swap(m_handle
);
775 void push(lua_State
* interpreter
) const;
776 lua_State
* interpreter() const;
777 bool is_valid() const;
780 index_proxy
<object
> operator[](T
const& key
) const
782 return index_proxy
<object
>(
783 *this, m_handle
.interpreter(), key
787 void swap(object
& other
)
789 m_handle
.swap(other
.m_handle
);
796 inline void object::push(lua_State
* interpreter
) const
798 m_handle
.push(interpreter
);
801 inline lua_State
* object::interpreter() const
803 return m_handle
.interpreter();
806 inline bool object::is_valid() const
808 return m_handle
.interpreter() != 0;
811 class argument
: public object_interface
<argument
>
814 argument(from_stack
const& stack_reference
)
815 : m_interpreter(stack_reference
.interpreter
)
816 , m_index(stack_reference
.index
)
819 m_index
= lua_gettop(m_interpreter
) - m_index
+ 1;
823 index_proxy
<argument
> operator[](T
const& key
) const
825 return index_proxy
<argument
>(*this, m_interpreter
, key
);
828 void push(lua_State
* L
) const
830 lua_pushvalue(L
, m_index
);
833 lua_State
* interpreter() const
835 return m_interpreter
;
839 lua_State
* m_interpreter
;
848 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
849 template <class ValueWrapper
, class Arguments
>
850 struct value_wrapper_traits
<adl::call_proxy
<ValueWrapper
, Arguments
> >
853 struct value_wrapper_traits
<adl::call_proxy_tag
>
856 typedef boost::mpl::true_ is_specialized
;
858 template<class W
, class A
>
859 static lua_State
* interpreter(adl::call_proxy
<W
,A
> const& proxy
)
861 return value_wrapper_traits
<W
>::interpreter(*proxy
.value_wrapper
);
864 template<class W
, class A
>
865 static void unwrap(lua_State
*, adl::call_proxy
<W
,A
> const& proxy
)
867 object result
= const_cast<adl::call_proxy
<W
,A
>&>(proxy
);
868 result
.push(result
.interpreter());
873 struct value_wrapper_traits
<object
>
875 typedef boost::mpl::true_ is_specialized
;
877 static lua_State
* interpreter(object
const& value
)
879 return value
.interpreter();
882 static void unwrap(lua_State
* interpreter
, object
const& value
)
884 value
.push(interpreter
);
887 static bool check(...)
894 struct value_wrapper_traits
<argument
>
896 typedef boost::mpl::true_ is_specialized
;
898 static lua_State
* interpreter(argument
const& value
)
900 return value
.interpreter();
903 static void unwrap(lua_State
* interpreter
, argument
const& value
)
905 value
.push(interpreter
);
908 static bool check(...)
915 inline void adl::index_proxy
<Next
>::push(lua_State
* interpreter
)
917 assert(interpreter
== m_interpreter
);
919 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
921 lua_pushvalue(m_interpreter
, m_key_index
);
922 lua_gettable(m_interpreter
, -2);
923 lua_remove(m_interpreter
, -2);
927 inline adl::index_proxy
<Next
>::operator object()
929 detail::stack_pop
pop(m_interpreter
, 1);
931 return object(from_stack(m_interpreter
, -1));
934 template<class AccessPolicy
>
935 adl::iterator_proxy
<AccessPolicy
>::operator object()
937 lua_pushvalue(m_interpreter
, m_key_index
);
938 AccessPolicy::get(m_interpreter
, m_table_index
);
939 detail::stack_pop
pop(m_interpreter
, 1);
940 return object(from_stack(m_interpreter
, -1));
943 template<class AccessPolicy
>
944 object
detail::basic_iterator
<AccessPolicy
>::key() const
946 return object(m_key
);
959 ReturnType
object_cast_aux(
960 ValueWrapper
const& value_wrapper
967 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
971 #ifndef LUABIND_NO_ERROR_CHECKING
973 return ErrorPolicy::handle_error(interpreter
, typeid(void));
976 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value_wrapper
);
978 detail::stack_pop
pop(interpreter
, 1);
980 typedef typename
detail::find_conversion_policy
<
983 >::type converter_generator
;
985 typename
mpl::apply_wrap2
<converter_generator
, T
, lua_to_cpp
>::type cv
;
987 if (cv
.match(interpreter
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
989 return ErrorPolicy::handle_error(interpreter
, typeid(T
));
992 return cv
.apply(interpreter
, LUABIND_DECORATE_TYPE(T
), -1);
996 # pragma warning(push)
997 # pragma warning(disable:4702) // unreachable code
1001 struct throw_error_policy
1003 static T
handle_error(lua_State
* interpreter
, type_id
const& type_info
)
1005 #ifndef LUABIND_NO_EXCEPTIONS
1006 throw cast_failed(interpreter
, type_info
);
1008 cast_failed_callback_fun e
= get_cast_failed_callback();
1009 if (e
) e(interpreter
, type_info
);
1011 assert(0 && "object_cast failed. If you want to handle this error use "
1012 "luabind::set_error_callback()");
1015 return *(typename
boost::remove_reference
<T
>::type
*)0;
1020 # pragma warning(pop)
1024 struct nothrow_error_policy
1026 static boost::optional
<T
> handle_error(lua_State
*, type_id
const&)
1028 return boost::optional
<T
>();
1032 } // namespace detail
1034 template<class T
, class ValueWrapper
>
1035 T
object_cast(ValueWrapper
const& value_wrapper
)
1037 return detail::object_cast_aux(
1040 , (detail::null_type
*)0
1041 , (detail::throw_error_policy
<T
>*)0
1046 template<class T
, class ValueWrapper
, class Policies
>
1047 T
object_cast(ValueWrapper
const& value_wrapper
, Policies
const&)
1049 return detail::object_cast_aux(
1053 , (detail::throw_error_policy
<T
>*)0
1058 template<class T
, class ValueWrapper
>
1059 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
)
1061 return detail::object_cast_aux(
1064 , (detail::null_type
*)0
1065 , (detail::nothrow_error_policy
<T
>*)0
1066 , (boost::optional
<T
>*)0
1070 template<class T
, class ValueWrapper
, class Policies
>
1071 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
, Policies
const&)
1073 return detail::object_cast_aux(
1077 , (detail::nothrow_error_policy
<T
>*)0
1078 , (boost::optional
<T
>*)0
1086 struct push_args_from_tuple
1088 # ifdef LUABIND_CPP0x
1090 template <class Args
, class Policies
, class N
, class E
>
1091 static void push_args(
1092 lua_State
* L
, Args
const& args
, Policies
const& policies
, N
, E
)
1094 convert_to_lua_p
<N::value
+ 1>(L
, *std::get
<N::value
>(args
), policies
);
1096 L
, args
, policies
, std::integral_constant
<int, N::value
+ 1>(), E());
1099 template <class Args
, class Policies
, class E
>
1100 static void push_args(lua_State
* L
, Args
const&, Policies
const&, E
, E
)
1103 template <class... Args
, class Policies
= null_type
>
1105 lua_State
* L
, std::tuple
<Args
...> const& args
1106 , Policies
const policies
= Policies())
1112 , std::integral_constant
<int, 0>()
1113 , std::integral_constant
<int, sizeof...(Args
)>()
1117 # else // LUABIND_CPP0x
1119 template<class H
, class T
, class Policies
>
1120 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
, const Policies
& p
)
1122 convert_to_lua_p
<Index
>(L
, *x
.get_head(), p
);
1123 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail(), p
);
1126 template<class H
, class T
>
1127 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
)
1129 convert_to_lua(L
, *x
.get_head());
1130 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail());
1133 template<class Policies
>
1134 inline static void apply(lua_State
*, const boost::tuples::null_type
&, const Policies
&) {}
1136 inline static void apply(lua_State
*, const boost::tuples::null_type
&) {}
1138 # endif // LUABIND_CPP0x
1141 } // namespace detail
1146 template<class ValueWrapper
, class Arguments
>
1149 call_proxy(ValueWrapper
& value_wrapper
, Arguments arguments
)
1150 : value_wrapper(&value_wrapper
)
1151 , arguments(arguments
)
1154 call_proxy(call_proxy
const& other
)
1155 : value_wrapper(other
.value_wrapper
)
1156 , arguments(other
.arguments
)
1158 other
.value_wrapper
= 0;
1164 call((detail::null_type
*)0);
1169 return call((detail::null_type
*)0);
1172 template<class Policies
>
1173 object
operator[](Policies
const&)
1175 return call((Policies
*)0);
1178 template<class Policies
>
1179 object
call(Policies
*)
1181 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1185 value_wrapper_traits
<ValueWrapper
>::unwrap(
1192 detail::push_args_from_tuple
<1>::apply(interpreter
, arguments
, Policies());
1194 # ifdef LUABIND_CPP0x
1195 if (detail::pcall(interpreter
, std::tuple_size
<Arguments
>::value
, 1))
1197 if (detail::pcall(interpreter
, boost::tuples::length
<Arguments
>::value
, 1))
1200 #ifndef LUABIND_NO_EXCEPTIONS
1201 throw luabind::error(interpreter
);
1203 error_callback_fun e
= get_error_callback();
1204 if (e
) e(interpreter
);
1206 assert(0 && "the lua function threw an error and exceptions are disabled."
1207 "if you want to handle this error use luabind::set_error_callback()");
1212 detail::stack_pop
pop(interpreter
, 1);
1213 return object(from_stack(interpreter
, -1));
1216 mutable ValueWrapper
* value_wrapper
;
1217 Arguments arguments
;
1220 # ifndef LUABIND_CPP0x
1222 template<class Derived
>
1223 call_proxy
<Derived
, boost::tuples::tuple
<> >
1224 object_interface
<Derived
>::operator()()
1226 return call_proxy
<Derived
, boost::tuples::tuple
<> >(
1228 , boost::tuples::tuple
<>()
1234 // Simple value_wrapper adaptor with the sole purpose of helping with
1235 // overload resolution. Use this as a function parameter type instead
1236 // of "object" or "argument" to restrict the parameter to Lua tables.
1237 template <class Base
= object
>
1240 table(from_stack
const& stack_reference
)
1241 : Base(stack_reference
)
1249 template <class Base
>
1250 struct value_wrapper_traits
<adl::table
<Base
> >
1251 : value_wrapper_traits
<Base
>
1253 static bool check(lua_State
* L
, int idx
)
1255 return value_wrapper_traits
<Base
>::check(L
, idx
) &&
1256 lua_istable(L
, idx
);
1260 inline object
newtable(lua_State
* interpreter
)
1262 lua_newtable(interpreter
);
1263 detail::stack_pop
pop(interpreter
, 1);
1264 return object(from_stack(interpreter
, -1));
1267 // this could be optimized by returning a proxy
1268 inline object
globals(lua_State
* interpreter
)
1270 lua_pushvalue(interpreter
, LUA_GLOBALSINDEX
);
1271 detail::stack_pop
pop(interpreter
, 1);
1272 return object(from_stack(interpreter
, -1));
1275 // this could be optimized by returning a proxy
1276 inline object
registry(lua_State
* interpreter
)
1278 lua_pushvalue(interpreter
, LUA_REGISTRYINDEX
);
1279 detail::stack_pop
pop(interpreter
, 1);
1280 return object(from_stack(interpreter
, -1));
1283 template<class ValueWrapper
, class K
>
1284 inline object
gettable(ValueWrapper
const& table
, K
const& key
)
1286 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1290 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1291 detail::stack_pop
pop(interpreter
, 2);
1292 detail::push(interpreter
, key
);
1293 lua_gettable(interpreter
, -2);
1294 return object(from_stack(interpreter
, -1));
1297 template<class ValueWrapper
, class K
, class T
>
1298 inline void settable(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1300 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1304 // TODO: Exception safe?
1306 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1307 detail::stack_pop
pop(interpreter
, 1);
1308 detail::push(interpreter
, key
);
1309 detail::push(interpreter
, value
);
1310 lua_settable(interpreter
, -3);
1313 template<class ValueWrapper
, class K
>
1314 inline object
rawget(ValueWrapper
const& table
, K
const& key
)
1316 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1320 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1321 detail::stack_pop
pop(interpreter
, 2);
1322 detail::push(interpreter
, key
);
1323 lua_rawget(interpreter
, -2);
1324 return object(from_stack(interpreter
, -1));
1327 template<class ValueWrapper
, class K
, class T
>
1328 inline void rawset(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1330 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1334 // TODO: Exception safe?
1336 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1337 detail::stack_pop
pop(interpreter
, 1);
1338 detail::push(interpreter
, key
);
1339 detail::push(interpreter
, value
);
1340 lua_rawset(interpreter
, -3);
1343 template<class ValueWrapper
>
1344 inline int type(ValueWrapper
const& value
)
1346 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1350 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1351 detail::stack_pop
pop(interpreter
, 1);
1352 return lua_type(interpreter
, -1);
1355 template <class ValueWrapper
>
1356 inline object
getmetatable(ValueWrapper
const& obj
)
1358 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1362 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, obj
);
1363 detail::stack_pop
pop(interpreter
, 2);
1364 lua_getmetatable(interpreter
, -1);
1365 return object(from_stack(interpreter
, -1));
1368 template <class ValueWrapper1
, class ValueWrapper2
>
1369 inline void setmetatable(
1370 ValueWrapper1
const& obj
, ValueWrapper2
const& metatable
)
1372 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1376 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, obj
);
1377 detail::stack_pop
pop(interpreter
, 1);
1378 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, metatable
);
1379 lua_setmetatable(interpreter
, -2);
1382 template <class ValueWrapper
>
1383 inline lua_CFunction
tocfunction(ValueWrapper
const& value
)
1385 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1389 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1390 detail::stack_pop
pop(interpreter
, 1);
1391 return lua_tocfunction(interpreter
, -1);
1394 template <class T
, class ValueWrapper
>
1395 inline T
* touserdata(ValueWrapper
const& value
)
1397 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1401 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1402 detail::stack_pop
pop(interpreter
, 1);
1403 return static_cast<T
*>(lua_touserdata(interpreter
, -1));
1406 template <class ValueWrapper
>
1407 inline object
getupvalue(ValueWrapper
const& value
, int index
)
1409 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1413 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1414 detail::stack_pop
pop(interpreter
, 2);
1415 lua_getupvalue(interpreter
, -1, index
);
1416 return object(from_stack(interpreter
, -1));
1419 template <class ValueWrapper1
, class ValueWrapper2
>
1420 inline void setupvalue(
1421 ValueWrapper1
const& function
, int index
, ValueWrapper2
const& value
)
1423 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1427 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, function
);
1428 detail::stack_pop
pop(interpreter
, 1);
1429 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, value
);
1430 lua_setupvalue(interpreter
, -2, index
);
1433 template <class GetValueWrapper
>
1434 object
property(GetValueWrapper
const& get
)
1436 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1440 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1441 lua_pushnil(interpreter
);
1443 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1444 detail::stack_pop
pop(interpreter
, 1);
1446 return object(from_stack(interpreter
, -1));
1449 template <class GetValueWrapper
, class SetValueWrapper
>
1450 object
property(GetValueWrapper
const& get
, SetValueWrapper
const& set
)
1452 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1456 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1457 value_wrapper_traits
<SetValueWrapper
>::unwrap(interpreter
, set
);
1459 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1460 detail::stack_pop
pop(interpreter
, 1);
1462 return object(from_stack(interpreter
, -1));
1467 } // namespace luabind
1469 #endif // LUABIND_OBJECT_050419_HPP