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/value_wrapper.hpp>
34 #include <luabind/detail/pcall.hpp>
35 #include <luabind/handle.hpp>
36 #include <luabind/from_stack.hpp>
37 #include <luabind/detail/policy.hpp>
38 #include <luabind/detail/stack_utils.hpp>
39 #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
41 #include <boost/iterator/iterator_facade.hpp> // iterator
42 #include <boost/python/detail/is_xxx.hpp>
44 #include <boost/preprocessor/iteration/iterate.hpp>
50 namespace mpl
= boost::mpl
;
52 template<class T
, class ConverterGenerator
>
53 void push_aux(lua_State
* interpreter
, T
& value
, ConverterGenerator
*)
55 typedef typename
boost::mpl::if_
<
56 boost::is_reference_wrapper
<T
>
57 , BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
59 >::type unwrapped_type
;
61 typename
mpl::apply_wrap2
<
62 ConverterGenerator
,unwrapped_type
,cpp_to_lua
67 , boost::implicit_cast
<
68 BOOST_DEDUCED_TYPENAME
boost::unwrap_reference
<T
>::type
&
73 template<class T
, class Policies
>
74 void push(lua_State
* interpreter
, T
& value
, Policies
const&)
76 typedef typename find_conversion_policy
<
79 >::type converter_policy
;
81 push_aux(interpreter
, value
, (converter_policy
*)0);
85 void push(lua_State
* interpreter
, T
& value
)
87 push(interpreter
, value
, null_type());
95 template<class T
, class U
, class V
>
96 lua_State
* binary_interpreter(T
const& x
, U
const&, boost::mpl::true_
, V
)
98 return value_wrapper_traits
<T
>::interpreter(x
);
101 template<class T
, class U
>
102 lua_State
* binary_interpreter(T
const&, U
const& x
, boost::mpl::false_
, boost::mpl::true_
)
104 return value_wrapper_traits
<U
>::interpreter(x
);
107 template<class T
, class U
>
108 lua_State
* binary_interpreter(T
const& x
, U
const& y
)
110 return binary_interpreter(
113 , is_value_wrapper
<T
>()
114 , is_value_wrapper
<U
>()
118 #define LUABIND_BINARY_OP_DEF(op, fn) \
119 template<class LHS, class RHS> \
120 bool operator op(LHS const& lhs, RHS const& rhs) \
122 lua_State* L = binary_interpreter(lhs, rhs); \
126 detail::stack_pop pop1(L, 1); \
127 detail::push(L, lhs); \
128 detail::stack_pop pop2(L, 1); \
129 detail::push(L, rhs); \
131 return fn(L, -1, -2) != 0; \
134 LUABIND_BINARY_OP_DEF(==, lua_equal
)
135 LUABIND_BINARY_OP_DEF(<, lua_lessthan
)
137 #undef LUABIND_BINARY_OP_DEF
139 template<class LHS
, class RHS
>
140 bool operator>(LHS
const& lhs
, RHS
const& rhs
)
142 return !(lhs
< rhs
|| lhs
== rhs
);
145 template<class LHS
, class RHS
>
146 bool operator<=(LHS
const& lhs
, RHS
const& rhs
)
148 return lhs
< rhs
|| lhs
== rhs
;
151 template<class LHS
, class RHS
>
152 bool operator>=(LHS
const& lhs
, RHS
const& rhs
)
157 template<class LHS
, class RHS
>
158 bool operator!=(LHS
const& lhs
, RHS
const& rhs
)
163 template<class ValueWrapper
, class Arguments
>
171 template<class Derived
>
172 class object_interface
175 ~object_interface() {}
177 call_proxy
<Derived
, boost::tuples::tuple
<> > operator()();
182 , boost::tuples::tuple
<A0
const*>
183 > operator()(A0
const& a0
)
185 typedef boost::tuples::tuple
<A0
const*> arguments
;
187 return call_proxy
<Derived
, arguments
>(
193 template<class A0
, class A1
>
196 , boost::tuples::tuple
<A0
const*, A1
const*>
197 > operator()(A0
const& a0
, A1
const& a1
)
199 typedef boost::tuples::tuple
<A0
const*, A1
const*> arguments
;
201 return call_proxy
<object
, arguments
>(
203 , arguments(&a0
, &a1
)
207 // The rest of the overloads are PP-generated.
208 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
209 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
210 #include BOOST_PP_ITERATE()
215 return *static_cast<Derived
*>(this);
218 Derived
const& derived() const
220 return *static_cast<Derived
const*>(this);
224 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
225 struct iterator_proxy_tag
;
228 template<class AccessPolicy
>
230 : public object_interface
<iterator_proxy
<AccessPolicy
> >
233 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
234 typedef iterator_proxy_tag value_wrapper_tag
;
237 iterator_proxy(lua_State
* interpreter
, handle
const& table
, handle
const& key
)
238 : m_interpreter(interpreter
)
239 , m_table_index(lua_gettop(interpreter
) + 1)
240 , m_key_index(m_table_index
+ 1)
242 table
.push(m_interpreter
);
243 key
.push(m_interpreter
);
246 iterator_proxy(iterator_proxy
const& other
)
247 : m_interpreter(other
.m_interpreter
)
248 , m_table_index(other
.m_table_index
)
249 , m_key_index(other
.m_key_index
)
251 other
.m_interpreter
= 0;
257 lua_pop(m_interpreter
, 2);
261 iterator_proxy
& operator=(T
const& value
)
263 lua_pushvalue(m_interpreter
, m_key_index
);
264 detail::push(m_interpreter
, value
);
265 AccessPolicy::set(m_interpreter
, m_table_index
);
270 index_proxy
<iterator_proxy
<AccessPolicy
> > operator[](Key
const& key
)
272 return index_proxy
<iterator_proxy
<AccessPolicy
> >(
273 *this, m_interpreter
, key
277 // This is non-const to prevent conversion on lvalues.
280 lua_State
* interpreter() const
282 return m_interpreter
;
285 // TODO: Why is it non-const?
286 void push(lua_State
* interpreter
)
288 assert(interpreter
== m_interpreter
);
289 lua_pushvalue(m_interpreter
, m_key_index
);
290 AccessPolicy::get(m_interpreter
, m_table_index
);
294 mutable lua_State
* m_interpreter
;
305 static void set(lua_State
* interpreter
, int table
)
307 lua_settable(interpreter
, table
);
310 static void get(lua_State
* interpreter
, int table
)
312 lua_gettable(interpreter
, table
);
318 static void set(lua_State
* interpreter
, int table
)
320 lua_rawset(interpreter
, table
);
323 static void get(lua_State
* interpreter
, int table
)
325 lua_rawget(interpreter
, table
);
329 template<class AccessPolicy
>
331 : public boost::iterator_facade
<
332 basic_iterator
<AccessPolicy
>
333 , adl::iterator_proxy
<AccessPolicy
>
334 , boost::single_pass_traversal_tag
335 , adl::iterator_proxy
<AccessPolicy
>
343 template<class ValueWrapper
>
344 explicit basic_iterator(ValueWrapper
const& value_wrapper
)
346 value_wrapper_traits
<ValueWrapper
>::interpreter(value_wrapper
)
349 detail::stack_pop
pop(m_interpreter
, 1);
350 value_wrapper_traits
<ValueWrapper
>::unwrap(m_interpreter
, value_wrapper
);
352 lua_pushnil(m_interpreter
);
353 if (lua_next(m_interpreter
, -2) != 0)
355 detail::stack_pop
pop(m_interpreter
, 2);
356 handle(m_interpreter
, -2).swap(m_key
);
364 handle(m_interpreter
, -1).swap(m_table
);
367 adl::object
key() const;
370 friend class boost::iterator_core_access
;
374 m_table
.push(m_interpreter
);
375 m_key
.push(m_interpreter
);
377 detail::stack_pop
pop(m_interpreter
, 1);
379 if (lua_next(m_interpreter
, -2) != 0)
381 m_key
.replace(m_interpreter
, -2);
382 lua_pop(m_interpreter
, 2);
387 handle().swap(m_table
);
388 handle().swap(m_key
);
392 bool equal(basic_iterator
const& other
) const
394 if (m_interpreter
== 0 && other
.m_interpreter
== 0)
397 if (m_interpreter
!= other
.m_interpreter
)
400 detail::stack_pop
pop(m_interpreter
, 2);
401 m_key
.push(m_interpreter
);
402 other
.m_key
.push(m_interpreter
);
403 return lua_equal(m_interpreter
, -2, -1) != 0;
406 adl::iterator_proxy
<AccessPolicy
> dereference() const
408 return adl::iterator_proxy
<AccessPolicy
>(m_interpreter
, m_table
, m_key
);
411 lua_State
* m_interpreter
;
416 // Needed because of some strange ADL issues.
418 #define LUABIND_OPERATOR_ADL_WKND(op) \
419 inline bool operator op( \
420 basic_iterator<basic_access> const& x \
421 , basic_iterator<basic_access> const& y) \
423 return boost::operator op(x, y); \
426 inline bool operator op( \
427 basic_iterator<raw_access> const& x \
428 , basic_iterator<raw_access> const& y) \
430 return boost::operator op(x, y); \
433 LUABIND_OPERATOR_ADL_WKND(==)
434 LUABIND_OPERATOR_ADL_WKND(!=)
436 #undef LUABIND_OPERATOR_ADL_WKND
438 } // namespace detail
443 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
444 struct index_proxy_tag
;
449 : public object_interface
<index_proxy
<Next
> >
452 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
453 typedef index_proxy_tag value_wrapper_tag
;
456 typedef index_proxy
<Next
> this_type
;
459 index_proxy(Next
const& next
, lua_State
* interpreter
, Key
const& key
)
460 : m_interpreter(interpreter
)
461 , m_key_index(lua_gettop(interpreter
) + 1)
464 detail::push(m_interpreter
, key
);
467 index_proxy(index_proxy
const& other
)
468 : m_interpreter(other
.m_interpreter
)
469 , m_key_index(other
.m_key_index
)
470 , m_next(other
.m_next
)
472 other
.m_interpreter
= 0;
478 lua_pop(m_interpreter
, 1);
481 // This is non-const to prevent conversion on lvalues.
485 this_type
& operator=(T
const& value
)
487 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
488 detail::stack_pop
pop(m_interpreter
, 1);
490 lua_pushvalue(m_interpreter
, m_key_index
);
491 detail::push(m_interpreter
, value
);
492 lua_settable(m_interpreter
, -3);
497 index_proxy
<this_type
> operator[](T
const& key
)
499 return index_proxy
<this_type
>(*this, m_interpreter
, key
);
502 void push(lua_State
* interpreter
);
504 lua_State
* interpreter() const
506 return m_interpreter
;
510 this_type
& operator=(index_proxy
<Next
> const&);
512 mutable lua_State
* m_interpreter
;
520 typedef detail::basic_iterator
<detail::basic_access
> iterator
;
521 typedef detail::basic_iterator
<detail::raw_access
> raw_iterator
;
523 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
525 struct value_wrapper_traits
<adl::index_proxy
<T
> >
528 struct value_wrapper_traits
<adl::index_proxy_tag
>
531 typedef boost::mpl::true_ is_specialized
;
534 static lua_State
* interpreter(adl::index_proxy
<Next
> const& proxy
)
536 return proxy
.interpreter();
540 static void unwrap(lua_State
* interpreter
, adl::index_proxy
<Next
> const& proxy
)
542 const_cast<adl::index_proxy
<Next
>&>(proxy
).push(interpreter
);
546 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
547 template<class AccessPolicy
>
548 struct value_wrapper_traits
<adl::iterator_proxy
<AccessPolicy
> >
551 struct value_wrapper_traits
<adl::iterator_proxy_tag
>
554 typedef boost::mpl::true_ is_specialized
;
556 template<class Proxy
>
557 static lua_State
* interpreter(Proxy
const& p
)
559 return p
.interpreter();
562 template<class Proxy
>
563 static void unwrap(lua_State
* interpreter
, Proxy
const& p
)
565 // TODO: Why const_cast?
566 const_cast<Proxy
&>(p
).push(interpreter
);
578 explicit object_init(from_stack
const& stack_reference
, boost::mpl::true_
)
579 : m_handle(stack_reference
.interpreter
, stack_reference
.index
)
583 template<class ValueWrapper
>
584 explicit object_init(ValueWrapper
const& value_wrapper
, boost::mpl::false_
)
586 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
590 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value_wrapper
);
591 detail::stack_pop
pop(interpreter
, 1);
593 handle(interpreter
, -1).swap(m_handle
);
599 // An object holds a reference to a Lua value residing
601 class object
: public object_interface
<object
>
603 struct safe_bool_type
{};
608 explicit object(handle
const& other
)
612 explicit object(from_stack
const& stack_reference
)
613 : m_handle(stack_reference
.interpreter
, stack_reference
.index
)
618 object(lua_State
* interpreter
, T
const& value
)
620 detail::push(interpreter
, value
);
621 detail::stack_pop
pop(interpreter
, 1);
622 handle(interpreter
, -1).swap(m_handle
);
625 template<class T
, class Policies
>
626 object(lua_State
* interpreter
, T
const& value
, Policies
const&)
628 detail::push(interpreter
, value
, Policies());
629 detail::stack_pop
pop(interpreter
, 1);
630 handle(interpreter
, -1).swap(m_handle
);
633 void push(lua_State
* interpreter
) const;
634 lua_State
* interpreter() const;
635 bool is_valid() const;
636 operator safe_bool_type
*() const;
639 index_proxy
<object
> operator[](T
const& key
) const
641 return index_proxy
<object
>(
642 *this, m_handle
.interpreter(), key
646 void swap(object
& other
)
648 m_handle
.swap(other
.m_handle
);
655 inline void object::push(lua_State
* interpreter
) const
657 m_handle
.push(interpreter
);
660 inline lua_State
* object::interpreter() const
662 return m_handle
.interpreter();
665 inline bool object::is_valid() const
667 return m_handle
.interpreter() != 0;
670 inline object::operator object::safe_bool_type
*() const
672 return is_valid()?(safe_bool_type
*)1:0;
680 struct value_wrapper_traits
<object
>
682 typedef boost::mpl::true_ is_specialized
;
684 static lua_State
* interpreter(object
const& value
)
686 return value
.interpreter();
689 static void unwrap(lua_State
* interpreter
, object
const& value
)
691 value
.push(interpreter
);
694 static bool check(...)
701 inline void adl::index_proxy
<Next
>::push(lua_State
* interpreter
)
703 assert(interpreter
== m_interpreter
);
705 value_wrapper_traits
<Next
>::unwrap(m_interpreter
, m_next
);
707 lua_pushvalue(m_interpreter
, m_key_index
);
708 lua_gettable(m_interpreter
, -2);
709 lua_remove(m_interpreter
, -2);
713 inline adl::index_proxy
<Next
>::operator object()
715 detail::stack_pop
pop(m_interpreter
, 1);
717 return object(from_stack(m_interpreter
, -1));
720 template<class AccessPolicy
>
721 adl::iterator_proxy
<AccessPolicy
>::operator object()
723 lua_pushvalue(m_interpreter
, m_key_index
);
724 AccessPolicy::get(m_interpreter
, m_table_index
);
725 detail::stack_pop
pop(m_interpreter
, 1);
726 return object(from_stack(m_interpreter
, -1));
729 template<class AccessPolicy
>
730 object
detail::basic_iterator
<AccessPolicy
>::key() const
732 return object(m_key
);
745 ReturnType
object_cast_aux(
746 ValueWrapper
const& value_wrapper
753 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
757 #ifndef LUABIND_NO_ERROR_CHECKING
759 return ErrorPolicy::handle_error(interpreter
, LUABIND_TYPEID(void));
762 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value_wrapper
);
764 detail::stack_pop
pop(interpreter
, 1);
766 typedef typename
detail::find_conversion_policy
<
769 >::type converter_generator
;
771 typename
mpl::apply_wrap2
<converter_generator
, T
, lua_to_cpp
>::type cv
;
773 #ifndef LUABIND_NO_ERROR_CHECKING
774 if (cv
.match(interpreter
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
776 return ErrorPolicy::handle_error(interpreter
, LUABIND_TYPEID(T
));
780 return cv
.apply(interpreter
, LUABIND_DECORATE_TYPE(T
), -1);
784 struct throw_error_policy
786 static T
handle_error(lua_State
* interpreter
, LUABIND_TYPE_INFO type_info
)
788 #ifndef LUABIND_NO_EXCEPTIONS
789 throw cast_failed(interpreter
, type_info
);
791 cast_failed_callback_fun e
= get_cast_failed_callback();
792 if (e
) e(interpreter
, type_info
);
794 assert(0 && "object_cast failed. If you want to handle this error use "
795 "luabind::set_error_callback()");
802 struct nothrow_error_policy
804 static boost::optional
<T
> handle_error(lua_State
*, LUABIND_TYPE_INFO
)
806 return boost::optional
<T
>();
810 } // namespace detail
812 template<class T
, class ValueWrapper
>
813 T
object_cast(ValueWrapper
const& value_wrapper
)
815 return detail::object_cast_aux(
818 , (detail::null_type
*)0
819 , (detail::throw_error_policy
<T
>*)0
824 template<class T
, class ValueWrapper
, class Policies
>
825 T
object_cast(ValueWrapper
const& value_wrapper
, Policies
const&)
827 return detail::object_cast_aux(
831 , (detail::throw_error_policy
<T
>*)0
836 template<class T
, class ValueWrapper
>
837 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
)
839 return detail::object_cast_aux(
842 , (detail::null_type
*)0
843 , (detail::nothrow_error_policy
<T
>*)0
844 , (boost::optional
<T
>*)0
848 template<class T
, class ValueWrapper
, class Policies
>
849 boost::optional
<T
> object_cast_nothrow(ValueWrapper
const& value_wrapper
, Policies
const&)
851 return detail::object_cast_aux(
855 , (detail::nothrow_error_policy
<T
>*)0
856 , (boost::optional
<T
>*)0
864 struct push_args_from_tuple
866 template<class H
, class T
, class Policies
>
867 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
, const Policies
& p
)
869 convert_to_lua_p
<Index
>(L
, *x
.get_head(), p
);
870 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail(), p
);
873 template<class H
, class T
>
874 inline static void apply(lua_State
* L
, const boost::tuples::cons
<H
, T
>& x
)
876 convert_to_lua(L
, *x
.get_head());
877 push_args_from_tuple
<Index
+1>::apply(L
, x
.get_tail());
880 template<class Policies
>
881 inline static void apply(lua_State
*, const boost::tuples::null_type
&, const Policies
&) {};
883 inline static void apply(lua_State
*, const boost::tuples::null_type
&) {};
886 } // namespace detail
891 template<class ValueWrapper
, class Arguments
>
894 call_proxy(ValueWrapper
& value_wrapper
, Arguments arguments
)
895 : value_wrapper(&value_wrapper
)
896 , arguments(arguments
)
899 call_proxy(call_proxy
const& other
)
900 : value_wrapper(other
.value_wrapper
)
901 , arguments(other
.arguments
)
903 other
.value_wrapper
= 0;
909 call((detail::null_type
*)0);
914 return call((detail::null_type
*)0);
917 template<class Policies
>
918 object
operator[](Policies
const&)
920 return call((Policies
*)0);
923 template<class Policies
>
924 object
call(Policies
*)
926 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
930 value_wrapper_traits
<ValueWrapper
>::unwrap(
937 detail::push_args_from_tuple
<1>::apply(interpreter
, arguments
, Policies());
939 if (detail::pcall(interpreter
, boost::tuples::length
<Arguments
>::value
, 1))
941 #ifndef LUABIND_NO_EXCEPTIONS
942 throw luabind::error(interpreter
);
944 error_callback_fun e
= get_error_callback();
945 if (e
) e(interpreter
);
947 assert(0 && "the lua function threw an error and exceptions are disabled."
948 "if you want to handle this error use luabind::set_error_callback()");
953 detail::stack_pop
pop(interpreter
, 1);
954 return object(from_stack(interpreter
, -1));
957 mutable ValueWrapper
* value_wrapper
;
961 template<class Derived
>
962 call_proxy
<Derived
, boost::tuples::tuple
<> >
963 object_interface
<Derived
>::operator()()
965 return call_proxy
<Derived
, boost::tuples::tuple
<> >(
967 , boost::tuples::tuple
<>()
973 inline object
newtable(lua_State
* interpreter
)
975 lua_newtable(interpreter
);
976 detail::stack_pop
pop(interpreter
, 1);
977 return object(from_stack(interpreter
, -1));
980 inline object
globals(lua_State
* interpreter
)
982 lua_pushvalue(interpreter
, LUA_GLOBALSINDEX
);
983 detail::stack_pop
pop(interpreter
, 1);
984 return object(from_stack(interpreter
, -1));
987 template<class ValueWrapper
, class K
>
988 inline object
gettable(ValueWrapper
const& table
, K
const& key
)
990 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
994 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
995 detail::stack_pop
pop(interpreter
, 2);
996 detail::push(interpreter
, key
);
997 lua_gettable(interpreter
, -2);
998 return object(from_stack(interpreter
, -1));
1001 template<class ValueWrapper
, class K
, class T
>
1002 inline void settable(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1004 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1008 // TODO: Exception safe?
1010 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1011 detail::stack_pop
pop(interpreter
, 1);
1012 detail::push(interpreter
, key
);
1013 detail::push(interpreter
, value
);
1014 lua_settable(interpreter
, -3);
1017 template<class ValueWrapper
, class K
>
1018 inline object
rawget(ValueWrapper
const& table
, K
const& key
)
1020 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1024 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1025 detail::stack_pop
pop(interpreter
, 2);
1026 detail::push(interpreter
, key
);
1027 lua_rawget(interpreter
, -2);
1028 return object(from_stack(interpreter
, -1));
1031 template<class ValueWrapper
, class K
, class T
>
1032 inline void rawset(ValueWrapper
const& table
, K
const& key
, T
const& value
)
1034 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1038 // TODO: Exception safe?
1040 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, table
);
1041 detail::stack_pop
pop(interpreter
, 1);
1042 detail::push(interpreter
, key
);
1043 detail::push(interpreter
, value
);
1044 lua_rawset(interpreter
, -3);
1047 template<class ValueWrapper
>
1048 inline int type(ValueWrapper
const& value
)
1050 lua_State
* interpreter
= value_wrapper_traits
<ValueWrapper
>::interpreter(
1054 value_wrapper_traits
<ValueWrapper
>::unwrap(interpreter
, value
);
1055 detail::stack_pop
pop(interpreter
, 1);
1056 return lua_type(interpreter
, -1);
1059 } // namespace luabind
1061 #endif // LUABIND_OBJECT_050419_HPP