Operators should only be enabled for object and it's proxy classes, not
[luabind.git] / luabind / object.hpp
blobe6be755c30545ed2e451e0adf9971ac774254c19
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>
45 #include <boost/utility/enable_if.hpp>
47 namespace luabind {
49 namespace detail
51 namespace mpl = boost::mpl;
53 template<class T, class ConverterGenerator>
54 void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
56 typedef typename boost::mpl::if_<
57 boost::is_reference_wrapper<T>
58 , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
59 , T
60 >::type unwrapped_type;
62 typename mpl::apply_wrap2<
63 ConverterGenerator,unwrapped_type,cpp_to_lua
64 >::type cv;
66 cv.apply(
67 interpreter
68 , boost::implicit_cast<
69 BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
70 >(value)
74 template<class T, class Policies>
75 void push(lua_State* interpreter, T& value, Policies const&)
77 typedef typename find_conversion_policy<
79 , Policies
80 >::type converter_policy;
82 push_aux(interpreter, value, (converter_policy*)0);
85 template<class T>
86 void push(lua_State* interpreter, T& value)
88 push(interpreter, value, null_type());
91 } // namespace detail
93 namespace adl
95 namespace mpl = boost::mpl;
97 template <class T>
98 class object_interface;
100 namespace is_object_interface_aux
102 typedef char (&yes)[1];
103 typedef char (&no)[2];
105 template <class T>
106 yes check(object_interface<T>*);
107 no check(void*);
109 template <class T>
110 struct impl
112 BOOST_STATIC_CONSTANT(bool, value =
113 sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
116 typedef mpl::bool_<value> type;
119 } // namespace detail
121 template <class T>
122 struct is_object_interface
123 : is_object_interface_aux::impl<T>::type
126 template <class R, class T, class U>
127 struct enable_binary
128 # ifndef BOOST_NO_SFINAE
129 : boost::enable_if<
130 mpl::or_<
131 is_object_interface<T>
132 , is_object_interface<U>
137 # else
139 typedef R type;
141 # endif
143 template<class T, class U, class V>
144 lua_State* binary_interpreter(T const& x, U const&, boost::mpl::true_, V)
146 return value_wrapper_traits<T>::interpreter(x);
149 template<class T, class U>
150 lua_State* binary_interpreter(T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
152 return value_wrapper_traits<U>::interpreter(x);
155 template<class T, class U>
156 lua_State* binary_interpreter(T const& x, U const& y)
158 return binary_interpreter(
161 , is_value_wrapper<T>()
162 , is_value_wrapper<U>()
166 #define LUABIND_BINARY_OP_DEF(op, fn) \
167 template<class LHS, class RHS> \
168 typename enable_binary<bool,LHS,RHS>::type \
169 operator op(LHS const& lhs, RHS const& rhs) \
171 lua_State* L = binary_interpreter(lhs, rhs); \
173 assert(L); \
175 detail::stack_pop pop1(L, 1); \
176 detail::push(L, lhs); \
177 detail::stack_pop pop2(L, 1); \
178 detail::push(L, rhs); \
180 return fn(L, -1, -2) != 0; \
183 LUABIND_BINARY_OP_DEF(==, lua_equal)
184 LUABIND_BINARY_OP_DEF(<, lua_lessthan)
186 #undef LUABIND_BINARY_OP_DEF
188 template<class LHS, class RHS>
189 typename enable_binary<bool,LHS,RHS>::type
190 operator>(LHS const& lhs, RHS const& rhs)
192 return !(lhs < rhs || lhs == rhs);
195 template<class LHS, class RHS>
196 typename enable_binary<bool,LHS,RHS>::type
197 operator<=(LHS const& lhs, RHS const& rhs)
199 return lhs < rhs || lhs == rhs;
202 template<class LHS, class RHS>
203 typename enable_binary<bool,LHS,RHS>::type
204 operator>=(LHS const& lhs, RHS const& rhs)
206 return !(lhs < rhs);
209 template<class LHS, class RHS>
210 typename enable_binary<bool,LHS,RHS>::type
211 operator!=(LHS const& lhs, RHS const& rhs)
213 return !(lhs < rhs);
216 template<class ValueWrapper, class Arguments>
217 struct call_proxy;
219 template<class Next>
220 class index_proxy;
222 class object;
224 template<class Derived>
225 class object_interface
227 public:
228 ~object_interface() {}
230 call_proxy<Derived, boost::tuples::tuple<> > operator()();
232 template<class A0>
233 call_proxy<
234 Derived
235 , boost::tuples::tuple<A0 const*>
236 > operator()(A0 const& a0)
238 typedef boost::tuples::tuple<A0 const*> arguments;
240 return call_proxy<Derived, arguments>(
241 derived()
242 , arguments(&a0)
246 template<class A0, class A1>
247 call_proxy<
248 Derived
249 , boost::tuples::tuple<A0 const*, A1 const*>
250 > operator()(A0 const& a0, A1 const& a1)
252 typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
254 return call_proxy<object, arguments>(
255 derived()
256 , arguments(&a0, &a1)
260 // The rest of the overloads are PP-generated.
261 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
262 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
263 #include BOOST_PP_ITERATE()
265 private:
266 Derived& derived()
268 return *static_cast<Derived*>(this);
271 Derived const& derived() const
273 return *static_cast<Derived const*>(this);
277 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
278 struct iterator_proxy_tag;
279 #endif
281 template<class AccessPolicy>
282 class iterator_proxy
283 : public object_interface<iterator_proxy<AccessPolicy> >
285 public:
286 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
287 typedef iterator_proxy_tag value_wrapper_tag;
288 #endif
290 iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
291 : m_interpreter(interpreter)
292 , m_table_index(lua_gettop(interpreter) + 1)
293 , m_key_index(m_table_index + 1)
295 table.push(m_interpreter);
296 key.push(m_interpreter);
299 iterator_proxy(iterator_proxy const& other)
300 : m_interpreter(other.m_interpreter)
301 , m_table_index(other.m_table_index)
302 , m_key_index(other.m_key_index)
304 other.m_interpreter = 0;
307 ~iterator_proxy()
309 if (m_interpreter)
310 lua_pop(m_interpreter, 2);
313 template<class T>
314 iterator_proxy& operator=(T const& value)
316 lua_pushvalue(m_interpreter, m_key_index);
317 detail::push(m_interpreter, value);
318 AccessPolicy::set(m_interpreter, m_table_index);
319 return *this;
322 template<class Key>
323 index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
325 return index_proxy<iterator_proxy<AccessPolicy> >(
326 *this, m_interpreter, key
330 // This is non-const to prevent conversion on lvalues.
331 operator object();
333 lua_State* interpreter() const
335 return m_interpreter;
338 // TODO: Why is it non-const?
339 void push(lua_State* interpreter)
341 assert(interpreter == m_interpreter);
342 lua_pushvalue(m_interpreter, m_key_index);
343 AccessPolicy::get(m_interpreter, m_table_index);
346 private:
347 mutable lua_State* m_interpreter;
348 int m_table_index;
349 int m_key_index;
352 } // namespace adl
354 namespace detail
356 struct basic_access
358 static void set(lua_State* interpreter, int table)
360 lua_settable(interpreter, table);
363 static void get(lua_State* interpreter, int table)
365 lua_gettable(interpreter, table);
369 struct raw_access
371 static void set(lua_State* interpreter, int table)
373 lua_rawset(interpreter, table);
376 static void get(lua_State* interpreter, int table)
378 lua_rawget(interpreter, table);
382 template<class AccessPolicy>
383 class basic_iterator
384 : public boost::iterator_facade<
385 basic_iterator<AccessPolicy>
386 , adl::iterator_proxy<AccessPolicy>
387 , boost::single_pass_traversal_tag
388 , adl::iterator_proxy<AccessPolicy>
391 public:
392 basic_iterator()
393 : m_interpreter(0)
396 template<class ValueWrapper>
397 explicit basic_iterator(ValueWrapper const& value_wrapper)
398 : m_interpreter(
399 value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
402 detail::stack_pop pop(m_interpreter, 1);
403 value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
405 lua_pushnil(m_interpreter);
406 if (lua_next(m_interpreter, -2) != 0)
408 detail::stack_pop pop(m_interpreter, 2);
409 handle(m_interpreter, -2).swap(m_key);
411 else
413 m_interpreter = 0;
414 return;
417 handle(m_interpreter, -1).swap(m_table);
420 adl::object key() const;
422 private:
423 friend class boost::iterator_core_access;
425 void increment()
427 m_table.push(m_interpreter);
428 m_key.push(m_interpreter);
430 detail::stack_pop pop(m_interpreter, 1);
432 if (lua_next(m_interpreter, -2) != 0)
434 m_key.replace(m_interpreter, -2);
435 lua_pop(m_interpreter, 2);
437 else
439 m_interpreter = 0;
440 handle().swap(m_table);
441 handle().swap(m_key);
445 bool equal(basic_iterator const& other) const
447 if (m_interpreter == 0 && other.m_interpreter == 0)
448 return true;
450 if (m_interpreter != other.m_interpreter)
451 return false;
453 detail::stack_pop pop(m_interpreter, 2);
454 m_key.push(m_interpreter);
455 other.m_key.push(m_interpreter);
456 return lua_equal(m_interpreter, -2, -1) != 0;
459 adl::iterator_proxy<AccessPolicy> dereference() const
461 return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
464 lua_State* m_interpreter;
465 handle m_table;
466 handle m_key;
469 // Needed because of some strange ADL issues.
471 #define LUABIND_OPERATOR_ADL_WKND(op) \
472 inline bool operator op( \
473 basic_iterator<basic_access> const& x \
474 , basic_iterator<basic_access> const& y) \
476 return boost::operator op(x, y); \
479 inline bool operator op( \
480 basic_iterator<raw_access> const& x \
481 , basic_iterator<raw_access> const& y) \
483 return boost::operator op(x, y); \
486 LUABIND_OPERATOR_ADL_WKND(==)
487 LUABIND_OPERATOR_ADL_WKND(!=)
489 #undef LUABIND_OPERATOR_ADL_WKND
491 } // namespace detail
493 namespace adl
496 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
497 struct index_proxy_tag;
498 #endif
500 template<class Next>
501 class index_proxy
502 : public object_interface<index_proxy<Next> >
504 public:
505 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
506 typedef index_proxy_tag value_wrapper_tag;
507 #endif
509 typedef index_proxy<Next> this_type;
511 template<class Key>
512 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
513 : m_interpreter(interpreter)
514 , m_key_index(lua_gettop(interpreter) + 1)
515 , m_next(next)
517 detail::push(m_interpreter, key);
520 index_proxy(index_proxy const& other)
521 : m_interpreter(other.m_interpreter)
522 , m_key_index(other.m_key_index)
523 , m_next(other.m_next)
525 other.m_interpreter = 0;
528 ~index_proxy()
530 if (m_interpreter)
531 lua_pop(m_interpreter, 1);
534 // This is non-const to prevent conversion on lvalues.
535 operator object();
537 template<class T>
538 this_type& operator=(T const& value)
540 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
541 detail::stack_pop pop(m_interpreter, 1);
543 lua_pushvalue(m_interpreter, m_key_index);
544 detail::push(m_interpreter, value);
545 lua_settable(m_interpreter, -3);
546 return *this;
549 template<class T>
550 index_proxy<this_type> operator[](T const& key)
552 return index_proxy<this_type>(*this, m_interpreter, key);
555 void push(lua_State* interpreter);
557 lua_State* interpreter() const
559 return m_interpreter;
562 private:
563 this_type& operator=(index_proxy<Next> const&);
565 mutable lua_State* m_interpreter;
566 int m_key_index;
568 Next const& m_next;
571 } // namespace adl
573 typedef detail::basic_iterator<detail::basic_access> iterator;
574 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
576 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
577 template<class T>
578 struct value_wrapper_traits<adl::index_proxy<T> >
579 #else
580 template<>
581 struct value_wrapper_traits<adl::index_proxy_tag>
582 #endif
584 typedef boost::mpl::true_ is_specialized;
586 template<class Next>
587 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
589 return proxy.interpreter();
592 template<class Next>
593 static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
595 const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
599 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
600 template<class AccessPolicy>
601 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
602 #else
603 template<>
604 struct value_wrapper_traits<adl::iterator_proxy_tag>
605 #endif
607 typedef boost::mpl::true_ is_specialized;
609 template<class Proxy>
610 static lua_State* interpreter(Proxy const& p)
612 return p.interpreter();
615 template<class Proxy>
616 static void unwrap(lua_State* interpreter, Proxy const& p)
618 // TODO: Why const_cast?
619 const_cast<Proxy&>(p).push(interpreter);
623 namespace adl
625 class object_init
627 protected:
628 object_init()
631 explicit object_init(from_stack const& stack_reference, boost::mpl::true_)
632 : m_handle(stack_reference.interpreter, stack_reference.index)
636 template<class ValueWrapper>
637 explicit object_init(ValueWrapper const& value_wrapper, boost::mpl::false_)
639 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
640 value_wrapper
643 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
644 detail::stack_pop pop(interpreter, 1);
646 handle(interpreter, -1).swap(m_handle);
649 handle m_handle;
652 // An object holds a reference to a Lua value residing
653 // in the registry.
654 class object : public object_interface<object>
656 struct safe_bool_type {};
657 public:
658 object()
661 explicit object(handle const& other)
662 : m_handle(other)
665 explicit object(from_stack const& stack_reference)
666 : m_handle(stack_reference.interpreter, stack_reference.index)
670 template<class T>
671 object(lua_State* interpreter, T const& value)
673 detail::push(interpreter, value);
674 detail::stack_pop pop(interpreter, 1);
675 handle(interpreter, -1).swap(m_handle);
678 template<class T, class Policies>
679 object(lua_State* interpreter, T const& value, Policies const&)
681 detail::push(interpreter, value, Policies());
682 detail::stack_pop pop(interpreter, 1);
683 handle(interpreter, -1).swap(m_handle);
686 void push(lua_State* interpreter) const;
687 lua_State* interpreter() const;
688 bool is_valid() const;
689 operator safe_bool_type*() const;
691 template<class T>
692 index_proxy<object> operator[](T const& key) const
694 return index_proxy<object>(
695 *this, m_handle.interpreter(), key
699 void swap(object& other)
701 m_handle.swap(other.m_handle);
704 private:
705 handle m_handle;
708 inline void object::push(lua_State* interpreter) const
710 m_handle.push(interpreter);
713 inline lua_State* object::interpreter() const
715 return m_handle.interpreter();
718 inline bool object::is_valid() const
720 return m_handle.interpreter() != 0;
723 inline object::operator object::safe_bool_type*() const
725 return is_valid()?(safe_bool_type*)1:0;
728 } // namespace adl
730 using adl::object;
732 template<>
733 struct value_wrapper_traits<object>
735 typedef boost::mpl::true_ is_specialized;
737 static lua_State* interpreter(object const& value)
739 return value.interpreter();
742 static void unwrap(lua_State* interpreter, object const& value)
744 value.push(interpreter);
747 static bool check(...)
749 return true;
753 template<class Next>
754 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
756 assert(interpreter == m_interpreter);
758 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
760 lua_pushvalue(m_interpreter, m_key_index);
761 lua_gettable(m_interpreter, -2);
762 lua_remove(m_interpreter, -2);
765 template<class Next>
766 inline adl::index_proxy<Next>::operator object()
768 detail::stack_pop pop(m_interpreter, 1);
769 push(m_interpreter);
770 return object(from_stack(m_interpreter, -1));
773 template<class AccessPolicy>
774 adl::iterator_proxy<AccessPolicy>::operator object()
776 lua_pushvalue(m_interpreter, m_key_index);
777 AccessPolicy::get(m_interpreter, m_table_index);
778 detail::stack_pop pop(m_interpreter, 1);
779 return object(from_stack(m_interpreter, -1));
782 template<class AccessPolicy>
783 object detail::basic_iterator<AccessPolicy>::key() const
785 return object(m_key);
788 namespace detail
791 template<
792 class T
793 , class ValueWrapper
794 , class Policies
795 , class ErrorPolicy
796 , class ReturnType
798 ReturnType object_cast_aux(
799 ValueWrapper const& value_wrapper
800 , T*
801 , Policies*
802 , ErrorPolicy*
803 , ReturnType*
806 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
807 value_wrapper
810 #ifndef LUABIND_NO_ERROR_CHECKING
811 if (!interpreter)
812 return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(void));
813 #endif
815 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
817 detail::stack_pop pop(interpreter, 1);
819 typedef typename detail::find_conversion_policy<
821 , Policies
822 >::type converter_generator;
824 typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
826 #ifndef LUABIND_NO_ERROR_CHECKING
827 if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
829 return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(T));
831 #endif
833 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
836 template<class T>
837 struct throw_error_policy
839 static T handle_error(lua_State* interpreter, LUABIND_TYPE_INFO type_info)
841 #ifndef LUABIND_NO_EXCEPTIONS
842 throw cast_failed(interpreter, type_info);
843 #else
844 cast_failed_callback_fun e = get_cast_failed_callback();
845 if (e) e(interpreter, type_info);
847 assert(0 && "object_cast failed. If you want to handle this error use "
848 "luabind::set_error_callback()");
849 std::terminate();
850 #endif
854 template<class T>
855 struct nothrow_error_policy
857 static boost::optional<T> handle_error(lua_State*, LUABIND_TYPE_INFO)
859 return boost::optional<T>();
863 } // namespace detail
865 template<class T, class ValueWrapper>
866 T object_cast(ValueWrapper const& value_wrapper)
868 return detail::object_cast_aux(
869 value_wrapper
870 , (T*)0
871 , (detail::null_type*)0
872 , (detail::throw_error_policy<T>*)0
873 , (T*)0
877 template<class T, class ValueWrapper, class Policies>
878 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
880 return detail::object_cast_aux(
881 value_wrapper
882 , (T*)0
883 , (Policies*)0
884 , (detail::throw_error_policy<T>*)0
885 , (T*)0
889 template<class T, class ValueWrapper>
890 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
892 return detail::object_cast_aux(
893 value_wrapper
894 , (T*)0
895 , (detail::null_type*)0
896 , (detail::nothrow_error_policy<T>*)0
897 , (boost::optional<T>*)0
901 template<class T, class ValueWrapper, class Policies>
902 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
904 return detail::object_cast_aux(
905 value_wrapper
906 , (T*)0
907 , (Policies*)0
908 , (detail::nothrow_error_policy<T>*)0
909 , (boost::optional<T>*)0
913 namespace detail
916 template<int Index>
917 struct push_args_from_tuple
919 template<class H, class T, class Policies>
920 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
922 convert_to_lua_p<Index>(L, *x.get_head(), p);
923 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
926 template<class H, class T>
927 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
929 convert_to_lua(L, *x.get_head());
930 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
933 template<class Policies>
934 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
936 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
939 } // namespace detail
941 namespace adl
944 template<class ValueWrapper, class Arguments>
945 struct call_proxy
947 call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
948 : value_wrapper(&value_wrapper)
949 , arguments(arguments)
952 call_proxy(call_proxy const& other)
953 : value_wrapper(other.value_wrapper)
954 , arguments(other.arguments)
956 other.value_wrapper = 0;
959 ~call_proxy()
961 if (value_wrapper)
962 call((detail::null_type*)0);
965 operator object()
967 return call((detail::null_type*)0);
970 template<class Policies>
971 object operator[](Policies const&)
973 return call((Policies*)0);
976 template<class Policies>
977 object call(Policies*)
979 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
980 *value_wrapper
983 value_wrapper_traits<ValueWrapper>::unwrap(
984 interpreter
985 , *value_wrapper
988 value_wrapper = 0;
990 detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
992 if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
994 #ifndef LUABIND_NO_EXCEPTIONS
995 throw luabind::error(interpreter);
996 #else
997 error_callback_fun e = get_error_callback();
998 if (e) e(interpreter);
1000 assert(0 && "the lua function threw an error and exceptions are disabled."
1001 "if you want to handle this error use luabind::set_error_callback()");
1002 std::terminate();
1003 #endif
1006 detail::stack_pop pop(interpreter, 1);
1007 return object(from_stack(interpreter, -1));
1010 mutable ValueWrapper* value_wrapper;
1011 Arguments arguments;
1014 template<class Derived>
1015 call_proxy<Derived, boost::tuples::tuple<> >
1016 object_interface<Derived>::operator()()
1018 return call_proxy<Derived, boost::tuples::tuple<> >(
1019 derived()
1020 , boost::tuples::tuple<>()
1024 } // namespace adl
1026 inline object newtable(lua_State* interpreter)
1028 lua_newtable(interpreter);
1029 detail::stack_pop pop(interpreter, 1);
1030 return object(from_stack(interpreter, -1));
1033 inline object globals(lua_State* interpreter)
1035 lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1036 detail::stack_pop pop(interpreter, 1);
1037 return object(from_stack(interpreter, -1));
1040 template<class ValueWrapper, class K>
1041 inline object gettable(ValueWrapper const& table, K const& key)
1043 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1044 table
1047 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1048 detail::stack_pop pop(interpreter, 2);
1049 detail::push(interpreter, key);
1050 lua_gettable(interpreter, -2);
1051 return object(from_stack(interpreter, -1));
1054 template<class ValueWrapper, class K, class T>
1055 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1057 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1058 table
1061 // TODO: Exception safe?
1063 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1064 detail::stack_pop pop(interpreter, 1);
1065 detail::push(interpreter, key);
1066 detail::push(interpreter, value);
1067 lua_settable(interpreter, -3);
1070 template<class ValueWrapper, class K>
1071 inline object rawget(ValueWrapper const& table, K const& key)
1073 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1074 table
1077 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1078 detail::stack_pop pop(interpreter, 2);
1079 detail::push(interpreter, key);
1080 lua_rawget(interpreter, -2);
1081 return object(from_stack(interpreter, -1));
1084 template<class ValueWrapper, class K, class T>
1085 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1087 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1088 table
1091 // TODO: Exception safe?
1093 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1094 detail::stack_pop pop(interpreter, 1);
1095 detail::push(interpreter, key);
1096 detail::push(interpreter, value);
1097 lua_rawset(interpreter, -3);
1100 template<class ValueWrapper>
1101 inline int type(ValueWrapper const& value)
1103 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1104 value
1107 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1108 detail::stack_pop pop(interpreter, 1);
1109 return lua_type(interpreter, -1);
1112 } // namespace luabind
1114 #endif // LUABIND_OBJECT_050419_HPP