Initial C++0x support.
[luabind.git] / luabind / object.hpp
blobaa54dcf049d79d690d99d13f279012306b6817ce
1 // Copyright (c) 2005 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef LUABIND_OBJECT_050419_HPP
24 #define LUABIND_OBJECT_050419_HPP
26 #include <boost/implicit_cast.hpp> // detail::push()
27 #include <boost/ref.hpp> // detail::push()
28 #include <boost/mpl/bool.hpp> // value_wrapper_traits specializations
29 #include <boost/mpl/apply_wrap.hpp>
30 #include <boost/tuple/tuple.hpp>
31 #include <boost/optional.hpp>
33 #include <luabind/nil.hpp>
34 #include <luabind/value_wrapper.hpp>
35 #include <luabind/detail/pcall.hpp>
36 #include <luabind/handle.hpp>
37 #include <luabind/from_stack.hpp>
38 #include <luabind/detail/policy.hpp>
39 #include <luabind/detail/stack_utils.hpp>
40 #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
41 #include <luabind/typeid.hpp>
43 #include <boost/iterator/iterator_facade.hpp> // iterator
45 #ifndef LUABIND_CPP0x
46 #include <boost/preprocessor/iteration/iterate.hpp>
47 #endif
48 #include <boost/utility/enable_if.hpp>
50 namespace luabind {
52 namespace detail
54 namespace mpl = boost::mpl;
56 template<class T, class ConverterGenerator>
57 void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
59 typedef typename boost::mpl::if_<
60 boost::is_reference_wrapper<T>
61 , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
62 , T
63 >::type unwrapped_type;
65 typename mpl::apply_wrap2<
66 ConverterGenerator,unwrapped_type,cpp_to_lua
67 >::type cv;
69 cv.apply(
70 interpreter
71 , boost::implicit_cast<
72 BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
73 >(value)
77 template<class T, class Policies>
78 void push(lua_State* interpreter, T& value, Policies const&)
80 typedef typename find_conversion_policy<
82 , Policies
83 >::type converter_policy;
85 push_aux(interpreter, value, (converter_policy*)0);
88 template<class T>
89 void push(lua_State* interpreter, T& value)
91 push(interpreter, value, null_type());
94 } // namespace detail
96 namespace adl
98 namespace mpl = boost::mpl;
100 template <class T>
101 class object_interface;
103 namespace is_object_interface_aux
105 typedef char (&yes)[1];
106 typedef char (&no)[2];
108 template <class T>
109 yes check(object_interface<T>*);
110 no check(void*);
112 template <class T>
113 struct impl
115 BOOST_STATIC_CONSTANT(bool, value =
116 sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
119 typedef mpl::bool_<value> type;
122 } // namespace detail
124 template <class T>
125 struct is_object_interface
126 : is_object_interface_aux::impl<T>::type
129 template <class R, class T, class U>
130 struct enable_binary
131 # ifndef BOOST_NO_SFINAE
132 : boost::enable_if<
133 mpl::or_<
134 is_object_interface<T>
135 , is_object_interface<U>
140 # else
142 typedef R type;
144 # endif
146 template<class T, class U>
147 int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs
148 , boost::mpl::true_, boost::mpl::true_)
150 L = value_wrapper_traits<T>::interpreter(lhs);
151 lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs);
153 // you are comparing objects with different interpreters
154 // that's not allowed.
155 assert(L == L2 || L == 0 || L2 == 0);
157 // if the two objects we compare have different interpreters
158 // then they
160 if (L != L2) return -1;
161 if (L == 0) return 1;
162 return 0;
165 template<class T, class U>
166 int binary_interpreter(lua_State*& L, T const& x, U const&
167 , boost::mpl::true_, boost::mpl::false_)
169 L = value_wrapper_traits<T>::interpreter(x);
170 return 0;
173 template<class T, class U>
174 int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
176 L = value_wrapper_traits<U>::interpreter(x);
177 return 0;
180 template<class T, class U>
181 int binary_interpreter(lua_State*& L, T const& x, U const& y)
183 return binary_interpreter(
187 , is_value_wrapper<T>()
188 , is_value_wrapper<U>()
192 #define LUABIND_BINARY_OP_DEF(op, fn) \
193 template<class LHS, class RHS> \
194 typename enable_binary<bool,LHS,RHS>::type \
195 operator op(LHS const& lhs, RHS const& rhs) \
197 lua_State* L = 0; \
198 switch (binary_interpreter(L, lhs, rhs)) \
200 case 1: \
201 return true; \
202 case -1: \
203 return false; \
206 assert(L); \
208 detail::stack_pop pop1(L, 1); \
209 detail::push(L, lhs); \
210 detail::stack_pop pop2(L, 1); \
211 detail::push(L, rhs); \
213 return fn(L, -1, -2) != 0; \
216 LUABIND_BINARY_OP_DEF(==, lua_equal)
217 LUABIND_BINARY_OP_DEF(<, lua_lessthan)
219 template<class ValueWrapper>
220 std::ostream& operator<<(std::ostream& os
221 , object_interface<ValueWrapper> const& v)
223 using namespace luabind;
224 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
225 static_cast<ValueWrapper const&>(v));
226 detail::stack_pop pop(interpreter, 1);
227 value_wrapper_traits<ValueWrapper>::unwrap(interpreter
228 , static_cast<ValueWrapper const&>(v));
229 char const* p = lua_tostring(interpreter, -1);
230 std::size_t len = lua_strlen(interpreter, -1);
231 std::copy(p, p + len, std::ostream_iterator<char>(os));
232 return os;
235 #undef LUABIND_BINARY_OP_DEF
237 template<class LHS, class RHS>
238 typename enable_binary<bool,LHS,RHS>::type
239 operator>(LHS const& lhs, RHS const& rhs)
241 return !(lhs < rhs || lhs == rhs);
244 template<class LHS, class RHS>
245 typename enable_binary<bool,LHS,RHS>::type
246 operator<=(LHS const& lhs, RHS const& rhs)
248 return lhs < rhs || lhs == rhs;
251 template<class LHS, class RHS>
252 typename enable_binary<bool,LHS,RHS>::type
253 operator>=(LHS const& lhs, RHS const& rhs)
255 return !(lhs < rhs);
258 template<class LHS, class RHS>
259 typename enable_binary<bool,LHS,RHS>::type
260 operator!=(LHS const& lhs, RHS const& rhs)
262 return !(lhs == rhs);
265 template<class ValueWrapper, class Arguments>
266 struct call_proxy;
268 template<class Next>
269 class index_proxy;
271 class object;
273 template<class Derived>
274 class object_interface
276 struct safe_bool_type {};
277 public:
278 ~object_interface() {}
280 # ifdef LUABIND_CPP0x
282 template <class... Args>
283 call_proxy<
284 Derived, std::tuple<Args const*...>
285 > operator()(Args const& ...args)
287 typedef std::tuple<Args const*...> arguments;
288 return call_proxy<Derived, arguments>(derived(), arguments(&args...));
291 # else
293 call_proxy<Derived, boost::tuples::tuple<> > operator()();
295 template<class A0>
296 call_proxy<
297 Derived
298 , boost::tuples::tuple<A0 const*>
299 > operator()(A0 const& a0)
301 typedef boost::tuples::tuple<A0 const*> arguments;
303 return call_proxy<Derived, arguments>(
304 derived()
305 , arguments(&a0)
309 template<class A0, class A1>
310 call_proxy<
311 Derived
312 , boost::tuples::tuple<A0 const*, A1 const*>
313 > operator()(A0 const& a0, A1 const& a1)
315 typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
317 return call_proxy<Derived, arguments>(
318 derived()
319 , arguments(&a0, &a1)
323 // The rest of the overloads are PP-generated.
324 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
325 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
326 #include BOOST_PP_ITERATE()
328 # endif // LUABIND_CPP0x
330 operator safe_bool_type*() const
332 lua_State* L = value_wrapper_traits<Derived>::interpreter(derived());
334 if (!L)
335 return 0;
337 value_wrapper_traits<Derived>::unwrap(L, derived());
338 detail::stack_pop pop(L, 1);
340 return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0;
343 private:
344 Derived& derived()
346 return *static_cast<Derived*>(this);
349 Derived const& derived() const
351 return *static_cast<Derived const*>(this);
355 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
356 struct iterator_proxy_tag;
357 #endif
359 template<class AccessPolicy>
360 class iterator_proxy
361 : public object_interface<iterator_proxy<AccessPolicy> >
363 public:
364 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
365 typedef iterator_proxy_tag value_wrapper_tag;
366 #endif
368 iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
369 : m_interpreter(interpreter)
370 , m_table_index(lua_gettop(interpreter) + 1)
371 , m_key_index(m_table_index + 1)
373 table.push(m_interpreter);
374 key.push(m_interpreter);
377 iterator_proxy(iterator_proxy const& other)
378 : m_interpreter(other.m_interpreter)
379 , m_table_index(other.m_table_index)
380 , m_key_index(other.m_key_index)
382 other.m_interpreter = 0;
385 ~iterator_proxy()
387 if (m_interpreter)
388 lua_pop(m_interpreter, 2);
391 // this will set the value to nil
392 iterator_proxy & operator=(luabind::detail::nil_type)
394 lua_pushvalue(m_interpreter, m_key_index);
395 lua_pushnil(m_interpreter);
396 AccessPolicy::set(m_interpreter, m_table_index);
397 return *this;
400 template<class T>
401 iterator_proxy& operator=(T const& value)
403 lua_pushvalue(m_interpreter, m_key_index);
404 detail::push(m_interpreter, value);
405 AccessPolicy::set(m_interpreter, m_table_index);
406 return *this;
409 template<class Key>
410 index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
412 return index_proxy<iterator_proxy<AccessPolicy> >(
413 *this, m_interpreter, key
417 // This is non-const to prevent conversion on lvalues.
418 operator object();
420 lua_State* interpreter() const
422 return m_interpreter;
425 // TODO: Why is it non-const?
426 void push(lua_State* interpreter)
428 assert(interpreter == m_interpreter);
429 lua_pushvalue(m_interpreter, m_key_index);
430 AccessPolicy::get(m_interpreter, m_table_index);
433 private:
434 mutable lua_State* m_interpreter;
435 int m_table_index;
436 int m_key_index;
439 } // namespace adl
441 namespace detail
443 struct basic_access
445 static void set(lua_State* interpreter, int table)
447 lua_settable(interpreter, table);
450 static void get(lua_State* interpreter, int table)
452 lua_gettable(interpreter, table);
456 struct raw_access
458 static void set(lua_State* interpreter, int table)
460 lua_rawset(interpreter, table);
463 static void get(lua_State* interpreter, int table)
465 lua_rawget(interpreter, table);
469 template<class AccessPolicy>
470 class basic_iterator
471 : public boost::iterator_facade<
472 basic_iterator<AccessPolicy>
473 , adl::iterator_proxy<AccessPolicy>
474 , boost::single_pass_traversal_tag
475 , adl::iterator_proxy<AccessPolicy>
478 public:
479 basic_iterator()
480 : m_interpreter(0)
483 template<class ValueWrapper>
484 explicit basic_iterator(ValueWrapper const& value_wrapper)
485 : m_interpreter(
486 value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
489 detail::stack_pop pop(m_interpreter, 1);
490 value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
492 lua_pushnil(m_interpreter);
493 if (lua_next(m_interpreter, -2) != 0)
495 detail::stack_pop pop(m_interpreter, 2);
496 handle(m_interpreter, -2).swap(m_key);
498 else
500 m_interpreter = 0;
501 return;
504 handle(m_interpreter, -1).swap(m_table);
507 adl::object key() const;
509 private:
510 friend class boost::iterator_core_access;
512 void increment()
514 m_table.push(m_interpreter);
515 m_key.push(m_interpreter);
517 detail::stack_pop pop(m_interpreter, 1);
519 if (lua_next(m_interpreter, -2) != 0)
521 m_key.replace(m_interpreter, -2);
522 lua_pop(m_interpreter, 2);
524 else
526 m_interpreter = 0;
527 handle().swap(m_table);
528 handle().swap(m_key);
532 bool equal(basic_iterator const& other) const
534 if (m_interpreter == 0 && other.m_interpreter == 0)
535 return true;
537 if (m_interpreter != other.m_interpreter)
538 return false;
540 detail::stack_pop pop(m_interpreter, 2);
541 m_key.push(m_interpreter);
542 other.m_key.push(m_interpreter);
543 return lua_equal(m_interpreter, -2, -1) != 0;
546 adl::iterator_proxy<AccessPolicy> dereference() const
548 return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
551 lua_State* m_interpreter;
552 handle m_table;
553 handle m_key;
556 // Needed because of some strange ADL issues.
558 #define LUABIND_OPERATOR_ADL_WKND(op) \
559 inline bool operator op( \
560 basic_iterator<basic_access> const& x \
561 , basic_iterator<basic_access> const& y) \
563 return boost::operator op(x, y); \
566 inline bool operator op( \
567 basic_iterator<raw_access> const& x \
568 , basic_iterator<raw_access> const& y) \
570 return boost::operator op(x, y); \
573 LUABIND_OPERATOR_ADL_WKND(==)
574 LUABIND_OPERATOR_ADL_WKND(!=)
576 #undef LUABIND_OPERATOR_ADL_WKND
578 } // namespace detail
580 namespace adl
583 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
584 struct index_proxy_tag;
585 #endif
587 template<class Next>
588 class index_proxy
589 : public object_interface<index_proxy<Next> >
591 public:
592 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
593 typedef index_proxy_tag value_wrapper_tag;
594 #endif
596 typedef index_proxy<Next> this_type;
598 template<class Key>
599 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
600 : m_interpreter(interpreter)
601 , m_key_index(lua_gettop(interpreter) + 1)
602 , m_next(next)
604 detail::push(m_interpreter, key);
607 index_proxy(index_proxy const& other)
608 : m_interpreter(other.m_interpreter)
609 , m_key_index(other.m_key_index)
610 , m_next(other.m_next)
612 other.m_interpreter = 0;
615 ~index_proxy()
617 if (m_interpreter)
618 lua_pop(m_interpreter, 1);
621 // This is non-const to prevent conversion on lvalues.
622 operator object();
624 // this will set the value to nil
625 this_type& operator=(luabind::detail::nil_type)
627 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
628 detail::stack_pop pop(m_interpreter, 1);
630 lua_pushvalue(m_interpreter, m_key_index);
631 lua_pushnil(m_interpreter);
632 lua_settable(m_interpreter, -3);
633 return *this;
636 template<class T>
637 this_type& operator=(T const& value)
639 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
640 detail::stack_pop pop(m_interpreter, 1);
642 lua_pushvalue(m_interpreter, m_key_index);
643 detail::push(m_interpreter, value);
644 lua_settable(m_interpreter, -3);
645 return *this;
648 this_type& operator=(this_type const& value)
650 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
651 detail::stack_pop pop(m_interpreter, 1);
653 lua_pushvalue(m_interpreter, m_key_index);
654 detail::push(m_interpreter, value);
655 lua_settable(m_interpreter, -3);
656 return *this;
659 template<class T>
660 index_proxy<this_type> operator[](T const& key)
662 return index_proxy<this_type>(*this, m_interpreter, key);
665 void push(lua_State* interpreter);
667 lua_State* interpreter() const
669 return m_interpreter;
672 private:
673 struct hidden_type {};
675 // this_type& operator=(index_proxy<Next> const&);
677 mutable lua_State* m_interpreter;
678 int m_key_index;
680 Next const& m_next;
683 } // namespace adl
685 typedef detail::basic_iterator<detail::basic_access> iterator;
686 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
688 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
689 template<class T>
690 struct value_wrapper_traits<adl::index_proxy<T> >
691 #else
692 template<>
693 struct value_wrapper_traits<adl::index_proxy_tag>
694 #endif
696 typedef boost::mpl::true_ is_specialized;
698 template<class Next>
699 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
701 return proxy.interpreter();
704 template<class Next>
705 static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
707 const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
711 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
712 template<class AccessPolicy>
713 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
714 #else
715 template<>
716 struct value_wrapper_traits<adl::iterator_proxy_tag>
717 #endif
719 typedef boost::mpl::true_ is_specialized;
721 template<class Proxy>
722 static lua_State* interpreter(Proxy const& p)
724 return p.interpreter();
727 template<class Proxy>
728 static void unwrap(lua_State* interpreter, Proxy const& p)
730 // TODO: Why const_cast?
731 const_cast<Proxy&>(p).push(interpreter);
735 namespace adl
738 // An object holds a reference to a Lua value residing
739 // in the registry.
740 class object : public object_interface<object>
742 public:
743 object()
746 explicit object(handle const& other)
747 : m_handle(other)
750 explicit object(from_stack const& stack_reference)
751 : m_handle(stack_reference.interpreter, stack_reference.index)
755 template<class T>
756 object(lua_State* interpreter, T const& value)
758 detail::push(interpreter, value);
759 detail::stack_pop pop(interpreter, 1);
760 handle(interpreter, -1).swap(m_handle);
763 template<class T, class Policies>
764 object(lua_State* interpreter, T const& value, Policies const&)
766 detail::push(interpreter, value, Policies());
767 detail::stack_pop pop(interpreter, 1);
768 handle(interpreter, -1).swap(m_handle);
771 void push(lua_State* interpreter) const;
772 lua_State* interpreter() const;
773 bool is_valid() const;
775 template<class T>
776 index_proxy<object> operator[](T const& key) const
778 return index_proxy<object>(
779 *this, m_handle.interpreter(), key
783 void swap(object& other)
785 m_handle.swap(other.m_handle);
788 private:
789 handle m_handle;
792 inline void object::push(lua_State* interpreter) const
794 m_handle.push(interpreter);
797 inline lua_State* object::interpreter() const
799 return m_handle.interpreter();
802 inline bool object::is_valid() const
804 return m_handle.interpreter() != 0;
807 class argument : public object_interface<argument>
809 public:
810 argument(from_stack const& stack_reference)
811 : m_interpreter(stack_reference.interpreter)
812 , m_index(stack_reference.index)
814 if (m_index < 0)
815 m_index = lua_gettop(m_interpreter) - m_index + 1;
818 template<class T>
819 index_proxy<argument> operator[](T const& key) const
821 return index_proxy<argument>(*this, m_interpreter, key);
824 void push(lua_State* L) const
826 lua_pushvalue(L, m_index);
829 lua_State* interpreter() const
831 return m_interpreter;
834 private:
835 lua_State* m_interpreter;
836 int m_index;
839 } // namespace adl
841 using adl::object;
842 using adl::argument;
844 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
845 template <class ValueWrapper, class Arguments>
846 struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
847 #else
848 template<>
849 struct value_wrapper_traits<adl::call_proxy_tag>
850 #endif
852 typedef boost::mpl::true_ is_specialized;
854 template<class W, class A>
855 static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
857 return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
860 template<class W, class A>
861 static void unwrap(lua_State*, adl::call_proxy<W,A> const& proxy)
863 object result = const_cast<adl::call_proxy<W,A>&>(proxy);
864 result.push(result.interpreter());
868 template<>
869 struct value_wrapper_traits<object>
871 typedef boost::mpl::true_ is_specialized;
873 static lua_State* interpreter(object const& value)
875 return value.interpreter();
878 static void unwrap(lua_State* interpreter, object const& value)
880 value.push(interpreter);
883 static bool check(...)
885 return true;
889 template<>
890 struct value_wrapper_traits<argument>
892 typedef boost::mpl::true_ is_specialized;
894 static lua_State* interpreter(argument const& value)
896 return value.interpreter();
899 static void unwrap(lua_State* interpreter, argument const& value)
901 value.push(interpreter);
904 static bool check(...)
906 return true;
910 template<class Next>
911 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
913 assert(interpreter == m_interpreter);
915 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
917 lua_pushvalue(m_interpreter, m_key_index);
918 lua_gettable(m_interpreter, -2);
919 lua_remove(m_interpreter, -2);
922 template<class Next>
923 inline adl::index_proxy<Next>::operator object()
925 detail::stack_pop pop(m_interpreter, 1);
926 push(m_interpreter);
927 return object(from_stack(m_interpreter, -1));
930 template<class AccessPolicy>
931 adl::iterator_proxy<AccessPolicy>::operator object()
933 lua_pushvalue(m_interpreter, m_key_index);
934 AccessPolicy::get(m_interpreter, m_table_index);
935 detail::stack_pop pop(m_interpreter, 1);
936 return object(from_stack(m_interpreter, -1));
939 template<class AccessPolicy>
940 object detail::basic_iterator<AccessPolicy>::key() const
942 return object(m_key);
945 namespace detail
948 template<
949 class T
950 , class ValueWrapper
951 , class Policies
952 , class ErrorPolicy
953 , class ReturnType
955 ReturnType object_cast_aux(
956 ValueWrapper const& value_wrapper
957 , T*
958 , Policies*
959 , ErrorPolicy*
960 , ReturnType*
963 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
964 value_wrapper
967 #ifndef LUABIND_NO_ERROR_CHECKING
968 if (!interpreter)
969 return ErrorPolicy::handle_error(interpreter, typeid(void));
970 #endif
972 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
974 detail::stack_pop pop(interpreter, 1);
976 typedef typename detail::find_conversion_policy<
978 , Policies
979 >::type converter_generator;
981 typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
983 if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
985 return ErrorPolicy::handle_error(interpreter, typeid(T));
988 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
991 # ifdef BOOST_MSVC
992 # pragma warning(push)
993 # pragma warning(disable:4702) // unreachable code
994 # endif
996 template<class T>
997 struct throw_error_policy
999 static T handle_error(lua_State* interpreter, type_id const& type_info)
1001 #ifndef LUABIND_NO_EXCEPTIONS
1002 throw cast_failed(interpreter, type_info);
1003 #else
1004 cast_failed_callback_fun e = get_cast_failed_callback();
1005 if (e) e(interpreter, type_info);
1007 assert(0 && "object_cast failed. If you want to handle this error use "
1008 "luabind::set_error_callback()");
1009 std::terminate();
1010 #endif
1011 return *(typename boost::remove_reference<T>::type*)0;
1015 # ifdef BOOST_MSVC
1016 # pragma warning(pop)
1017 # endif
1019 template<class T>
1020 struct nothrow_error_policy
1022 static boost::optional<T> handle_error(lua_State*, type_id const&)
1024 return boost::optional<T>();
1028 } // namespace detail
1030 template<class T, class ValueWrapper>
1031 T object_cast(ValueWrapper const& value_wrapper)
1033 return detail::object_cast_aux(
1034 value_wrapper
1035 , (T*)0
1036 , (detail::null_type*)0
1037 , (detail::throw_error_policy<T>*)0
1038 , (T*)0
1042 template<class T, class ValueWrapper, class Policies>
1043 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
1045 return detail::object_cast_aux(
1046 value_wrapper
1047 , (T*)0
1048 , (Policies*)0
1049 , (detail::throw_error_policy<T>*)0
1050 , (T*)0
1054 template<class T, class ValueWrapper>
1055 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
1057 return detail::object_cast_aux(
1058 value_wrapper
1059 , (T*)0
1060 , (detail::null_type*)0
1061 , (detail::nothrow_error_policy<T>*)0
1062 , (boost::optional<T>*)0
1066 template<class T, class ValueWrapper, class Policies>
1067 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
1069 return detail::object_cast_aux(
1070 value_wrapper
1071 , (T*)0
1072 , (Policies*)0
1073 , (detail::nothrow_error_policy<T>*)0
1074 , (boost::optional<T>*)0
1078 namespace detail
1081 template<int Index>
1082 struct push_args_from_tuple
1084 # ifdef LUABIND_CPP0x
1086 template <class Args, class Policies, class N, class E>
1087 static void push_args(
1088 lua_State* L, Args const& args, Policies const& policies, N, E)
1090 convert_to_lua_p<N::value + 1>(L, *std::get<N::value>(args), policies);
1091 push_args(
1092 L, args, policies, std::integral_constant<int, N::value + 1>(), E());
1095 template <class Args, class Policies, class E>
1096 static void push_args(lua_State* L, Args const&, Policies const&, E, E)
1099 template <class... Args, class Policies = null_type>
1100 static void apply(
1101 lua_State* L, std::tuple<Args...> const& args
1102 , Policies const policies = Policies())
1104 push_args(
1106 , args
1107 , policies
1108 , std::integral_constant<int, 0>()
1109 , std::integral_constant<int, sizeof...(Args)>()
1113 # else // LUABIND_CPP0x
1115 template<class H, class T, class Policies>
1116 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
1118 convert_to_lua_p<Index>(L, *x.get_head(), p);
1119 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
1122 template<class H, class T>
1123 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
1125 convert_to_lua(L, *x.get_head());
1126 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
1129 template<class Policies>
1130 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
1132 inline static void apply(lua_State*, const boost::tuples::null_type&) {}
1134 # endif // LUABIND_CPP0x
1137 } // namespace detail
1139 namespace adl
1142 template<class ValueWrapper, class Arguments>
1143 struct call_proxy
1145 call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
1146 : value_wrapper(&value_wrapper)
1147 , arguments(arguments)
1150 call_proxy(call_proxy const& other)
1151 : value_wrapper(other.value_wrapper)
1152 , arguments(other.arguments)
1154 other.value_wrapper = 0;
1157 ~call_proxy()
1159 if (value_wrapper)
1160 call((detail::null_type*)0);
1163 operator object()
1165 return call((detail::null_type*)0);
1168 template<class Policies>
1169 object operator[](Policies const&)
1171 return call((Policies*)0);
1174 template<class Policies>
1175 object call(Policies*)
1177 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1178 *value_wrapper
1181 value_wrapper_traits<ValueWrapper>::unwrap(
1182 interpreter
1183 , *value_wrapper
1186 value_wrapper = 0;
1188 detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
1190 # ifdef LUABIND_CPP0x
1191 if (detail::pcall(interpreter, std::tuple_size<Arguments>::value, 1))
1192 # else
1193 if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
1194 # endif
1196 #ifndef LUABIND_NO_EXCEPTIONS
1197 throw luabind::error(interpreter);
1198 #else
1199 error_callback_fun e = get_error_callback();
1200 if (e) e(interpreter);
1202 assert(0 && "the lua function threw an error and exceptions are disabled."
1203 "if you want to handle this error use luabind::set_error_callback()");
1204 std::terminate();
1205 #endif
1208 detail::stack_pop pop(interpreter, 1);
1209 return object(from_stack(interpreter, -1));
1212 mutable ValueWrapper* value_wrapper;
1213 Arguments arguments;
1216 # ifndef LUABIND_CPP0x
1218 template<class Derived>
1219 call_proxy<Derived, boost::tuples::tuple<> >
1220 object_interface<Derived>::operator()()
1222 return call_proxy<Derived, boost::tuples::tuple<> >(
1223 derived()
1224 , boost::tuples::tuple<>()
1228 # endif
1230 // Simple value_wrapper adaptor with the sole purpose of helping with
1231 // overload resolution. Use this as a function parameter type instead
1232 // of "object" or "argument" to restrict the parameter to Lua tables.
1233 template <class Base = object>
1234 struct table : Base
1236 table(from_stack const& stack_reference)
1237 : Base(stack_reference)
1241 } // namespace adl
1243 using adl::table;
1245 template <class Base>
1246 struct value_wrapper_traits<adl::table<Base> >
1247 : value_wrapper_traits<Base>
1249 static bool check(lua_State* L, int idx)
1251 return value_wrapper_traits<Base>::check(L, idx) &&
1252 lua_istable(L, idx);
1256 inline object newtable(lua_State* interpreter)
1258 lua_newtable(interpreter);
1259 detail::stack_pop pop(interpreter, 1);
1260 return object(from_stack(interpreter, -1));
1263 // this could be optimized by returning a proxy
1264 inline object globals(lua_State* interpreter)
1266 lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1267 detail::stack_pop pop(interpreter, 1);
1268 return object(from_stack(interpreter, -1));
1271 // this could be optimized by returning a proxy
1272 inline object registry(lua_State* interpreter)
1274 lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
1275 detail::stack_pop pop(interpreter, 1);
1276 return object(from_stack(interpreter, -1));
1279 template<class ValueWrapper, class K>
1280 inline object gettable(ValueWrapper const& table, K const& key)
1282 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1283 table
1286 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1287 detail::stack_pop pop(interpreter, 2);
1288 detail::push(interpreter, key);
1289 lua_gettable(interpreter, -2);
1290 return object(from_stack(interpreter, -1));
1293 template<class ValueWrapper, class K, class T>
1294 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1296 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1297 table
1300 // TODO: Exception safe?
1302 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1303 detail::stack_pop pop(interpreter, 1);
1304 detail::push(interpreter, key);
1305 detail::push(interpreter, value);
1306 lua_settable(interpreter, -3);
1309 template<class ValueWrapper, class K>
1310 inline object rawget(ValueWrapper const& table, K const& key)
1312 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1313 table
1316 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1317 detail::stack_pop pop(interpreter, 2);
1318 detail::push(interpreter, key);
1319 lua_rawget(interpreter, -2);
1320 return object(from_stack(interpreter, -1));
1323 template<class ValueWrapper, class K, class T>
1324 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1326 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1327 table
1330 // TODO: Exception safe?
1332 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1333 detail::stack_pop pop(interpreter, 1);
1334 detail::push(interpreter, key);
1335 detail::push(interpreter, value);
1336 lua_rawset(interpreter, -3);
1339 template<class ValueWrapper>
1340 inline int type(ValueWrapper const& value)
1342 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1343 value
1346 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1347 detail::stack_pop pop(interpreter, 1);
1348 return lua_type(interpreter, -1);
1351 template <class ValueWrapper>
1352 inline object getmetatable(ValueWrapper const& obj)
1354 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1358 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, obj);
1359 detail::stack_pop pop(interpreter, 2);
1360 lua_getmetatable(interpreter, -1);
1361 return object(from_stack(interpreter, -1));
1364 template <class ValueWrapper1, class ValueWrapper2>
1365 inline void setmetatable(
1366 ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
1368 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1372 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, obj);
1373 detail::stack_pop pop(interpreter, 1);
1374 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, metatable);
1375 lua_setmetatable(interpreter, -2);
1378 template <class ValueWrapper>
1379 inline lua_CFunction tocfunction(ValueWrapper const& value)
1381 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1382 value
1385 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1386 detail::stack_pop pop(interpreter, 1);
1387 return lua_tocfunction(interpreter, -1);
1390 template <class T, class ValueWrapper>
1391 inline T* touserdata(ValueWrapper const& value)
1393 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1394 value
1397 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1398 detail::stack_pop pop(interpreter, 1);
1399 return static_cast<T*>(lua_touserdata(interpreter, -1));
1402 template <class ValueWrapper>
1403 inline object getupvalue(ValueWrapper const& value, int index)
1405 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1406 value
1409 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1410 detail::stack_pop pop(interpreter, 2);
1411 lua_getupvalue(interpreter, -1, index);
1412 return object(from_stack(interpreter, -1));
1415 template <class ValueWrapper1, class ValueWrapper2>
1416 inline void setupvalue(
1417 ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
1419 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1420 function
1423 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, function);
1424 detail::stack_pop pop(interpreter, 1);
1425 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, value);
1426 lua_setupvalue(interpreter, -2, index);
1429 template <class GetValueWrapper>
1430 object property(GetValueWrapper const& get)
1432 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1436 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1437 lua_pushnil(interpreter);
1439 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1440 detail::stack_pop pop(interpreter, 1);
1442 return object(from_stack(interpreter, -1));
1445 template <class GetValueWrapper, class SetValueWrapper>
1446 object property(GetValueWrapper const& get, SetValueWrapper const& set)
1448 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1452 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1453 value_wrapper_traits<SetValueWrapper>::unwrap(interpreter, set);
1455 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1456 detail::stack_pop pop(interpreter, 1);
1458 return object(from_stack(interpreter, -1));
1463 } // namespace luabind
1465 #endif // LUABIND_OBJECT_050419_HPP