Made it work on VC6.5 again. This involves changing generate_converter
[luabind.git] / luabind / object.hpp
blob7abe0ff169701f1731eca82318d15677b3a352f2
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>
46 namespace luabind {
48 namespace detail
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&
58 , T
59 >::type unwrapped_type;
61 typename mpl::apply_wrap2<
62 ConverterGenerator,unwrapped_type,cpp_to_lua
63 >::type cv;
65 cv.apply(
66 interpreter
67 , boost::implicit_cast<
68 BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
69 >(value)
73 template<class T, class Policies>
74 void push(lua_State* interpreter, T& value, Policies const&)
76 typedef typename find_conversion_policy<
78 , Policies
79 >::type converter_policy;
81 push_aux(interpreter, value, (converter_policy*)0);
84 template<class T>
85 void push(lua_State* interpreter, T& value)
87 push(interpreter, value, null_type());
90 } // namespace detail
92 namespace adl
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); \
124 assert(L); \
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)
154 return !(lhs < rhs);
157 template<class LHS, class RHS>
158 bool operator!=(LHS const& lhs, RHS const& rhs)
160 return !(lhs < rhs);
163 template<class ValueWrapper, class Arguments>
164 struct call_proxy;
166 template<class Next>
167 class index_proxy;
169 class object;
171 template<class Derived>
172 class object_interface
174 public:
175 ~object_interface() {}
177 call_proxy<Derived, boost::tuples::tuple<> > operator()();
179 template<class A0>
180 call_proxy<
181 Derived
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>(
188 derived()
189 , arguments(&a0)
193 template<class A0, class A1>
194 call_proxy<
195 Derived
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>(
202 derived()
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()
212 private:
213 Derived& derived()
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;
226 #endif
228 template<class AccessPolicy>
229 class iterator_proxy
230 : public object_interface<iterator_proxy<AccessPolicy> >
232 public:
233 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
234 typedef iterator_proxy_tag value_wrapper_tag;
235 #endif
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;
254 ~iterator_proxy()
256 if (m_interpreter)
257 lua_pop(m_interpreter, 2);
260 template<class T>
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);
266 return *this;
269 template<class Key>
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.
278 operator object();
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);
293 private:
294 mutable lua_State* m_interpreter;
295 int m_table_index;
296 int m_key_index;
299 } // namespace adl
301 namespace detail
303 struct basic_access
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);
316 struct raw_access
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>
330 class basic_iterator
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>
338 public:
339 basic_iterator()
340 : m_interpreter(0)
343 template<class ValueWrapper>
344 explicit basic_iterator(ValueWrapper const& value_wrapper)
345 : m_interpreter(
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);
358 else
360 m_interpreter = 0;
361 return;
364 handle(m_interpreter, -1).swap(m_table);
367 adl::object key() const;
369 private:
370 friend class boost::iterator_core_access;
372 void increment()
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);
384 else
386 m_interpreter = 0;
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)
395 return true;
397 if (m_interpreter != other.m_interpreter)
398 return false;
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;
412 handle m_table;
413 handle m_key;
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
440 namespace adl
443 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
444 struct index_proxy_tag;
445 #endif
447 template<class Next>
448 class index_proxy
449 : public object_interface<index_proxy<Next> >
451 public:
452 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
453 typedef index_proxy_tag value_wrapper_tag;
454 #endif
456 typedef index_proxy<Next> this_type;
458 template<class Key>
459 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
460 : m_interpreter(interpreter)
461 , m_key_index(lua_gettop(interpreter) + 1)
462 , m_next(next)
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;
475 ~index_proxy()
477 if (m_interpreter)
478 lua_pop(m_interpreter, 1);
481 // This is non-const to prevent conversion on lvalues.
482 operator object();
484 template<class T>
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);
493 return *this;
496 template<class T>
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;
509 private:
510 this_type& operator=(index_proxy<Next> const&);
512 mutable lua_State* m_interpreter;
513 int m_key_index;
515 Next const& m_next;
518 } // namespace adl
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
524 template<class T>
525 struct value_wrapper_traits<adl::index_proxy<T> >
526 #else
527 template<>
528 struct value_wrapper_traits<adl::index_proxy_tag>
529 #endif
531 typedef boost::mpl::true_ is_specialized;
533 template<class Next>
534 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
536 return proxy.interpreter();
539 template<class Next>
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> >
549 #else
550 template<>
551 struct value_wrapper_traits<adl::iterator_proxy_tag>
552 #endif
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);
570 namespace adl
572 class object_init
574 protected:
575 object_init()
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(
587 value_wrapper
590 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
591 detail::stack_pop pop(interpreter, 1);
593 handle(interpreter, -1).swap(m_handle);
596 handle m_handle;
599 // An object holds a reference to a Lua value residing
600 // in the registry.
601 class object : public object_interface<object>
603 struct safe_bool_type {};
604 public:
605 object()
608 explicit object(handle const& other)
609 : m_handle(other)
612 explicit object(from_stack const& stack_reference)
613 : m_handle(stack_reference.interpreter, stack_reference.index)
617 template<class T>
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;
638 template<class T>
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);
651 private:
652 handle 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;
675 } // namespace adl
677 using adl::object;
679 template<>
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(...)
696 return true;
700 template<class Next>
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);
712 template<class Next>
713 inline adl::index_proxy<Next>::operator object()
715 detail::stack_pop pop(m_interpreter, 1);
716 push(m_interpreter);
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);
735 namespace detail
738 template<
739 class T
740 , class ValueWrapper
741 , class Policies
742 , class ErrorPolicy
743 , class ReturnType
745 ReturnType object_cast_aux(
746 ValueWrapper const& value_wrapper
747 , T*
748 , Policies*
749 , ErrorPolicy*
750 , ReturnType*
753 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
754 value_wrapper
757 #ifndef LUABIND_NO_ERROR_CHECKING
758 if (!interpreter)
759 return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(void));
760 #endif
762 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
764 detail::stack_pop pop(interpreter, 1);
766 typedef typename detail::find_conversion_policy<
768 , Policies
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));
778 #endif
780 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
783 template<class T>
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);
790 #else
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()");
796 std::terminate();
797 #endif
801 template<class T>
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(
816 value_wrapper
817 , (T*)0
818 , (detail::null_type*)0
819 , (detail::throw_error_policy<T>*)0
820 , (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(
828 value_wrapper
829 , (T*)0
830 , (Policies*)0
831 , (detail::throw_error_policy<T>*)0
832 , (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(
840 value_wrapper
841 , (T*)0
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(
852 value_wrapper
853 , (T*)0
854 , (Policies*)0
855 , (detail::nothrow_error_policy<T>*)0
856 , (boost::optional<T>*)0
860 namespace detail
863 template<int Index>
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
888 namespace adl
891 template<class ValueWrapper, class Arguments>
892 struct call_proxy
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;
906 ~call_proxy()
908 if (value_wrapper)
909 call((detail::null_type*)0);
912 operator object()
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(
927 *value_wrapper
930 value_wrapper_traits<ValueWrapper>::unwrap(
931 interpreter
932 , *value_wrapper
935 value_wrapper = 0;
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);
943 #else
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()");
949 std::terminate();
950 #endif
953 detail::stack_pop pop(interpreter, 1);
954 return object(from_stack(interpreter, -1));
957 mutable ValueWrapper* value_wrapper;
958 Arguments arguments;
961 template<class Derived>
962 call_proxy<Derived, boost::tuples::tuple<> >
963 object_interface<Derived>::operator()()
965 return call_proxy<Derived, boost::tuples::tuple<> >(
966 derived()
967 , boost::tuples::tuple<>()
971 } // namespace adl
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(
991 table
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(
1005 table
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(
1021 table
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(
1035 table
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(
1051 value
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