Add missing <tuple> include.
[luabind.git] / luabind / object.hpp
blobd1892bf24791837df55144a957a37e08116164ef
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 #ifdef LUABIND_CPP0x
31 # include <tuple>
32 #else
33 # include <boost/tuple/tuple.hpp>
34 #endif
35 #include <boost/optional.hpp>
37 #include <luabind/nil.hpp>
38 #include <luabind/value_wrapper.hpp>
39 #include <luabind/detail/pcall.hpp>
40 #include <luabind/handle.hpp>
41 #include <luabind/from_stack.hpp>
42 #include <luabind/detail/policy.hpp>
43 #include <luabind/detail/stack_utils.hpp>
44 #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
45 #include <luabind/typeid.hpp>
47 #include <boost/iterator/iterator_facade.hpp> // iterator
49 #ifndef LUABIND_CPP0x
50 #include <boost/preprocessor/iteration/iterate.hpp>
51 #endif
52 #include <boost/utility/enable_if.hpp>
54 namespace luabind {
56 namespace detail
58 namespace mpl = boost::mpl;
60 template<class T, class ConverterGenerator>
61 void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
63 typedef typename boost::mpl::if_<
64 boost::is_reference_wrapper<T>
65 , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
66 , T
67 >::type unwrapped_type;
69 typename mpl::apply_wrap2<
70 ConverterGenerator,unwrapped_type,cpp_to_lua
71 >::type cv;
73 cv.apply(
74 interpreter
75 , boost::implicit_cast<
76 BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
77 >(value)
81 template<class T, class Policies>
82 void push(lua_State* interpreter, T& value, Policies const&)
84 typedef typename find_conversion_policy<
86 , Policies
87 >::type converter_policy;
89 push_aux(interpreter, value, (converter_policy*)0);
92 template<class T>
93 void push(lua_State* interpreter, T& value)
95 push(interpreter, value, null_type());
98 } // namespace detail
100 namespace adl
102 namespace mpl = boost::mpl;
104 template <class T>
105 class object_interface;
107 namespace is_object_interface_aux
109 typedef char (&yes)[1];
110 typedef char (&no)[2];
112 template <class T>
113 yes check(object_interface<T>*);
114 no check(void*);
116 template <class T>
117 struct impl
119 BOOST_STATIC_CONSTANT(bool, value =
120 sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
123 typedef mpl::bool_<value> type;
126 } // namespace detail
128 template <class T>
129 struct is_object_interface
130 : is_object_interface_aux::impl<T>::type
133 template <class R, class T, class U>
134 struct enable_binary
135 # ifndef BOOST_NO_SFINAE
136 : boost::enable_if<
137 mpl::or_<
138 is_object_interface<T>
139 , is_object_interface<U>
144 # else
146 typedef R type;
148 # endif
150 template<class T, class U>
151 int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs
152 , boost::mpl::true_, boost::mpl::true_)
154 L = value_wrapper_traits<T>::interpreter(lhs);
155 lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs);
157 // you are comparing objects with different interpreters
158 // that's not allowed.
159 assert(L == L2 || L == 0 || L2 == 0);
161 // if the two objects we compare have different interpreters
162 // then they
164 if (L != L2) return -1;
165 if (L == 0) return 1;
166 return 0;
169 template<class T, class U>
170 int binary_interpreter(lua_State*& L, T const& x, U const&
171 , boost::mpl::true_, boost::mpl::false_)
173 L = value_wrapper_traits<T>::interpreter(x);
174 return 0;
177 template<class T, class U>
178 int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
180 L = value_wrapper_traits<U>::interpreter(x);
181 return 0;
184 template<class T, class U>
185 int binary_interpreter(lua_State*& L, T const& x, U const& y)
187 return binary_interpreter(
191 , is_value_wrapper<T>()
192 , is_value_wrapper<U>()
196 #define LUABIND_BINARY_OP_DEF(op, fn) \
197 template<class LHS, class RHS> \
198 typename enable_binary<bool,LHS,RHS>::type \
199 operator op(LHS const& lhs, RHS const& rhs) \
201 lua_State* L = 0; \
202 switch (binary_interpreter(L, lhs, rhs)) \
204 case 1: \
205 return true; \
206 case -1: \
207 return false; \
210 assert(L); \
212 detail::stack_pop pop1(L, 1); \
213 detail::push(L, lhs); \
214 detail::stack_pop pop2(L, 1); \
215 detail::push(L, rhs); \
217 return fn(L, -1, -2) != 0; \
220 LUABIND_BINARY_OP_DEF(==, lua_equal)
221 LUABIND_BINARY_OP_DEF(<, lua_lessthan)
223 template<class ValueWrapper>
224 std::ostream& operator<<(std::ostream& os
225 , object_interface<ValueWrapper> const& v)
227 using namespace luabind;
228 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
229 static_cast<ValueWrapper const&>(v));
230 detail::stack_pop pop(interpreter, 1);
231 value_wrapper_traits<ValueWrapper>::unwrap(interpreter
232 , static_cast<ValueWrapper const&>(v));
233 char const* p = lua_tostring(interpreter, -1);
234 std::size_t len = lua_strlen(interpreter, -1);
235 std::copy(p, p + len, std::ostream_iterator<char>(os));
236 return os;
239 #undef LUABIND_BINARY_OP_DEF
241 template<class LHS, class RHS>
242 typename enable_binary<bool,LHS,RHS>::type
243 operator>(LHS const& lhs, RHS const& rhs)
245 return !(lhs < rhs || lhs == rhs);
248 template<class LHS, class RHS>
249 typename enable_binary<bool,LHS,RHS>::type
250 operator<=(LHS const& lhs, RHS const& rhs)
252 return lhs < rhs || lhs == rhs;
255 template<class LHS, class RHS>
256 typename enable_binary<bool,LHS,RHS>::type
257 operator>=(LHS const& lhs, RHS const& rhs)
259 return !(lhs < rhs);
262 template<class LHS, class RHS>
263 typename enable_binary<bool,LHS,RHS>::type
264 operator!=(LHS const& lhs, RHS const& rhs)
266 return !(lhs == rhs);
269 template<class ValueWrapper, class Arguments>
270 struct call_proxy;
272 template<class Next>
273 class index_proxy;
275 class object;
277 template<class Derived>
278 class object_interface
280 struct safe_bool_type {};
281 public:
282 ~object_interface() {}
284 # ifdef LUABIND_CPP0x
286 template <class... Args>
287 call_proxy<
288 Derived, std::tuple<Args const*...>
289 > operator()(Args const& ...args)
291 typedef std::tuple<Args const*...> arguments;
292 return call_proxy<Derived, arguments>(derived(), arguments(&args...));
295 # else
297 call_proxy<Derived, boost::tuples::tuple<> > operator()();
299 template<class A0>
300 call_proxy<
301 Derived
302 , boost::tuples::tuple<A0 const*>
303 > operator()(A0 const& a0)
305 typedef boost::tuples::tuple<A0 const*> arguments;
307 return call_proxy<Derived, arguments>(
308 derived()
309 , arguments(&a0)
313 template<class A0, class A1>
314 call_proxy<
315 Derived
316 , boost::tuples::tuple<A0 const*, A1 const*>
317 > operator()(A0 const& a0, A1 const& a1)
319 typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
321 return call_proxy<Derived, arguments>(
322 derived()
323 , arguments(&a0, &a1)
327 // The rest of the overloads are PP-generated.
328 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
329 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
330 #include BOOST_PP_ITERATE()
332 # endif // LUABIND_CPP0x
334 operator safe_bool_type*() const
336 lua_State* L = value_wrapper_traits<Derived>::interpreter(derived());
338 if (!L)
339 return 0;
341 value_wrapper_traits<Derived>::unwrap(L, derived());
342 detail::stack_pop pop(L, 1);
344 return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0;
347 private:
348 Derived& derived()
350 return *static_cast<Derived*>(this);
353 Derived const& derived() const
355 return *static_cast<Derived const*>(this);
359 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
360 struct iterator_proxy_tag;
361 #endif
363 template<class AccessPolicy>
364 class iterator_proxy
365 : public object_interface<iterator_proxy<AccessPolicy> >
367 public:
368 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
369 typedef iterator_proxy_tag value_wrapper_tag;
370 #endif
372 iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
373 : m_interpreter(interpreter)
374 , m_table_index(lua_gettop(interpreter) + 1)
375 , m_key_index(m_table_index + 1)
377 table.push(m_interpreter);
378 key.push(m_interpreter);
381 iterator_proxy(iterator_proxy const& other)
382 : m_interpreter(other.m_interpreter)
383 , m_table_index(other.m_table_index)
384 , m_key_index(other.m_key_index)
386 other.m_interpreter = 0;
389 ~iterator_proxy()
391 if (m_interpreter)
392 lua_pop(m_interpreter, 2);
395 // this will set the value to nil
396 iterator_proxy & operator=(luabind::detail::nil_type)
398 lua_pushvalue(m_interpreter, m_key_index);
399 lua_pushnil(m_interpreter);
400 AccessPolicy::set(m_interpreter, m_table_index);
401 return *this;
404 template<class T>
405 iterator_proxy& operator=(T const& value)
407 lua_pushvalue(m_interpreter, m_key_index);
408 detail::push(m_interpreter, value);
409 AccessPolicy::set(m_interpreter, m_table_index);
410 return *this;
413 template<class Key>
414 index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
416 return index_proxy<iterator_proxy<AccessPolicy> >(
417 *this, m_interpreter, key
421 // This is non-const to prevent conversion on lvalues.
422 operator object();
424 lua_State* interpreter() const
426 return m_interpreter;
429 // TODO: Why is it non-const?
430 void push(lua_State* interpreter)
432 assert(interpreter == m_interpreter);
433 lua_pushvalue(m_interpreter, m_key_index);
434 AccessPolicy::get(m_interpreter, m_table_index);
437 private:
438 mutable lua_State* m_interpreter;
439 int m_table_index;
440 int m_key_index;
443 } // namespace adl
445 namespace detail
447 struct basic_access
449 static void set(lua_State* interpreter, int table)
451 lua_settable(interpreter, table);
454 static void get(lua_State* interpreter, int table)
456 lua_gettable(interpreter, table);
460 struct raw_access
462 static void set(lua_State* interpreter, int table)
464 lua_rawset(interpreter, table);
467 static void get(lua_State* interpreter, int table)
469 lua_rawget(interpreter, table);
473 template<class AccessPolicy>
474 class basic_iterator
475 : public boost::iterator_facade<
476 basic_iterator<AccessPolicy>
477 , adl::iterator_proxy<AccessPolicy>
478 , boost::single_pass_traversal_tag
479 , adl::iterator_proxy<AccessPolicy>
482 public:
483 basic_iterator()
484 : m_interpreter(0)
487 template<class ValueWrapper>
488 explicit basic_iterator(ValueWrapper const& value_wrapper)
489 : m_interpreter(
490 value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
493 detail::stack_pop pop(m_interpreter, 1);
494 value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
496 lua_pushnil(m_interpreter);
497 if (lua_next(m_interpreter, -2) != 0)
499 detail::stack_pop pop(m_interpreter, 2);
500 handle(m_interpreter, -2).swap(m_key);
502 else
504 m_interpreter = 0;
505 return;
508 handle(m_interpreter, -1).swap(m_table);
511 adl::object key() const;
513 private:
514 friend class boost::iterator_core_access;
516 void increment()
518 m_table.push(m_interpreter);
519 m_key.push(m_interpreter);
521 detail::stack_pop pop(m_interpreter, 1);
523 if (lua_next(m_interpreter, -2) != 0)
525 m_key.replace(m_interpreter, -2);
526 lua_pop(m_interpreter, 2);
528 else
530 m_interpreter = 0;
531 handle().swap(m_table);
532 handle().swap(m_key);
536 bool equal(basic_iterator const& other) const
538 if (m_interpreter == 0 && other.m_interpreter == 0)
539 return true;
541 if (m_interpreter != other.m_interpreter)
542 return false;
544 detail::stack_pop pop(m_interpreter, 2);
545 m_key.push(m_interpreter);
546 other.m_key.push(m_interpreter);
547 return lua_equal(m_interpreter, -2, -1) != 0;
550 adl::iterator_proxy<AccessPolicy> dereference() const
552 return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
555 lua_State* m_interpreter;
556 handle m_table;
557 handle m_key;
560 // Needed because of some strange ADL issues.
562 #define LUABIND_OPERATOR_ADL_WKND(op) \
563 inline bool operator op( \
564 basic_iterator<basic_access> const& x \
565 , basic_iterator<basic_access> const& y) \
567 return boost::operator op(x, y); \
570 inline bool operator op( \
571 basic_iterator<raw_access> const& x \
572 , basic_iterator<raw_access> const& y) \
574 return boost::operator op(x, y); \
577 LUABIND_OPERATOR_ADL_WKND(==)
578 LUABIND_OPERATOR_ADL_WKND(!=)
580 #undef LUABIND_OPERATOR_ADL_WKND
582 } // namespace detail
584 namespace adl
587 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
588 struct index_proxy_tag;
589 #endif
591 template<class Next>
592 class index_proxy
593 : public object_interface<index_proxy<Next> >
595 public:
596 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
597 typedef index_proxy_tag value_wrapper_tag;
598 #endif
600 typedef index_proxy<Next> this_type;
602 template<class Key>
603 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
604 : m_interpreter(interpreter)
605 , m_key_index(lua_gettop(interpreter) + 1)
606 , m_next(next)
608 detail::push(m_interpreter, key);
611 index_proxy(index_proxy const& other)
612 : m_interpreter(other.m_interpreter)
613 , m_key_index(other.m_key_index)
614 , m_next(other.m_next)
616 other.m_interpreter = 0;
619 ~index_proxy()
621 if (m_interpreter)
622 lua_pop(m_interpreter, 1);
625 // This is non-const to prevent conversion on lvalues.
626 operator object();
628 // this will set the value to nil
629 this_type& operator=(luabind::detail::nil_type)
631 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
632 detail::stack_pop pop(m_interpreter, 1);
634 lua_pushvalue(m_interpreter, m_key_index);
635 lua_pushnil(m_interpreter);
636 lua_settable(m_interpreter, -3);
637 return *this;
640 template<class T>
641 this_type& operator=(T const& value)
643 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
644 detail::stack_pop pop(m_interpreter, 1);
646 lua_pushvalue(m_interpreter, m_key_index);
647 detail::push(m_interpreter, value);
648 lua_settable(m_interpreter, -3);
649 return *this;
652 this_type& operator=(this_type const& value)
654 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
655 detail::stack_pop pop(m_interpreter, 1);
657 lua_pushvalue(m_interpreter, m_key_index);
658 detail::push(m_interpreter, value);
659 lua_settable(m_interpreter, -3);
660 return *this;
663 template<class T>
664 index_proxy<this_type> operator[](T const& key)
666 return index_proxy<this_type>(*this, m_interpreter, key);
669 void push(lua_State* interpreter);
671 lua_State* interpreter() const
673 return m_interpreter;
676 private:
677 struct hidden_type {};
679 // this_type& operator=(index_proxy<Next> const&);
681 mutable lua_State* m_interpreter;
682 int m_key_index;
684 Next const& m_next;
687 } // namespace adl
689 typedef detail::basic_iterator<detail::basic_access> iterator;
690 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
692 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
693 template<class T>
694 struct value_wrapper_traits<adl::index_proxy<T> >
695 #else
696 template<>
697 struct value_wrapper_traits<adl::index_proxy_tag>
698 #endif
700 typedef boost::mpl::true_ is_specialized;
702 template<class Next>
703 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
705 return proxy.interpreter();
708 template<class Next>
709 static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
711 const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
715 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
716 template<class AccessPolicy>
717 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
718 #else
719 template<>
720 struct value_wrapper_traits<adl::iterator_proxy_tag>
721 #endif
723 typedef boost::mpl::true_ is_specialized;
725 template<class Proxy>
726 static lua_State* interpreter(Proxy const& p)
728 return p.interpreter();
731 template<class Proxy>
732 static void unwrap(lua_State* interpreter, Proxy const& p)
734 // TODO: Why const_cast?
735 const_cast<Proxy&>(p).push(interpreter);
739 namespace adl
742 // An object holds a reference to a Lua value residing
743 // in the registry.
744 class object : public object_interface<object>
746 public:
747 object()
750 explicit object(handle const& other)
751 : m_handle(other)
754 explicit object(from_stack const& stack_reference)
755 : m_handle(stack_reference.interpreter, stack_reference.index)
759 template<class T>
760 object(lua_State* interpreter, T const& value)
762 detail::push(interpreter, value);
763 detail::stack_pop pop(interpreter, 1);
764 handle(interpreter, -1).swap(m_handle);
767 template<class T, class Policies>
768 object(lua_State* interpreter, T const& value, Policies const&)
770 detail::push(interpreter, value, Policies());
771 detail::stack_pop pop(interpreter, 1);
772 handle(interpreter, -1).swap(m_handle);
775 void push(lua_State* interpreter) const;
776 lua_State* interpreter() const;
777 bool is_valid() const;
779 template<class T>
780 index_proxy<object> operator[](T const& key) const
782 return index_proxy<object>(
783 *this, m_handle.interpreter(), key
787 void swap(object& other)
789 m_handle.swap(other.m_handle);
792 private:
793 handle m_handle;
796 inline void object::push(lua_State* interpreter) const
798 m_handle.push(interpreter);
801 inline lua_State* object::interpreter() const
803 return m_handle.interpreter();
806 inline bool object::is_valid() const
808 return m_handle.interpreter() != 0;
811 class argument : public object_interface<argument>
813 public:
814 argument(from_stack const& stack_reference)
815 : m_interpreter(stack_reference.interpreter)
816 , m_index(stack_reference.index)
818 if (m_index < 0)
819 m_index = lua_gettop(m_interpreter) - m_index + 1;
822 template<class T>
823 index_proxy<argument> operator[](T const& key) const
825 return index_proxy<argument>(*this, m_interpreter, key);
828 void push(lua_State* L) const
830 lua_pushvalue(L, m_index);
833 lua_State* interpreter() const
835 return m_interpreter;
838 private:
839 lua_State* m_interpreter;
840 int m_index;
843 } // namespace adl
845 using adl::object;
846 using adl::argument;
848 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
849 template <class ValueWrapper, class Arguments>
850 struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
851 #else
852 template<>
853 struct value_wrapper_traits<adl::call_proxy_tag>
854 #endif
856 typedef boost::mpl::true_ is_specialized;
858 template<class W, class A>
859 static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
861 return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
864 template<class W, class A>
865 static void unwrap(lua_State*, adl::call_proxy<W,A> const& proxy)
867 object result = const_cast<adl::call_proxy<W,A>&>(proxy);
868 result.push(result.interpreter());
872 template<>
873 struct value_wrapper_traits<object>
875 typedef boost::mpl::true_ is_specialized;
877 static lua_State* interpreter(object const& value)
879 return value.interpreter();
882 static void unwrap(lua_State* interpreter, object const& value)
884 value.push(interpreter);
887 static bool check(...)
889 return true;
893 template<>
894 struct value_wrapper_traits<argument>
896 typedef boost::mpl::true_ is_specialized;
898 static lua_State* interpreter(argument const& value)
900 return value.interpreter();
903 static void unwrap(lua_State* interpreter, argument const& value)
905 value.push(interpreter);
908 static bool check(...)
910 return true;
914 template<class Next>
915 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
917 assert(interpreter == m_interpreter);
919 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
921 lua_pushvalue(m_interpreter, m_key_index);
922 lua_gettable(m_interpreter, -2);
923 lua_remove(m_interpreter, -2);
926 template<class Next>
927 inline adl::index_proxy<Next>::operator object()
929 detail::stack_pop pop(m_interpreter, 1);
930 push(m_interpreter);
931 return object(from_stack(m_interpreter, -1));
934 template<class AccessPolicy>
935 adl::iterator_proxy<AccessPolicy>::operator object()
937 lua_pushvalue(m_interpreter, m_key_index);
938 AccessPolicy::get(m_interpreter, m_table_index);
939 detail::stack_pop pop(m_interpreter, 1);
940 return object(from_stack(m_interpreter, -1));
943 template<class AccessPolicy>
944 object detail::basic_iterator<AccessPolicy>::key() const
946 return object(m_key);
949 namespace detail
952 template<
953 class T
954 , class ValueWrapper
955 , class Policies
956 , class ErrorPolicy
957 , class ReturnType
959 ReturnType object_cast_aux(
960 ValueWrapper const& value_wrapper
961 , T*
962 , Policies*
963 , ErrorPolicy*
964 , ReturnType*
967 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
968 value_wrapper
971 #ifndef LUABIND_NO_ERROR_CHECKING
972 if (!interpreter)
973 return ErrorPolicy::handle_error(interpreter, typeid(void));
974 #endif
976 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
978 detail::stack_pop pop(interpreter, 1);
980 typedef typename detail::find_conversion_policy<
982 , Policies
983 >::type converter_generator;
985 typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
987 if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
989 return ErrorPolicy::handle_error(interpreter, typeid(T));
992 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
995 # ifdef BOOST_MSVC
996 # pragma warning(push)
997 # pragma warning(disable:4702) // unreachable code
998 # endif
1000 template<class T>
1001 struct throw_error_policy
1003 static T handle_error(lua_State* interpreter, type_id const& type_info)
1005 #ifndef LUABIND_NO_EXCEPTIONS
1006 throw cast_failed(interpreter, type_info);
1007 #else
1008 cast_failed_callback_fun e = get_cast_failed_callback();
1009 if (e) e(interpreter, type_info);
1011 assert(0 && "object_cast failed. If you want to handle this error use "
1012 "luabind::set_error_callback()");
1013 std::terminate();
1014 #endif
1015 return *(typename boost::remove_reference<T>::type*)0;
1019 # ifdef BOOST_MSVC
1020 # pragma warning(pop)
1021 # endif
1023 template<class T>
1024 struct nothrow_error_policy
1026 static boost::optional<T> handle_error(lua_State*, type_id const&)
1028 return boost::optional<T>();
1032 } // namespace detail
1034 template<class T, class ValueWrapper>
1035 T object_cast(ValueWrapper const& value_wrapper)
1037 return detail::object_cast_aux(
1038 value_wrapper
1039 , (T*)0
1040 , (detail::null_type*)0
1041 , (detail::throw_error_policy<T>*)0
1042 , (T*)0
1046 template<class T, class ValueWrapper, class Policies>
1047 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
1049 return detail::object_cast_aux(
1050 value_wrapper
1051 , (T*)0
1052 , (Policies*)0
1053 , (detail::throw_error_policy<T>*)0
1054 , (T*)0
1058 template<class T, class ValueWrapper>
1059 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
1061 return detail::object_cast_aux(
1062 value_wrapper
1063 , (T*)0
1064 , (detail::null_type*)0
1065 , (detail::nothrow_error_policy<T>*)0
1066 , (boost::optional<T>*)0
1070 template<class T, class ValueWrapper, class Policies>
1071 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
1073 return detail::object_cast_aux(
1074 value_wrapper
1075 , (T*)0
1076 , (Policies*)0
1077 , (detail::nothrow_error_policy<T>*)0
1078 , (boost::optional<T>*)0
1082 namespace detail
1085 template<int Index>
1086 struct push_args_from_tuple
1088 # ifdef LUABIND_CPP0x
1090 template <class Args, class Policies, class N, class E>
1091 static void push_args(
1092 lua_State* L, Args const& args, Policies const& policies, N, E)
1094 convert_to_lua_p<N::value + 1>(L, *std::get<N::value>(args), policies);
1095 push_args(
1096 L, args, policies, std::integral_constant<int, N::value + 1>(), E());
1099 template <class Args, class Policies, class E>
1100 static void push_args(lua_State* L, Args const&, Policies const&, E, E)
1103 template <class... Args, class Policies = null_type>
1104 static void apply(
1105 lua_State* L, std::tuple<Args...> const& args
1106 , Policies const policies = Policies())
1108 push_args(
1110 , args
1111 , policies
1112 , std::integral_constant<int, 0>()
1113 , std::integral_constant<int, sizeof...(Args)>()
1117 # else // LUABIND_CPP0x
1119 template<class H, class T, class Policies>
1120 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
1122 convert_to_lua_p<Index>(L, *x.get_head(), p);
1123 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
1126 template<class H, class T>
1127 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
1129 convert_to_lua(L, *x.get_head());
1130 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
1133 template<class Policies>
1134 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
1136 inline static void apply(lua_State*, const boost::tuples::null_type&) {}
1138 # endif // LUABIND_CPP0x
1141 } // namespace detail
1143 namespace adl
1146 template<class ValueWrapper, class Arguments>
1147 struct call_proxy
1149 call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
1150 : value_wrapper(&value_wrapper)
1151 , arguments(arguments)
1154 call_proxy(call_proxy const& other)
1155 : value_wrapper(other.value_wrapper)
1156 , arguments(other.arguments)
1158 other.value_wrapper = 0;
1161 ~call_proxy()
1163 if (value_wrapper)
1164 call((detail::null_type*)0);
1167 operator object()
1169 return call((detail::null_type*)0);
1172 template<class Policies>
1173 object operator[](Policies const&)
1175 return call((Policies*)0);
1178 template<class Policies>
1179 object call(Policies*)
1181 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1182 *value_wrapper
1185 value_wrapper_traits<ValueWrapper>::unwrap(
1186 interpreter
1187 , *value_wrapper
1190 value_wrapper = 0;
1192 detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
1194 # ifdef LUABIND_CPP0x
1195 if (detail::pcall(interpreter, std::tuple_size<Arguments>::value, 1))
1196 # else
1197 if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
1198 # endif
1200 #ifndef LUABIND_NO_EXCEPTIONS
1201 throw luabind::error(interpreter);
1202 #else
1203 error_callback_fun e = get_error_callback();
1204 if (e) e(interpreter);
1206 assert(0 && "the lua function threw an error and exceptions are disabled."
1207 "if you want to handle this error use luabind::set_error_callback()");
1208 std::terminate();
1209 #endif
1212 detail::stack_pop pop(interpreter, 1);
1213 return object(from_stack(interpreter, -1));
1216 mutable ValueWrapper* value_wrapper;
1217 Arguments arguments;
1220 # ifndef LUABIND_CPP0x
1222 template<class Derived>
1223 call_proxy<Derived, boost::tuples::tuple<> >
1224 object_interface<Derived>::operator()()
1226 return call_proxy<Derived, boost::tuples::tuple<> >(
1227 derived()
1228 , boost::tuples::tuple<>()
1232 # endif
1234 // Simple value_wrapper adaptor with the sole purpose of helping with
1235 // overload resolution. Use this as a function parameter type instead
1236 // of "object" or "argument" to restrict the parameter to Lua tables.
1237 template <class Base = object>
1238 struct table : Base
1240 table(from_stack const& stack_reference)
1241 : Base(stack_reference)
1245 } // namespace adl
1247 using adl::table;
1249 template <class Base>
1250 struct value_wrapper_traits<adl::table<Base> >
1251 : value_wrapper_traits<Base>
1253 static bool check(lua_State* L, int idx)
1255 return value_wrapper_traits<Base>::check(L, idx) &&
1256 lua_istable(L, idx);
1260 inline object newtable(lua_State* interpreter)
1262 lua_newtable(interpreter);
1263 detail::stack_pop pop(interpreter, 1);
1264 return object(from_stack(interpreter, -1));
1267 // this could be optimized by returning a proxy
1268 inline object globals(lua_State* interpreter)
1270 lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1271 detail::stack_pop pop(interpreter, 1);
1272 return object(from_stack(interpreter, -1));
1275 // this could be optimized by returning a proxy
1276 inline object registry(lua_State* interpreter)
1278 lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
1279 detail::stack_pop pop(interpreter, 1);
1280 return object(from_stack(interpreter, -1));
1283 template<class ValueWrapper, class K>
1284 inline object gettable(ValueWrapper const& table, K const& key)
1286 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1287 table
1290 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1291 detail::stack_pop pop(interpreter, 2);
1292 detail::push(interpreter, key);
1293 lua_gettable(interpreter, -2);
1294 return object(from_stack(interpreter, -1));
1297 template<class ValueWrapper, class K, class T>
1298 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1300 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1301 table
1304 // TODO: Exception safe?
1306 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1307 detail::stack_pop pop(interpreter, 1);
1308 detail::push(interpreter, key);
1309 detail::push(interpreter, value);
1310 lua_settable(interpreter, -3);
1313 template<class ValueWrapper, class K>
1314 inline object rawget(ValueWrapper const& table, K const& key)
1316 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1317 table
1320 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1321 detail::stack_pop pop(interpreter, 2);
1322 detail::push(interpreter, key);
1323 lua_rawget(interpreter, -2);
1324 return object(from_stack(interpreter, -1));
1327 template<class ValueWrapper, class K, class T>
1328 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1330 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1331 table
1334 // TODO: Exception safe?
1336 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1337 detail::stack_pop pop(interpreter, 1);
1338 detail::push(interpreter, key);
1339 detail::push(interpreter, value);
1340 lua_rawset(interpreter, -3);
1343 template<class ValueWrapper>
1344 inline int type(ValueWrapper const& value)
1346 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1347 value
1350 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1351 detail::stack_pop pop(interpreter, 1);
1352 return lua_type(interpreter, -1);
1355 template <class ValueWrapper>
1356 inline object getmetatable(ValueWrapper const& obj)
1358 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1362 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, obj);
1363 detail::stack_pop pop(interpreter, 2);
1364 lua_getmetatable(interpreter, -1);
1365 return object(from_stack(interpreter, -1));
1368 template <class ValueWrapper1, class ValueWrapper2>
1369 inline void setmetatable(
1370 ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
1372 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1376 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, obj);
1377 detail::stack_pop pop(interpreter, 1);
1378 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, metatable);
1379 lua_setmetatable(interpreter, -2);
1382 template <class ValueWrapper>
1383 inline lua_CFunction tocfunction(ValueWrapper const& value)
1385 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1386 value
1389 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1390 detail::stack_pop pop(interpreter, 1);
1391 return lua_tocfunction(interpreter, -1);
1394 template <class T, class ValueWrapper>
1395 inline T* touserdata(ValueWrapper const& value)
1397 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1398 value
1401 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1402 detail::stack_pop pop(interpreter, 1);
1403 return static_cast<T*>(lua_touserdata(interpreter, -1));
1406 template <class ValueWrapper>
1407 inline object getupvalue(ValueWrapper const& value, int index)
1409 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1410 value
1413 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1414 detail::stack_pop pop(interpreter, 2);
1415 lua_getupvalue(interpreter, -1, index);
1416 return object(from_stack(interpreter, -1));
1419 template <class ValueWrapper1, class ValueWrapper2>
1420 inline void setupvalue(
1421 ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
1423 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1424 function
1427 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, function);
1428 detail::stack_pop pop(interpreter, 1);
1429 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, value);
1430 lua_setupvalue(interpreter, -2, index);
1433 template <class GetValueWrapper>
1434 object property(GetValueWrapper const& get)
1436 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1440 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1441 lua_pushnil(interpreter);
1443 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1444 detail::stack_pop pop(interpreter, 1);
1446 return object(from_stack(interpreter, -1));
1449 template <class GetValueWrapper, class SetValueWrapper>
1450 object property(GetValueWrapper const& get, SetValueWrapper const& set)
1452 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1456 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1457 value_wrapper_traits<SetValueWrapper>::unwrap(interpreter, set);
1459 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1460 detail::stack_pop pop(interpreter, 1);
1462 return object(from_stack(interpreter, -1));
1467 } // namespace luabind
1469 #endif // LUABIND_OBJECT_050419_HPP