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
45 #include <boost/preprocessor/iteration/iterate.hpp>
46 #include <boost/utility/enable_if.hpp>
52 namespace mpl
= boost::mpl
;
54 template<class T
, class ConverterGenerator
>
55 void push_aux(lua_State
* interpreter
, T
& value
, ConverterGenerator
*)
57 typedef typename
boost::mpl::if_
<
58 boost::is_reference_wrapper
<T
>
59 , BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
61 >::type unwrapped_type
;
63 typename
mpl::apply_wrap2
<
64 ConverterGenerator
,unwrapped_type
,cpp_to_lua
69 , boost::implicit_cast
<
70 BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
75 template<class T
, class Policies
>
76 void push(lua_State
* interpreter
, T
& value
, Policies
const&)
78 typedef typename find_conversion_policy
<
81 >::type converter_policy
;
83 push_aux(interpreter
, value
, (converter_policy
*)0);
87 void push(lua_State
* interpreter
, T
& value
)
89 push(interpreter
, value
, null_type());
96 namespace mpl
= boost::mpl
;
99 class object_interface
;
101 namespace is_object_interface_aux
103 typedef char (&yes
)[1];
104 typedef char (&no
)[2];
107 yes
check(object_interface
<T
>*);
113 BOOST_STATIC_CONSTANT(bool, value
=
114 sizeof(is_object_interface_aux::check((T
*)0)) == sizeof(yes
)
117 typedef mpl::bool_
<value
> type
;
120 } // namespace detail
123 struct is_object_interface
124 : is_object_interface_aux::impl
<T
>::type
127 template <class R
, class T
, class U
>
129 # ifndef BOOST_NO_SFINAE
132 is_object_interface
<T
>
133 , is_object_interface
<U
>
144 template<class T
, class U
>
145 int binary_interpreter(lua_State
*& L
, T
const& lhs
, U
const& rhs
146 , boost::mpl::true_
, boost::mpl::true_
)
148 L
= value_wrapper_traits
<T
>::interpreter(lhs
);
149 lua_State
* L2
= value_wrapper_traits
<U
>::interpreter(rhs
);
151 // you are comparing objects with different interpreters
152 // that's not allowed.
153 assert(L
== L2
|| L
== 0 || L2
== 0);
155 // if the two objects we compare have different interpreters
158 if (L
!= L2
) return -1;
159 if (L
== 0) return 1;
163 template<class T
, class U
>
164 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const&
165 , boost::mpl::true_
, boost::mpl::false_
)
167 L
= value_wrapper_traits
<T
>::interpreter(x
);
171 template<class T
, class U
>
172 int binary_interpreter(lua_State
*& L
, T
const&, U
const& x
, boost::mpl::false_
, boost::mpl::true_
)
174 L
= value_wrapper_traits
<U
>::interpreter(x
);
178 template<class T
, class U
>
179 int binary_interpreter(lua_State
*& L
, T
const& x
, U
const& y
)
181 return binary_interpreter(
185 , is_value_wrapper
<T
>()
186 , is_value_wrapper
<U
>()
190 #define LUABIND_BINARY_OP_DEF(op, fn) \
191 template<class LHS, class RHS> \
192 typename enable_binary<bool,LHS,RHS>::type \
193 operator op(LHS const& lhs, RHS const& rhs) \
196 switch (binary_interpreter(L, lhs, rhs)) \
206 detail::stack_pop pop1(L, 1); \
207 detail::push(L, lhs); \
208 detail::stack_pop pop2(L, 1); \
209 detail::push(L, rhs); \
211 return fn(L, -1, -2) != 0; \
214 LUABIND_BINARY_OP_DEF(==, lua_equal
)
215 LUABIND_BINARY_OP_DEF(<, lua_lessthan
)
217 template<class ValueWrapper
>
218 std::ostream
& operator<<(std::ostream
& os
219 , object_interface
<ValueWrapper
> const& v
)
221 using namespace luabind
;
222 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
223 static_cast<ValueWrapper
const&>(v
));
224 detail::stack_pop
pop(interpreter
, 1);
225 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
226 , static_cast<ValueWrapper
const&>(v
));
227 char const* p
= lua_tostring(interpreter
, -1);
228 std::size_t len
= lua_strlen(interpreter
, -1);
229 std::copy(p
, p
+ len
, std::ostream_iterator
<char>(os
));
233 #undef LUABIND_BINARY_OP_DEF
235 template<class LHS
, class RHS
>
236 typename enable_binary
<bool,LHS
,RHS
>::type
237 operator>(LHS
const& lhs
, RHS
const& rhs
)
239 return !(lhs
< rhs
|| lhs
== rhs
);
242 template<class LHS
, class RHS
>
243 typename enable_binary
<bool,LHS
,RHS
>::type
244 operator<=(LHS
const& lhs
, RHS
const& rhs
)
246 return lhs
< rhs
|| lhs
== rhs
;
249 template<class LHS
, class RHS
>
250 typename enable_binary
<bool,LHS
,RHS
>::type
251 operator>=(LHS
const& lhs
, RHS
const& rhs
)
256 template<class LHS
, class RHS
>
257 typename enable_binary
<bool,LHS
,RHS
>::type
258 operator!=(LHS
const& lhs
, RHS
const& rhs
)
260 return !(lhs
== rhs
);
263 template<class ValueWrapper
, class Arguments
>
271 template<class Derived
>
272 class object_interface
274 struct safe_bool_type
{};
276 ~object_interface() {}
278 call_proxy
<Derived
, boost::tuples::tuple
<> > operator()();
283 , boost::tuples::tuple
<A0
const*>
284 > operator()(A0
const& a0
)
286 typedef boost::tuples::tuple
<A0
const*> arguments
;
288 return call_proxy
<Derived
, arguments
>(
294 template<class A0
, class A1
>
297 , boost::tuples::tuple
<A0
const*, A1
const*>
298 > operator()(A0
const& a0
, A1
const& a1
)
300 typedef boost::tuples::tuple
<A0
const*, A1
const*> arguments
;
302 return call_proxy
<Derived
, arguments
>(
304 , arguments(&a0
, &a1
)
308 // The rest of the overloads are PP-generated.
309 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
310 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
311 #include BOOST_PP_ITERATE()
313 operator safe_bool_type
*() const
315 lua_State
* L
= value_wrapper_traits
<Derived
>::interpreter(derived());
320 value_wrapper_traits
<Derived
>::unwrap(L
, derived());
321 detail::stack_pop
pop(L
, 1);
323 return lua_toboolean(L
, -1) == 1 ? (safe_bool_type
*)1 : 0;
329 return *static_cast<Derived
*>(this);
332 Derived
const& derived() const
334 return *static_cast<Derived
const*>(this);
338 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
339 struct iterator_proxy_tag
;
342 template<class AccessPolicy
>
344 : public object_interface
<iterator_proxy
<AccessPolicy
> >
347 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
348 typedef iterator_proxy_tag value_wrapper_tag
;
351 iterator_proxy(lua_State
* interpreter
, handle
const& table
, handle
const& key
)
352 : m_interpreter(interpreter
)
353 , m_table_index(lua_gettop(interpreter
) + 1)
354 , m_key_index(m_table_index
+ 1)
356 table
.push(m_interpreter
);
357 key
.push(m_interpreter
);
360 iterator_proxy(iterator_proxy
const& other
)
361 : m_interpreter(other
.m_interpreter
)
362 , m_table_index(other
.m_table_index
)
363 , m_key_index(other
.m_key_index
)
365 other
.m_interpreter
= 0;
371 lua_pop(m_interpreter
, 2);
374 // this will set the value to nil
375 iterator_proxy
& operator=(luabind::detail::nil_type
)
377 lua_pushvalue(m_interpreter
, m_key_index
);
378 lua_pushnil(m_interpreter
);
379 AccessPolicy::set(m_interpreter
, m_table_index
);
384 iterator_proxy
& operator=(T
const& value
)
386 lua_pushvalue(m_interpreter
, m_key_index
);
387 detail::push(m_interpreter
, value
);
388 AccessPolicy::set(m_interpreter
, m_table_index
);
393 index_proxy
<iterator_proxy
<AccessPolicy
> > operator[](Key
const& key
)
395 return index_proxy
<iterator_proxy
<AccessPolicy
> >(
396 *this, m_interpreter
, key
400 // This is non-const to prevent conversion on lvalues.
403 lua_State
* interpreter() const
405 return m_interpreter
;
408 // TODO: Why is it non-const?
409 void push(lua_State
* interpreter
)
411 assert(interpreter
== m_interpreter
);
412 lua_pushvalue(m_interpreter
, m_key_index
);
413 AccessPolicy::get(m_interpreter
, m_table_index
);
417 mutable lua_State
* m_interpreter
;
428 static void set(lua_State
* interpreter
, int table
)
430 lua_settable(interpreter
, table
);
433 static void get(lua_State
* interpreter
, int table
)
435 lua_gettable(interpreter
, table
);
441 static void set(lua_State
* interpreter
, int table
)
443 lua_rawset(interpreter
, table
);
446 static void get(lua_State
* interpreter
, int table
)
448 lua_rawget(interpreter
, table
);
452 template<class AccessPolicy
>
454 : public boost::iterator_facade
<
455 basic_iterator
<AccessPolicy
>
456 , adl::iterator_proxy
<AccessPolicy
>
457 , boost::single_pass_traversal_tag
458 , adl::iterator_proxy
<AccessPolicy
>
466 template<class ValueWrapper
>
467 explicit basic_iterator(ValueWrapper
const& value_wrapper
)
469 value_wrapper_traits
<ValueWrapper
>::interpreter(value_wrapper
)
472 detail::stack_pop
pop(m_interpreter
, 1);
473 value_wrapper_traits
<ValueWrapper
>::unwrap(m_interpreter
, value_wrapper
);
475 lua_pushnil(m_interpreter
);
476 if (lua_next(m_interpreter
, -2) != 0)
478 detail::stack_pop
pop(m_interpreter
, 2);
479 handle(m_interpreter
, -2).swap(m_key
);
487 handle(m_interpreter
, -1).swap(m_table
);
490 adl::object
key() const;
493 friend class boost::iterator_core_access
;
497 m_table
.push(m_interpreter
);
498 m_key
.push(m_interpreter
);
500 detail::stack_pop
pop(m_interpreter
, 1);
502 if (lua_next(m_interpreter
, -2) != 0)
504 m_key
.replace(m_interpreter
, -2);
505 lua_pop(m_interpreter
, 2);
510 handle().swap(m_table
);
511 handle().swap(m_key
);
515 bool equal(basic_iterator
const& other
) const
517 if (m_interpreter
== 0 && other
.m_interpreter
== 0)
520 if (m_interpreter
!= other
.m_interpreter
)
523 detail::stack_pop
pop(m_interpreter
, 2);
524 m_key
.push(m_interpreter
);
525 other
.m_key
.push(m_interpreter
);
526 return lua_equal(m_interpreter
, -2, -1) != 0;
529 adl::iterator_proxy
<AccessPolicy
> dereference() const
531 return adl::iterator_proxy
<AccessPolicy
>(m_interpreter
, m_table
, m_key
);
534 lua_State
* m_interpreter
;
539 // Needed because of some strange ADL issues.
541 #define LUABIND_OPERATOR_ADL_WKND(op) \
542 inline bool operator op( \
543 basic_iterator<basic_access> const& x \
544 , basic_iterator<basic_access> const& y) \
546 return boost::operator op(x, y); \
549 inline bool operator op( \
550 basic_iterator<raw_access> const& x \
551 , basic_iterator<raw_access> const& y) \
553 return boost::operator op(x, y); \
556 LUABIND_OPERATOR_ADL_WKND(==)
557 LUABIND_OPERATOR_ADL_WKND(!=)
559 #undef LUABIND_OPERATOR_ADL_WKND
561 } // namespace detail
566 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
567 struct index_proxy_tag
;
572 : public object_interface
<index_proxy
<Next
> >
575 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
576 typedef index_proxy_tag value_wrapper_tag
;
579 typedef index_proxy
<Next
> this_type
;
582 index_proxy(Next
const& next
, lua_State
* interpreter
, Key
const& key
)
583 : m_interpreter(interpreter
)
584 , m_key_index(lua_gettop(interpreter
) + 1)
587 detail::push(m_interpreter
, key
);
590 index_proxy(index_proxy
const& other
)
591 : m_interpreter(other
.m_interpreter
)
592 , m_key_index(other
.m_key_index
)
593 , m_next(other
.m_next
)
595 other
.m_interpreter
= 0;
601 lua_pop(m_interpreter
, 1);
604 // This is non-const to prevent conversion on lvalues.
607 // this will set the value to nil
608 this_type
& operator=(luabind::detail::nil_type
)
610 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
611 detail::stack_pop
pop(m_interpreter
, 1);
613 lua_pushvalue(m_interpreter
, m_key_index
);
614 lua_pushnil(m_interpreter
);
615 lua_settable(m_interpreter
, -3);
620 this_type
& operator=(T
const& value
)
622 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
623 detail::stack_pop
pop(m_interpreter
, 1);
625 lua_pushvalue(m_interpreter
, m_key_index
);
626 detail::push(m_interpreter
, value
);
627 lua_settable(m_interpreter
, -3);
631 this_type
& operator=(this_type
const& value
)
633 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
634 detail::stack_pop
pop(m_interpreter
, 1);
636 lua_pushvalue(m_interpreter
, m_key_index
);
637 detail::push(m_interpreter
, value
);
638 lua_settable(m_interpreter
, -3);
643 index_proxy
<this_type
> operator[](T
const& key
)
645 return index_proxy
<this_type
>(*this, m_interpreter
, key
);
648 void push(lua_State
* interpreter
);
650 lua_State
* interpreter() const
652 return m_interpreter
;
656 struct hidden_type
{};
658 // this_type& operator=(index_proxy<Next> const&);
660 mutable lua_State
* m_interpreter
;
668 typedef detail::basic_iterator
<detail::basic_access
> iterator
;
669 typedef detail::basic_iterator
<detail::raw_access
> raw_iterator
;
671 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
673 struct value_wrapper_traits
<adl::index_proxy
<T
> >
676 struct value_wrapper_traits
<adl::index_proxy_tag
>
679 typedef boost::mpl::true_ is_specialized
;
682 static lua_State
* interpreter(adl::index_proxy
<Next
> const& proxy
)
684 return proxy
.interpreter();
688 static void unwrap(lua_State
* interpreter
, adl::index_proxy
<Next
> const& proxy
)
690 const_cast<adl::index_proxy
<Next
>&>(proxy
).push(interpreter
);
694 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
695 template<class AccessPolicy
>
696 struct value_wrapper_traits
<adl::iterator_proxy
<AccessPolicy
> >
699 struct value_wrapper_traits
<adl::iterator_proxy_tag
>
702 typedef boost::mpl::true_ is_specialized
;
704 template<class Proxy
>
705 static lua_State
* interpreter(Proxy
const& p
)
707 return p
.interpreter();
710 template<class Proxy
>
711 static void unwrap(lua_State
* interpreter
, Proxy
const& p
)
713 // TODO: Why const_cast?
714 const_cast<Proxy
&>(p
).push(interpreter
);
721 // An object holds a reference to a Lua value residing
723 class object
: public object_interface
<object
>
729 explicit object(handle
const& other
)
733 explicit object(from_stack
const& stack_reference
)
734 : m_handle(stack_reference
.interpreter
, stack_reference
.index
)
739 object(lua_State
* interpreter
, T
const& value
)
741 detail::push(interpreter
, value
);
742 detail::stack_pop
pop(interpreter
, 1);
743 handle(interpreter
, -1).swap(m_handle
);
746 template<class T
, class Policies
>
747 object(lua_State
* interpreter
, T
const& value
, Policies
const&)
749 detail::push(interpreter
, value
, Policies());
750 detail::stack_pop
pop(interpreter
, 1);
751 handle(interpreter
, -1).swap(m_handle
);
754 void push(lua_State
* interpreter
) const;
755 lua_State
* interpreter() const;
756 bool is_valid() const;
759 index_proxy
<object
> operator[](T
const& key
) const
761 return index_proxy
<object
>(
762 *this, m_handle
.interpreter(), key
766 void swap(object
& other
)
768 m_handle
.swap(other
.m_handle
);
775 inline void object::push(lua_State
* interpreter
) const
777 m_handle
.push(interpreter
);
780 inline lua_State
* object::interpreter() const
782 return m_handle
.interpreter();
785 inline bool object::is_valid() const
787 return m_handle
.interpreter() != 0;
790 class argument
: public object_interface
<argument
>
793 argument(from_stack
const& stack_reference
)
794 : m_interpreter(stack_reference
.interpreter
)
795 , m_index(stack_reference
.index
)
798 m_index
= lua_gettop(m_interpreter
) - m_index
+ 1;
802 index_proxy
<argument
> operator[](T
const& key
) const
804 return index_proxy
<argument
>(*this, m_interpreter
, key
);
807 void push(lua_State
* L
) const
809 lua_pushvalue(L
, m_index
);
812 lua_State
* interpreter() const
814 return m_interpreter
;
818 lua_State
* m_interpreter
;
827 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
828 template <class ValueWrapper
, class Arguments
>
829 struct value_wrapper_traits
<adl::call_proxy
<ValueWrapper
, Arguments
> >
832 struct value_wrapper_traits
<adl::call_proxy_tag
>
835 typedef boost::mpl::true_ is_specialized
;
837 template<class W
, class A
>
838 static lua_State
* interpreter(adl::call_proxy
<W
,A
> const& proxy
)
840 return value_wrapper_traits
<W
>::interpreter(*proxy
.value_wrapper
);
843 template<class W
, class A
>
844 static void unwrap(lua_State
*, adl::call_proxy
<W
,A
> const& proxy
)
846 object result
= const_cast<adl::call_proxy
<W
,A
>&>(proxy
);
847 result
.push(result
.interpreter());
852 struct value_wrapper_traits
<object
>
854 typedef boost::mpl::true_ is_specialized
;
856 static lua_State
* interpreter(object
const& value
)
858 return value
.interpreter();
861 static void unwrap(lua_State
* interpreter
, object
const& value
)
863 value
.push(interpreter
);
866 static bool check(...)
873 struct value_wrapper_traits
<argument
>
875 typedef boost::mpl::true_ is_specialized
;
877 static lua_State
* interpreter(argument
const& value
)
879 return value
.interpreter();
882 static void unwrap(lua_State
* interpreter
, argument
const& value
)
884 value
.push(interpreter
);
887 static bool check(...)
894 inline void adl::index_proxy
<Next
>::push(lua_State
* interpreter
)
896 assert(interpreter
== m_interpreter
);
898 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
900 lua_pushvalue(m_interpreter
, m_key_index
);
901 lua_gettable(m_interpreter
, -2);
902 lua_remove(m_interpreter
, -2);
906 inline adl::index_proxy
<Next
>::operator object()
908 detail::stack_pop
pop(m_interpreter
, 1);
910 return object(from_stack(m_interpreter
, -1));
913 template<class AccessPolicy
>
914 adl::iterator_proxy
<AccessPolicy
>::operator object()
916 lua_pushvalue(m_interpreter
, m_key_index
);
917 AccessPolicy::get(m_interpreter
, m_table_index
);
918 detail::stack_pop
pop(m_interpreter
, 1);
919 return object(from_stack(m_interpreter
, -1));
922 template<class AccessPolicy
>
923 object
detail::basic_iterator
<AccessPolicy
>::key() const
925 return object(m_key
);
938 ReturnType
object_cast_aux(
939 ValueWrapper
const& value_wrapper
946 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
950 #ifndef LUABIND_NO_ERROR_CHECKING
952 return ErrorPolicy::handle_error(interpreter
, typeid(void));
955 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value_wrapper
);
957 detail::stack_pop
pop(interpreter
, 1);
959 typedef typename
detail::find_conversion_policy
<
962 >::type converter_generator
;
964 typename
mpl::apply_wrap2
<converter_generator
, T
, lua_to_cpp
>::type cv
;
966 #ifndef LUABIND_NO_ERROR_CHECKING
967 if (cv
.match(interpreter
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
969 return ErrorPolicy::handle_error(interpreter
, typeid(T
));
973 return cv
.apply(interpreter
, LUABIND_DECORATE_TYPE(T
), -1);
977 # pragma warning(push)
978 # pragma warning(disable:4702) // unreachable code
982 struct throw_error_policy
984 static T
handle_error(lua_State
* interpreter
, type_id
const& type_info
)
986 #ifndef LUABIND_NO_EXCEPTIONS
987 throw cast_failed(interpreter
, type_info
);
989 cast_failed_callback_fun e
= get_cast_failed_callback();
990 if (e
) e(interpreter
, type_info
);
992 assert(0 && "object_cast failed. If you want to handle this error use "
993 "luabind::set_error_callback()");
996 return *(typename
boost::remove_reference
<T
>::type
*)0;
1001 # pragma warning(pop)
1005 struct nothrow_error_policy
1007 static boost::optional
<T
> handle_error(lua_State
*, type_id
const&)
1009 return boost::optional
<T
>();
1013 } // namespace detail
1015 template<class T
, class ValueWrapper
>
1016 T
object_cast(ValueWrapper
const& value_wrapper
)
1018 return detail::object_cast_aux(
1021 , (detail::null_type
*)0
1022 , (detail::throw_error_policy
<T
>*)0
1027 template<class T
, class ValueWrapper
, class Policies
>
1028 T
object_cast(ValueWrapper
const& value_wrapper
, Policies
const&)
1030 return detail::object_cast_aux(
1034 , (detail::throw_error_policy
<T
>*)0
1039 template<class T
, class ValueWrapper
>
1040 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
)
1042 return detail::object_cast_aux(
1045 , (detail::null_type
*)0
1046 , (detail::nothrow_error_policy
<T
>*)0
1047 , (boost::optional
<T
>*)0
1051 template<class T
, class ValueWrapper
, class Policies
>
1052 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
, Policies
const&)
1054 return detail::object_cast_aux(
1058 , (detail::nothrow_error_policy
<T
>*)0
1059 , (boost::optional
<T
>*)0
1067 struct push_args_from_tuple
1069 template<class H
, class T
, class Policies
>
1070 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
, const Policies
& p
)
1072 convert_to_lua_p
<Index
>(L
, *x
.get_head(), p
);
1073 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail(), p
);
1076 template<class H
, class T
>
1077 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
)
1079 convert_to_lua(L
, *x
.get_head());
1080 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail());
1083 template<class Policies
>
1084 inline static void apply(lua_State
*, const boost::tuples::null_type
&, const Policies
&) {}
1086 inline static void apply(lua_State
*, const boost::tuples::null_type
&) {}
1089 } // namespace detail
1094 template<class ValueWrapper
, class Arguments
>
1097 call_proxy(ValueWrapper
& value_wrapper
, Arguments arguments
)
1098 : value_wrapper(&value_wrapper
)
1099 , arguments(arguments
)
1102 call_proxy(call_proxy
const& other
)
1103 : value_wrapper(other
.value_wrapper
)
1104 , arguments(other
.arguments
)
1106 other
.value_wrapper
= 0;
1112 call((detail::null_type
*)0);
1117 return call((detail::null_type
*)0);
1120 template<class Policies
>
1121 object
operator[](Policies
const&)
1123 return call((Policies
*)0);
1126 template<class Policies
>
1127 object
call(Policies
*)
1129 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1133 value_wrapper_traits
<ValueWrapper
>::unwrap(
1140 detail::push_args_from_tuple
<1>::apply(interpreter
, arguments
, Policies());
1142 if (detail::pcall(interpreter
, boost::tuples::length
<Arguments
>::value
, 1))
1144 #ifndef LUABIND_NO_EXCEPTIONS
1145 throw luabind::error(interpreter
);
1147 error_callback_fun e
= get_error_callback();
1148 if (e
) e(interpreter
);
1150 assert(0 && "the lua function threw an error and exceptions are disabled."
1151 "if you want to handle this error use luabind::set_error_callback()");
1156 detail::stack_pop
pop(interpreter
, 1);
1157 return object(from_stack(interpreter
, -1));
1160 mutable ValueWrapper
* value_wrapper
;
1161 Arguments arguments
;
1164 template<class Derived
>
1165 call_proxy
<Derived
, boost::tuples::tuple
<> >
1166 object_interface
<Derived
>::operator()()
1168 return call_proxy
<Derived
, boost::tuples::tuple
<> >(
1170 , boost::tuples::tuple
<>()
1174 // Simple value_wrapper adaptor with the sole purpose of helping with
1175 // overload resolution. Use this as a function parameter type instead
1176 // of "object" or "argument" to restrict the parameter to Lua tables.
1177 template <class Base
= object
>
1180 table(from_stack
const& stack_reference
)
1181 : Base(stack_reference
)
1189 template <class Base
>
1190 struct value_wrapper_traits
<adl::table
<Base
> >
1191 : value_wrapper_traits
<Base
>
1193 static bool check(lua_State
* L
, int idx
)
1195 return value_wrapper_traits
<Base
>::check(L
, idx
) &&
1196 lua_istable(L
, idx
);
1200 inline object
newtable(lua_State
* interpreter
)
1202 lua_newtable(interpreter
);
1203 detail::stack_pop
pop(interpreter
, 1);
1204 return object(from_stack(interpreter
, -1));
1207 // this could be optimized by returning a proxy
1208 inline object
globals(lua_State
* interpreter
)
1210 lua_pushvalue(interpreter
, LUA_GLOBALSINDEX
);
1211 detail::stack_pop
pop(interpreter
, 1);
1212 return object(from_stack(interpreter
, -1));
1215 // this could be optimized by returning a proxy
1216 inline object
registry(lua_State
* interpreter
)
1218 lua_pushvalue(interpreter
, LUA_REGISTRYINDEX
);
1219 detail::stack_pop
pop(interpreter
, 1);
1220 return object(from_stack(interpreter
, -1));
1223 template<class ValueWrapper
, class K
>
1224 inline object
gettable(ValueWrapper
const& table
, K
const& key
)
1226 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1230 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1231 detail::stack_pop
pop(interpreter
, 2);
1232 detail::push(interpreter
, key
);
1233 lua_gettable(interpreter
, -2);
1234 return object(from_stack(interpreter
, -1));
1237 template<class ValueWrapper
, class K
, class T
>
1238 inline void settable(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1240 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1244 // TODO: Exception safe?
1246 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1247 detail::stack_pop
pop(interpreter
, 1);
1248 detail::push(interpreter
, key
);
1249 detail::push(interpreter
, value
);
1250 lua_settable(interpreter
, -3);
1253 template<class ValueWrapper
, class K
>
1254 inline object
rawget(ValueWrapper
const& table
, K
const& key
)
1256 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1260 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1261 detail::stack_pop
pop(interpreter
, 2);
1262 detail::push(interpreter
, key
);
1263 lua_rawget(interpreter
, -2);
1264 return object(from_stack(interpreter
, -1));
1267 template<class ValueWrapper
, class K
, class T
>
1268 inline void rawset(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1270 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1274 // TODO: Exception safe?
1276 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1277 detail::stack_pop
pop(interpreter
, 1);
1278 detail::push(interpreter
, key
);
1279 detail::push(interpreter
, value
);
1280 lua_rawset(interpreter
, -3);
1283 template<class ValueWrapper
>
1284 inline int type(ValueWrapper
const& value
)
1286 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1290 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1291 detail::stack_pop
pop(interpreter
, 1);
1292 return lua_type(interpreter
, -1);
1295 template <class ValueWrapper
>
1296 inline object
getmetatable(ValueWrapper
const& obj
)
1298 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1302 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, obj
);
1303 detail::stack_pop
pop(interpreter
, 2);
1304 lua_getmetatable(interpreter
, -1);
1305 return object(from_stack(interpreter
, -1));
1308 template <class ValueWrapper1
, class ValueWrapper2
>
1309 inline void setmetatable(
1310 ValueWrapper1
const& obj
, ValueWrapper2
const& metatable
)
1312 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1316 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, obj
);
1317 detail::stack_pop
pop(interpreter
, 1);
1318 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, metatable
);
1319 lua_setmetatable(interpreter
, -2);
1322 template <class ValueWrapper
>
1323 inline lua_CFunction
tocfunction(ValueWrapper
const& value
)
1325 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1329 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1330 detail::stack_pop
pop(interpreter
, 1);
1331 return lua_tocfunction(interpreter
, -1);
1334 template <class T
, class ValueWrapper
>
1335 inline T
* touserdata(ValueWrapper
const& value
)
1337 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1341 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1342 detail::stack_pop
pop(interpreter
, 1);
1343 return static_cast<T
*>(lua_touserdata(interpreter
, -1));
1346 template <class ValueWrapper
>
1347 inline object
getupvalue(ValueWrapper
const& value
, int index
)
1349 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1353 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1354 detail::stack_pop
pop(interpreter
, 2);
1355 lua_getupvalue(interpreter
, -1, index
);
1356 return object(from_stack(interpreter
, -1));
1359 template <class ValueWrapper1
, class ValueWrapper2
>
1360 inline void setupvalue(
1361 ValueWrapper1
const& function
, int index
, ValueWrapper2
const& value
)
1363 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper1
>::interpreter(
1367 value_wrapper_traits
<ValueWrapper1
>::unwrap(interpreter
, function
);
1368 detail::stack_pop
pop(interpreter
, 1);
1369 value_wrapper_traits
<ValueWrapper2
>::unwrap(interpreter
, value
);
1370 lua_setupvalue(interpreter
, -2, index
);
1373 template <class GetValueWrapper
>
1374 object
property(GetValueWrapper
const& get
)
1376 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1380 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1381 lua_pushnil(interpreter
);
1383 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1384 detail::stack_pop
pop(interpreter
, 1);
1386 return object(from_stack(interpreter
, -1));
1389 template <class GetValueWrapper
, class SetValueWrapper
>
1390 object
property(GetValueWrapper
const& get
, SetValueWrapper
const& set
)
1392 lua_State
* interpreter
= value_wrapper_traits
<GetValueWrapper
>::interpreter(
1396 value_wrapper_traits
<GetValueWrapper
>::unwrap(interpreter
, get
);
1397 value_wrapper_traits
<SetValueWrapper
>::unwrap(interpreter
, set
);
1399 lua_pushcclosure(interpreter
, &detail::property_tag
, 2);
1400 detail::stack_pop
pop(interpreter
, 1);
1402 return object(from_stack(interpreter
, -1));
1407 } // namespace luabind
1409 #endif // LUABIND_OBJECT_050419_HPP