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>
30 #include <boost/tuple/tuple.hpp>
31 #include <boost/optional.hpp>
33 #include <luabind/nil.hpp>
34 #include <luabind/value_wrapper.hpp>
35 #include <luabind/detail/pcall.hpp>
36 #include <luabind/handle.hpp>
37 #include <luabind/from_stack.hpp>
38 #include <luabind/detail/policy.hpp>
39 #include <luabind/detail/stack_utils.hpp>
40 #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
41 #include <luabind/typeid.hpp>
43 #include <boost/iterator/iterator_facade.hpp> // iterator
46 #include <boost/preprocessor/iteration/iterate.hpp>
48 #include <boost/utility/enable_if.hpp>
54 namespace mpl
= boost::mpl
;
56 template<class T
, class ConverterGenerator
>
57 void push_aux(lua_State
* interpreter
, T
& value
, ConverterGenerator
*)
59 typedef typename
boost::mpl::if_
<
60 boost::is_reference_wrapper
<T
>
61 , BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
63 >::type unwrapped_type
;
65 typename
mpl::apply_wrap2
<
66 ConverterGenerator
,unwrapped_type
,cpp_to_lua
71 , boost::implicit_cast
<
72 BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
77 template<class T
, class Policies
>
78 void push(lua_State
* interpreter
, T
& value
, Policies
const&)
80 typedef typename find_conversion_policy
<
83 >::type converter_policy
;
85 push_aux(interpreter
, value
, (converter_policy
*)0);
89 void push(lua_State
* interpreter
, T
& value
)
91 push(interpreter
, value
, null_type());
98 namespace mpl
= boost::mpl
;
101 class object_interface
;
103 namespace is_object_interface_aux
105 typedef char (&yes
)[1];
106 typedef char (&no
)[2];
109 yes
check(object_interface
<T
>*);
115 BOOST_STATIC_CONSTANT(bool, value
=
116 sizeof(is_object_interface_aux::check((T
*)0)) == sizeof(yes
)
119 typedef mpl::bool_
<value
> type
;
122 } // namespace detail
125 struct is_object_interface
126 : is_object_interface_aux::impl
<T
>::type
129 template <class R
, class T
, class U
>
131 # ifndef BOOST_NO_SFINAE
134 is_object_interface
<T
>
135 , is_object_interface
<U
>
146 template<class T
, class U
>
147 int binary_interpreter(lua_State
*& L
, T
const& lhs
, U
const& rhs
148 , boost::mpl::true_
, boost::mpl::true_
)
150 L
= value_wrapper_traits
<T
>::interpreter(lhs
);
151 lua_State
* L2
= value_wrapper_traits
<U
>::interpreter(rhs
);
153 // you are comparing objects with different interpreters
154 // that's not allowed.
155 assert(L
== L2
|| L
== 0 || L2
== 0);
157 // if the two objects we compare have different interpreters
160 if (L
!= L2
) return -1;
161 if (L
== 0) return 1;
165 template<class T
, class U
>
166 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const&
167 , boost::mpl::true_
, boost::mpl::false_
)
169 L
= value_wrapper_traits
<T
>::interpreter(x
);
173 template<class T
, class U
>
174 int binary_interpreter(lua_State
*& L
, T
const&, U
const& x
, boost::mpl::false_
, boost::mpl::true_
)
176 L
= value_wrapper_traits
<U
>::interpreter(x
);
180 template<class T
, class U
>
181 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const& y
)
183 return binary_interpreter(
187 , is_value_wrapper
<T
>()
188 , is_value_wrapper
<U
>()
192 #define LUABIND_BINARY_OP_DEF(op, fn) \
193 template<class LHS, class RHS> \
194 typename enable_binary<bool,LHS,RHS>::type \
195 operator op(LHS const& lhs, RHS const& rhs) \
198 switch (binary_interpreter(L, lhs, rhs)) \
208 detail::stack_pop pop1(L, 1); \
209 detail::push(L, lhs); \
210 detail::stack_pop pop2(L, 1); \
211 detail::push(L, rhs); \
213 return fn(L, -1, -2) != 0; \
216 LUABIND_BINARY_OP_DEF(==, lua_equal
)
217 LUABIND_BINARY_OP_DEF(<, lua_lessthan
)
219 template<class ValueWrapper
>
220 std::ostream
& operator<<(std::ostream
& os
221 , object_interface
<ValueWrapper
> const& v
)
223 using namespace luabind
;
224 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
225 static_cast<ValueWrapper
const&>(v
));
226 detail::stack_pop
pop(interpreter
, 1);
227 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
228 , static_cast<ValueWrapper
const&>(v
));
229 char const* p
= lua_tostring(interpreter
, -1);
230 std::size_t len
= lua_strlen(interpreter
, -1);
231 std::copy(p
, p
+ len
, std::ostream_iterator
<char>(os
));
235 #undef LUABIND_BINARY_OP_DEF
237 template<class LHS
, class RHS
>
238 typename enable_binary
<bool,LHS
,RHS
>::type
239 operator>(LHS
const& lhs
, RHS
const& rhs
)
241 return !(lhs
< rhs
|| lhs
== rhs
);
244 template<class LHS
, class RHS
>
245 typename enable_binary
<bool,LHS
,RHS
>::type
246 operator<=(LHS
const& lhs
, RHS
const& rhs
)
248 return lhs
< rhs
|| lhs
== rhs
;
251 template<class LHS
, class RHS
>
252 typename enable_binary
<bool,LHS
,RHS
>::type
253 operator>=(LHS
const& lhs
, RHS
const& rhs
)
258 template<class LHS
, class RHS
>
259 typename enable_binary
<bool,LHS
,RHS
>::type
260 operator!=(LHS
const& lhs
, RHS
const& rhs
)
262 return !(lhs
== rhs
);
265 template<class ValueWrapper
, class Arguments
>
273 template<class Derived
>
274 class object_interface
276 struct safe_bool_type
{};
278 ~object_interface() {}
280 # ifdef LUABIND_CPP0x
282 template <class... Args
>
284 Derived
, std::tuple
<Args
const*...>
285 > operator()(Args
const& ...args
)
287 typedef std::tuple
<Args
const*...> arguments
;
288 return call_proxy
<Derived
, arguments
>(derived(), arguments(&args
...));
293 call_proxy
<Derived
, boost::tuples::tuple
<> > operator()();
298 , boost::tuples::tuple
<A0
const*>
299 > operator()(A0
const& a0
)
301 typedef boost::tuples::tuple
<A0
const*> arguments
;
303 return call_proxy
<Derived
, arguments
>(
309 template<class A0
, class A1
>
312 , boost::tuples::tuple
<A0
const*, A1
const*>
313 > operator()(A0
const& a0
, A1
const& a1
)
315 typedef boost::tuples::tuple
<A0
const*, A1
const*> arguments
;
317 return call_proxy
<Derived
, arguments
>(
319 , arguments(&a0
, &a1
)
323 // The rest of the overloads are PP-generated.
324 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
325 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
326 #include BOOST_PP_ITERATE()
328 # endif // LUABIND_CPP0x
330 operator safe_bool_type
*() const
332 lua_State
* L
= value_wrapper_traits
<Derived
>::interpreter(derived());
337 value_wrapper_traits
<Derived
>::unwrap(L
, derived());
338 detail::stack_pop
pop(L
, 1);
340 return lua_toboolean(L
, -1) == 1 ? (safe_bool_type
*)1 : 0;
346 return *static_cast<Derived
*>(this);
349 Derived
const& derived() const
351 return *static_cast<Derived
const*>(this);
355 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
356 struct iterator_proxy_tag
;
359 template<class AccessPolicy
>
361 : public object_interface
<iterator_proxy
<AccessPolicy
> >
364 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
365 typedef iterator_proxy_tag value_wrapper_tag
;
368 iterator_proxy(lua_State
* interpreter
, handle
const& table
, handle
const& key
)
369 : m_interpreter(interpreter
)
370 , m_table_index(lua_gettop(interpreter
) + 1)
371 , m_key_index(m_table_index
+ 1)
373 table
.push(m_interpreter
);
374 key
.push(m_interpreter
);
377 iterator_proxy(iterator_proxy
const& other
)
378 : m_interpreter(other
.m_interpreter
)
379 , m_table_index(other
.m_table_index
)
380 , m_key_index(other
.m_key_index
)
382 other
.m_interpreter
= 0;
388 lua_pop(m_interpreter
, 2);
391 // this will set the value to nil
392 iterator_proxy
& operator=(luabind::detail::nil_type
)
394 lua_pushvalue(m_interpreter
, m_key_index
);
395 lua_pushnil(m_interpreter
);
396 AccessPolicy::set(m_interpreter
, m_table_index
);
401 iterator_proxy
& operator=(T
const& value
)
403 lua_pushvalue(m_interpreter
, m_key_index
);
404 detail::push(m_interpreter
, value
);
405 AccessPolicy::set(m_interpreter
, m_table_index
);
410 index_proxy
<iterator_proxy
<AccessPolicy
> > operator[](Key
const& key
)
412 return index_proxy
<iterator_proxy
<AccessPolicy
> >(
413 *this, m_interpreter
, key
417 // This is non-const to prevent conversion on lvalues.
420 lua_State
* interpreter() const
422 return m_interpreter
;
425 // TODO: Why is it non-const?
426 void push(lua_State
* interpreter
)
428 assert(interpreter
== m_interpreter
);
429 lua_pushvalue(m_interpreter
, m_key_index
);
430 AccessPolicy::get(m_interpreter
, m_table_index
);
434 mutable lua_State
* m_interpreter
;
445 static void set(lua_State
* interpreter
, int table
)
447 lua_settable(interpreter
, table
);
450 static void get(lua_State
* interpreter
, int table
)
452 lua_gettable(interpreter
, table
);
458 static void set(lua_State
* interpreter
, int table
)
460 lua_rawset(interpreter
, table
);
463 static void get(lua_State
* interpreter
, int table
)
465 lua_rawget(interpreter
, table
);
469 template<class AccessPolicy
>
471 : public boost::iterator_facade
<
472 basic_iterator
<AccessPolicy
>
473 , adl::iterator_proxy
<AccessPolicy
>
474 , boost::single_pass_traversal_tag
475 , adl::iterator_proxy
<AccessPolicy
>
483 template<class ValueWrapper
>
484 explicit basic_iterator(ValueWrapper
const& value_wrapper
)
486 value_wrapper_traits
<ValueWrapper
>::interpreter(value_wrapper
)
489 detail::stack_pop
pop(m_interpreter
, 1);
490 value_wrapper_traits
<ValueWrapper
>::unwrap(m_interpreter
, value_wrapper
);
492 lua_pushnil(m_interpreter
);
493 if (lua_next(m_interpreter
, -2) != 0)
495 detail::stack_pop
pop(m_interpreter
, 2);
496 handle(m_interpreter
, -2).swap(m_key
);
504 handle(m_interpreter
, -1).swap(m_table
);
507 adl::object
key() const;
510 friend class boost::iterator_core_access
;
514 m_table
.push(m_interpreter
);
515 m_key
.push(m_interpreter
);
517 detail::stack_pop
pop(m_interpreter
, 1);
519 if (lua_next(m_interpreter
, -2) != 0)
521 m_key
.replace(m_interpreter
, -2);
522 lua_pop(m_interpreter
, 2);
527 handle().swap(m_table
);
528 handle().swap(m_key
);
532 bool equal(basic_iterator
const& other
) const
534 if (m_interpreter
== 0 && other
.m_interpreter
== 0)
537 if (m_interpreter
!= other
.m_interpreter
)
540 detail::stack_pop
pop(m_interpreter
, 2);
541 m_key
.push(m_interpreter
);
542 other
.m_key
.push(m_interpreter
);
543 return lua_equal(m_interpreter
, -2, -1) != 0;
546 adl::iterator_proxy
<AccessPolicy
> dereference() const
548 return adl::iterator_proxy
<AccessPolicy
>(m_interpreter
, m_table
, m_key
);
551 lua_State
* m_interpreter
;
556 // Needed because of some strange ADL issues.
558 #define LUABIND_OPERATOR_ADL_WKND(op) \
559 inline bool operator op( \
560 basic_iterator<basic_access> const& x \
561 , basic_iterator<basic_access> const& y) \
563 return boost::operator op(x, y); \
566 inline bool operator op( \
567 basic_iterator<raw_access> const& x \
568 , basic_iterator<raw_access> const& y) \
570 return boost::operator op(x, y); \
573 LUABIND_OPERATOR_ADL_WKND(==)
574 LUABIND_OPERATOR_ADL_WKND(!=)
576 #undef LUABIND_OPERATOR_ADL_WKND
578 } // namespace detail
583 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
584 struct index_proxy_tag
;
589 : public object_interface
<index_proxy
<Next
> >
592 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
593 typedef index_proxy_tag value_wrapper_tag
;
596 typedef index_proxy
<Next
> this_type
;
599 index_proxy(Next
const& next
, lua_State
* interpreter
, Key
const& key
)
600 : m_interpreter(interpreter
)
601 , m_key_index(lua_gettop(interpreter
) + 1)
604 detail::push(m_interpreter
, key
);
607 index_proxy(index_proxy
const& other
)
608 : m_interpreter(other
.m_interpreter
)
609 , m_key_index(other
.m_key_index
)
610 , m_next(other
.m_next
)
612 other
.m_interpreter
= 0;
618 lua_pop(m_interpreter
, 1);
621 // This is non-const to prevent conversion on lvalues.
624 // this will set the value to nil
625 this_type
& operator=(luabind::detail::nil_type
)
627 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
628 detail::stack_pop
pop(m_interpreter
, 1);
630 lua_pushvalue(m_interpreter
, m_key_index
);
631 lua_pushnil(m_interpreter
);
632 lua_settable(m_interpreter
, -3);
637 this_type
& operator=(T
const& value
)
639 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
640 detail::stack_pop
pop(m_interpreter
, 1);
642 lua_pushvalue(m_interpreter
, m_key_index
);
643 detail::push(m_interpreter
, value
);
644 lua_settable(m_interpreter
, -3);
648 this_type
& operator=(this_type
const& value
)
650 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
651 detail::stack_pop
pop(m_interpreter
, 1);
653 lua_pushvalue(m_interpreter
, m_key_index
);
654 detail::push(m_interpreter
, value
);
655 lua_settable(m_interpreter
, -3);
660 index_proxy
<this_type
> operator[](T
const& key
)
662 return index_proxy
<this_type
>(*this, m_interpreter
, key
);
665 void push(lua_State
* interpreter
);
667 lua_State
* interpreter() const
669 return m_interpreter
;
673 struct hidden_type
{};
675 // this_type& operator=(index_proxy<Next> const&);
677 mutable lua_State
* m_interpreter
;
685 typedef detail::basic_iterator
<detail::basic_access
> iterator
;
686 typedef detail::basic_iterator
<detail::raw_access
> raw_iterator
;
688 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
690 struct value_wrapper_traits
<adl::index_proxy
<T
> >
693 struct value_wrapper_traits
<adl::index_proxy_tag
>
696 typedef boost::mpl::true_ is_specialized
;
699 static lua_State
* interpreter(adl::index_proxy
<Next
> const& proxy
)
701 return proxy
.interpreter();
705 static void unwrap(lua_State
* interpreter
, adl::index_proxy
<Next
> const& proxy
)
707 const_cast<adl::index_proxy
<Next
>&>(proxy
).push(interpreter
);
711 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
712 template<class AccessPolicy
>
713 struct value_wrapper_traits
<adl::iterator_proxy
<AccessPolicy
> >
716 struct value_wrapper_traits
<adl::iterator_proxy_tag
>
719 typedef boost::mpl::true_ is_specialized
;
721 template<class Proxy
>
722 static lua_State
* interpreter(Proxy
const& p
)
724 return p
.interpreter();
727 template<class Proxy
>
728 static void unwrap(lua_State
* interpreter
, Proxy
const& p
)
730 // TODO: Why const_cast?
731 const_cast<Proxy
&>(p
).push(interpreter
);
738 // An object holds a reference to a Lua value residing
740 class object
: public object_interface
<object
>
746 explicit object(handle
const& other
)
750 explicit object(from_stack
const& stack_reference
)
751 : m_handle(stack_reference
.interpreter
, stack_reference
.index
)
756 object(lua_State
* interpreter
, T
const& value
)
758 detail::push(interpreter
, value
);
759 detail::stack_pop
pop(interpreter
, 1);
760 handle(interpreter
, -1).swap(m_handle
);
763 template<class T
, class Policies
>
764 object(lua_State
* interpreter
, T
const& value
, Policies
const&)
766 detail::push(interpreter
, value
, Policies());
767 detail::stack_pop
pop(interpreter
, 1);
768 handle(interpreter
, -1).swap(m_handle
);
771 void push(lua_State
* interpreter
) const;
772 lua_State
* interpreter() const;
773 bool is_valid() const;
776 index_proxy
<object
> operator[](T
const& key
) const
778 return index_proxy
<object
>(
779 *this, m_handle
.interpreter(), key
783 void swap(object
& other
)
785 m_handle
.swap(other
.m_handle
);
792 inline void object::push(lua_State
* interpreter
) const
794 m_handle
.push(interpreter
);
797 inline lua_State
* object::interpreter() const
799 return m_handle
.interpreter();
802 inline bool object::is_valid() const
804 return m_handle
.interpreter() != 0;
807 class argument
: public object_interface
<argument
>
810 argument(from_stack
const& stack_reference
)
811 : m_interpreter(stack_reference
.interpreter
)
812 , m_index(stack_reference
.index
)
815 m_index
= lua_gettop(m_interpreter
) - m_index
+ 1;
819 index_proxy
<argument
> operator[](T
const& key
) const
821 return index_proxy
<argument
>(*this, m_interpreter
, key
);
824 void push(lua_State
* L
) const
826 lua_pushvalue(L
, m_index
);
829 lua_State
* interpreter() const
831 return m_interpreter
;
835 lua_State
* m_interpreter
;
844 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
845 template <class ValueWrapper
, class Arguments
>
846 struct value_wrapper_traits
<adl::call_proxy
<ValueWrapper
, Arguments
> >
849 struct value_wrapper_traits
<adl::call_proxy_tag
>
852 typedef boost::mpl::true_ is_specialized
;
854 template<class W
, class A
>
855 static lua_State
* interpreter(adl::call_proxy
<W
,A
> const& proxy
)
857 return value_wrapper_traits
<W
>::interpreter(*proxy
.value_wrapper
);
860 template<class W
, class A
>
861 static void unwrap(lua_State
*, adl::call_proxy
<W
,A
> const& proxy
)
863 object result
= const_cast<adl::call_proxy
<W
,A
>&>(proxy
);
864 result
.push(result
.interpreter());
869 struct value_wrapper_traits
<object
>
871 typedef boost::mpl::true_ is_specialized
;
873 static lua_State
* interpreter(object
const& value
)
875 return value
.interpreter();
878 static void unwrap(lua_State
* interpreter
, object
const& value
)
880 value
.push(interpreter
);
883 static bool check(...)
890 struct value_wrapper_traits
<argument
>
892 typedef boost::mpl::true_ is_specialized
;
894 static lua_State
* interpreter(argument
const& value
)
896 return value
.interpreter();
899 static void unwrap(lua_State
* interpreter
, argument
const& value
)
901 value
.push(interpreter
);
904 static bool check(...)
911 inline void adl::index_proxy
<Next
>::push(lua_State
* interpreter
)
913 assert(interpreter
== m_interpreter
);
915 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
917 lua_pushvalue(m_interpreter
, m_key_index
);
918 lua_gettable(m_interpreter
, -2);
919 lua_remove(m_interpreter
, -2);
923 inline adl::index_proxy
<Next
>::operator object()
925 detail::stack_pop
pop(m_interpreter
, 1);
927 return object(from_stack(m_interpreter
, -1));
930 template<class AccessPolicy
>
931 adl::iterator_proxy
<AccessPolicy
>::operator object()
933 lua_pushvalue(m_interpreter
, m_key_index
);
934 AccessPolicy::get(m_interpreter
, m_table_index
);
935 detail::stack_pop
pop(m_interpreter
, 1);
936 return object(from_stack(m_interpreter
, -1));
939 template<class AccessPolicy
>
940 object
detail::basic_iterator
<AccessPolicy
>::key() const
942 return object(m_key
);
955 ReturnType
object_cast_aux(
956 ValueWrapper
const& value_wrapper
963 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
967 #ifndef LUABIND_NO_ERROR_CHECKING
969 return ErrorPolicy::handle_error(interpreter
, typeid(void));
972 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value_wrapper
);
974 detail::stack_pop
pop(interpreter
, 1);
976 typedef typename
detail::find_conversion_policy
<
979 >::type converter_generator
;
981 typename
mpl::apply_wrap2
<converter_generator
, T
, lua_to_cpp
>::type cv
;
983 if (cv
.match(interpreter
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
985 return ErrorPolicy::handle_error(interpreter
, typeid(T
));
988 return cv
.apply(interpreter
, LUABIND_DECORATE_TYPE(T
), -1);
992 # pragma warning(push)
993 # pragma warning(disable:4702) // unreachable code
997 struct throw_error_policy
999 static T
handle_error(lua_State
* interpreter
, type_id
const& type_info
)
1001 #ifndef LUABIND_NO_EXCEPTIONS
1002 throw cast_failed(interpreter
, type_info
);
1004 cast_failed_callback_fun e
= get_cast_failed_callback();
1005 if (e
) e(interpreter
, type_info
);
1007 assert(0 && "object_cast failed. If you want to handle this error use "
1008 "luabind::set_error_callback()");
1011 return *(typename
boost::remove_reference
<T
>::type
*)0;
1016 # pragma warning(pop)
1020 struct nothrow_error_policy
1022 static boost::optional
<T
> handle_error(lua_State
*, type_id
const&)
1024 return boost::optional
<T
>();
1028 } // namespace detail
1030 template<class T
, class ValueWrapper
>
1031 T
object_cast(ValueWrapper
const& value_wrapper
)
1033 return detail::object_cast_aux(
1036 , (detail::null_type
*)0
1037 , (detail::throw_error_policy
<T
>*)0
1042 template<class T
, class ValueWrapper
, class Policies
>
1043 T
object_cast(ValueWrapper
const& value_wrapper
, Policies
const&)
1045 return detail::object_cast_aux(
1049 , (detail::throw_error_policy
<T
>*)0
1054 template<class T
, class ValueWrapper
>
1055 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
)
1057 return detail::object_cast_aux(
1060 , (detail::null_type
*)0
1061 , (detail::nothrow_error_policy
<T
>*)0
1062 , (boost::optional
<T
>*)0
1066 template<class T
, class ValueWrapper
, class Policies
>
1067 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
, Policies
const&)
1069 return detail::object_cast_aux(
1073 , (detail::nothrow_error_policy
<T
>*)0
1074 , (boost::optional
<T
>*)0
1082 struct push_args_from_tuple
1084 # ifdef LUABIND_CPP0x
1086 template <class Args
, class Policies
, class N
, class E
>
1087 static void push_args(
1088 lua_State
* L
, Args
const& args
, Policies
const& policies
, N
, E
)
1090 convert_to_lua_p
<N::value
+ 1>(L
, *std::get
<N::value
>(args
), policies
);
1092 L
, args
, policies
, std::integral_constant
<int, N::value
+ 1>(), E());
1095 template <class Args
, class Policies
, class E
>
1096 static void push_args(lua_State
* L
, Args
const&, Policies
const&, E
, E
)
1099 template <class... Args
, class Policies
= null_type
>
1101 lua_State
* L
, std::tuple
<Args
...> const& args
1102 , Policies
const policies
= Policies())
1108 , std::integral_constant
<int, 0>()
1109 , std::integral_constant
<int, sizeof...(Args
)>()
1113 # else // LUABIND_CPP0x
1115 template<class H
, class T
, class Policies
>
1116 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
, const Policies
& p
)
1118 convert_to_lua_p
<Index
>(L
, *x
.get_head(), p
);
1119 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail(), p
);
1122 template<class H
, class T
>
1123 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
)
1125 convert_to_lua(L
, *x
.get_head());
1126 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail());
1129 template<class Policies
>
1130 inline static void apply(lua_State
*, const boost::tuples::null_type
&, const Policies
&) {}
1132 inline static void apply(lua_State
*, const boost::tuples::null_type
&) {}
1134 # endif // LUABIND_CPP0x
1137 } // namespace detail
1142 template<class ValueWrapper
, class Arguments
>
1145 call_proxy(ValueWrapper
& value_wrapper
, Arguments arguments
)
1146 : value_wrapper(&value_wrapper
)
1147 , arguments(arguments
)
1150 call_proxy(call_proxy
const& other
)
1151 : value_wrapper(other
.value_wrapper
)
1152 , arguments(other
.arguments
)
1154 other
.value_wrapper
= 0;
1160 call((detail::null_type
*)0);
1165 return call((detail::null_type
*)0);
1168 template<class Policies
>
1169 object
operator[](Policies
const&)
1171 return call((Policies
*)0);
1174 template<class Policies
>
1175 object
call(Policies
*)
1177 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1181 value_wrapper_traits
<ValueWrapper
>::unwrap(
1188 detail::push_args_from_tuple
<1>::apply(interpreter
, arguments
, Policies());
1190 # ifdef LUABIND_CPP0x
1191 if (detail::pcall(interpreter
, std::tuple_size
<Arguments
>::value
, 1))
1193 if (detail::pcall(interpreter
, boost::tuples::length
<Arguments
>::value
, 1))
1196 #ifndef LUABIND_NO_EXCEPTIONS
1197 throw luabind::error(interpreter
);
1199 error_callback_fun e
= get_error_callback();
1200 if (e
) e(interpreter
);
1202 assert(0 && "the lua function threw an error and exceptions are disabled."
1203 "if you want to handle this error use luabind::set_error_callback()");
1208 detail::stack_pop
pop(interpreter
, 1);
1209 return object(from_stack(interpreter
, -1));
1212 mutable ValueWrapper
* value_wrapper
;
1213 Arguments arguments
;
1216 # ifndef LUABIND_CPP0x
1218 template<class Derived
>
1219 call_proxy
<Derived
, boost::tuples::tuple
<> >
1220 object_interface
<Derived
>::operator()()
1222 return call_proxy
<Derived
, boost::tuples::tuple
<> >(
1224 , boost::tuples::tuple
<>()
1230 // Simple value_wrapper adaptor with the sole purpose of helping with
1231 // overload resolution. Use this as a function parameter type instead
1232 // of "object" or "argument" to restrict the parameter to Lua tables.
1233 template <class Base
= object
>
1236 table(from_stack
const& stack_reference
)
1237 : Base(stack_reference
)
1245 template <class Base
>
1246 struct value_wrapper_traits
<adl::table
<Base
> >
1247 : value_wrapper_traits
<Base
>
1249 static bool check(lua_State
* L
, int idx
)
1251 return value_wrapper_traits
<Base
>::check(L
, idx
) &&
1252 lua_istable(L
, idx
);
1256 inline object
newtable(lua_State
* interpreter
)
1258 lua_newtable(interpreter
);
1259 detail::stack_pop
pop(interpreter
, 1);
1260 return object(from_stack(interpreter
, -1));
1263 // this could be optimized by returning a proxy
1264 inline object
globals(lua_State
* interpreter
)
1266 lua_pushvalue(interpreter
, LUA_GLOBALSINDEX
);
1267 detail::stack_pop
pop(interpreter
, 1);
1268 return object(from_stack(interpreter
, -1));
1271 // this could be optimized by returning a proxy
1272 inline object
registry(lua_State
* interpreter
)
1274 lua_pushvalue(interpreter
, LUA_REGISTRYINDEX
);
1275 detail::stack_pop
pop(interpreter
, 1);
1276 return object(from_stack(interpreter
, -1));
1279 template<class ValueWrapper
, class K
>
1280 inline object
gettable(ValueWrapper
const& table
, K
const& key
)
1282 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1286 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1287 detail::stack_pop
pop(interpreter
, 2);
1288 detail::push(interpreter
, key
);
1289 lua_gettable(interpreter
, -2);
1290 return object(from_stack(interpreter
, -1));
1293 template<class ValueWrapper
, class K
, class T
>
1294 inline void settable(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1296 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1300 // TODO: Exception safe?
1302 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1303 detail::stack_pop
pop(interpreter
, 1);
1304 detail::push(interpreter
, key
);
1305 detail::push(interpreter
, value
);
1306 lua_settable(interpreter
, -3);
1309 template<class ValueWrapper
, class K
>
1310 inline object
rawget(ValueWrapper
const& table
, K
const& key
)
1312 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1316 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1317 detail::stack_pop
pop(interpreter
, 2);
1318 detail::push(interpreter
, key
);
1319 lua_rawget(interpreter
, -2);
1320 return object(from_stack(interpreter
, -1));
1323 template<class ValueWrapper
, class K
, class T
>
1324 inline void rawset(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1326 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1330 // TODO: Exception safe?
1332 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1333 detail::stack_pop
pop(interpreter
, 1);
1334 detail::push(interpreter
, key
);
1335 detail::push(interpreter
, value
);
1336 lua_rawset(interpreter
, -3);
1339 template<class ValueWrapper
>
1340 inline int type(ValueWrapper
const& value
)
1342 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1346 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1347 detail::stack_pop
pop(interpreter
, 1);
1348 return lua_type(interpreter
, -1);
1351 template <class ValueWrapper
>
1352 inline object
getmetatable(ValueWrapper
const& obj
)
1354 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1358 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, obj
);
1359 detail::stack_pop
pop(interpreter
, 2);
1360 lua_getmetatable(interpreter
, -1);
1361 return object(from_stack(interpreter
, -1));
1364 template <class ValueWrapper1
, class ValueWrapper2
>
1365 inline void setmetatable(
1366 ValueWrapper1
const& obj
, ValueWrapper2
const& metatable
)
1368 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1372 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, obj
);
1373 detail::stack_pop
pop(interpreter
, 1);
1374 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, metatable
);
1375 lua_setmetatable(interpreter
, -2);
1378 template <class ValueWrapper
>
1379 inline lua_CFunction
tocfunction(ValueWrapper
const& value
)
1381 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1385 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1386 detail::stack_pop
pop(interpreter
, 1);
1387 return lua_tocfunction(interpreter
, -1);
1390 template <class T
, class ValueWrapper
>
1391 inline T
* touserdata(ValueWrapper
const& value
)
1393 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1397 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1398 detail::stack_pop
pop(interpreter
, 1);
1399 return static_cast<T
*>(lua_touserdata(interpreter
, -1));
1402 template <class ValueWrapper
>
1403 inline object
getupvalue(ValueWrapper
const& value
, int index
)
1405 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1409 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1410 detail::stack_pop
pop(interpreter
, 2);
1411 lua_getupvalue(interpreter
, -1, index
);
1412 return object(from_stack(interpreter
, -1));
1415 template <class ValueWrapper1
, class ValueWrapper2
>
1416 inline void setupvalue(
1417 ValueWrapper1
const& function
, int index
, ValueWrapper2
const& value
)
1419 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1423 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, function
);
1424 detail::stack_pop
pop(interpreter
, 1);
1425 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, value
);
1426 lua_setupvalue(interpreter
, -2, index
);
1429 template <class GetValueWrapper
>
1430 object
property(GetValueWrapper
const& get
)
1432 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1436 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1437 lua_pushnil(interpreter
);
1439 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1440 detail::stack_pop
pop(interpreter
, 1);
1442 return object(from_stack(interpreter
, -1));
1445 template <class GetValueWrapper
, class SetValueWrapper
>
1446 object
property(GetValueWrapper
const& get
, SetValueWrapper
const& set
)
1448 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1452 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1453 value_wrapper_traits
<SetValueWrapper
>::unwrap(interpreter
, set
);
1455 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1456 detail::stack_pop
pop(interpreter
, 1);
1458 return object(from_stack(interpreter
, -1));
1463 } // namespace luabind
1465 #endif // LUABIND_OBJECT_050419_HPP