Fix LUABIND_ERROR_CHECKING conversion bug.
[luabind.git] / luabind / object.hpp
blobe0be5f58a0b568daeff5aa893963dfbc785c6493
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 #include <boost/preprocessor/iteration/iterate.hpp>
46 #include <boost/utility/enable_if.hpp>
48 namespace luabind {
50 namespace detail
52 namespace mpl = boost::mpl;
54 template<class T, class ConverterGenerator>
55 void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
57 typedef typename boost::mpl::if_<
58 boost::is_reference_wrapper<T>
59 , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
60 , T
61 >::type unwrapped_type;
63 typename mpl::apply_wrap2<
64 ConverterGenerator,unwrapped_type,cpp_to_lua
65 >::type cv;
67 cv.apply(
68 interpreter
69 , boost::implicit_cast<
70 BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
71 >(value)
75 template<class T, class Policies>
76 void push(lua_State* interpreter, T& value, Policies const&)
78 typedef typename find_conversion_policy<
80 , Policies
81 >::type converter_policy;
83 push_aux(interpreter, value, (converter_policy*)0);
86 template<class T>
87 void push(lua_State* interpreter, T& value)
89 push(interpreter, value, null_type());
92 } // namespace detail
94 namespace adl
96 namespace mpl = boost::mpl;
98 template <class T>
99 class object_interface;
101 namespace is_object_interface_aux
103 typedef char (&yes)[1];
104 typedef char (&no)[2];
106 template <class T>
107 yes check(object_interface<T>*);
108 no check(void*);
110 template <class T>
111 struct impl
113 BOOST_STATIC_CONSTANT(bool, value =
114 sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
117 typedef mpl::bool_<value> type;
120 } // namespace detail
122 template <class T>
123 struct is_object_interface
124 : is_object_interface_aux::impl<T>::type
127 template <class R, class T, class U>
128 struct enable_binary
129 # ifndef BOOST_NO_SFINAE
130 : boost::enable_if<
131 mpl::or_<
132 is_object_interface<T>
133 , is_object_interface<U>
138 # else
140 typedef R type;
142 # endif
144 template<class T, class U>
145 int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs
146 , boost::mpl::true_, boost::mpl::true_)
148 L = value_wrapper_traits<T>::interpreter(lhs);
149 lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs);
151 // you are comparing objects with different interpreters
152 // that's not allowed.
153 assert(L == L2 || L == 0 || L2 == 0);
155 // if the two objects we compare have different interpreters
156 // then they
158 if (L != L2) return -1;
159 if (L == 0) return 1;
160 return 0;
163 template<class T, class U>
164 int binary_interpreter(lua_State*& L, T const& x, U const&
165 , boost::mpl::true_, boost::mpl::false_)
167 L = value_wrapper_traits<T>::interpreter(x);
168 return 0;
171 template<class T, class U>
172 int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
174 L = value_wrapper_traits<U>::interpreter(x);
175 return 0;
178 template<class T, class U>
179 int binary_interpreter(lua_State*& L, T const& x, U const& y)
181 return binary_interpreter(
185 , is_value_wrapper<T>()
186 , is_value_wrapper<U>()
190 #define LUABIND_BINARY_OP_DEF(op, fn) \
191 template<class LHS, class RHS> \
192 typename enable_binary<bool,LHS,RHS>::type \
193 operator op(LHS const& lhs, RHS const& rhs) \
195 lua_State* L = 0; \
196 switch (binary_interpreter(L, lhs, rhs)) \
198 case 1: \
199 return true; \
200 case -1: \
201 return false; \
204 assert(L); \
206 detail::stack_pop pop1(L, 1); \
207 detail::push(L, lhs); \
208 detail::stack_pop pop2(L, 1); \
209 detail::push(L, rhs); \
211 return fn(L, -1, -2) != 0; \
214 LUABIND_BINARY_OP_DEF(==, lua_equal)
215 LUABIND_BINARY_OP_DEF(<, lua_lessthan)
217 template<class ValueWrapper>
218 std::ostream& operator<<(std::ostream& os
219 , object_interface<ValueWrapper> const& v)
221 using namespace luabind;
222 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
223 static_cast<ValueWrapper const&>(v));
224 detail::stack_pop pop(interpreter, 1);
225 value_wrapper_traits<ValueWrapper>::unwrap(interpreter
226 , static_cast<ValueWrapper const&>(v));
227 char const* p = lua_tostring(interpreter, -1);
228 int len = lua_strlen(interpreter, -1);
229 std::copy(p, p + len, std::ostream_iterator<char>(os));
230 return os;
233 #undef LUABIND_BINARY_OP_DEF
235 template<class LHS, class RHS>
236 typename enable_binary<bool,LHS,RHS>::type
237 operator>(LHS const& lhs, RHS const& rhs)
239 return !(lhs < rhs || lhs == rhs);
242 template<class LHS, class RHS>
243 typename enable_binary<bool,LHS,RHS>::type
244 operator<=(LHS const& lhs, RHS const& rhs)
246 return lhs < rhs || lhs == rhs;
249 template<class LHS, class RHS>
250 typename enable_binary<bool,LHS,RHS>::type
251 operator>=(LHS const& lhs, RHS const& rhs)
253 return !(lhs < rhs);
256 template<class LHS, class RHS>
257 typename enable_binary<bool,LHS,RHS>::type
258 operator!=(LHS const& lhs, RHS const& rhs)
260 return !(lhs < rhs);
263 template<class ValueWrapper, class Arguments>
264 struct call_proxy;
266 template<class Next>
267 class index_proxy;
269 class object;
271 template<class Derived>
272 class object_interface
274 struct safe_bool_type {};
275 public:
276 ~object_interface() {}
278 call_proxy<Derived, boost::tuples::tuple<> > operator()();
280 template<class A0>
281 call_proxy<
282 Derived
283 , boost::tuples::tuple<A0 const*>
284 > operator()(A0 const& a0)
286 typedef boost::tuples::tuple<A0 const*> arguments;
288 return call_proxy<Derived, arguments>(
289 derived()
290 , arguments(&a0)
294 template<class A0, class A1>
295 call_proxy<
296 Derived
297 , boost::tuples::tuple<A0 const*, A1 const*>
298 > operator()(A0 const& a0, A1 const& a1)
300 typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
302 return call_proxy<Derived, arguments>(
303 derived()
304 , arguments(&a0, &a1)
308 // The rest of the overloads are PP-generated.
309 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
310 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
311 #include BOOST_PP_ITERATE()
313 operator safe_bool_type*() const
315 lua_State* L = value_wrapper_traits<Derived>::interpreter(derived());
317 if (!L)
318 return 0;
320 value_wrapper_traits<Derived>::unwrap(L, derived());
321 detail::stack_pop pop(L, 1);
323 return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0;
326 private:
327 Derived& derived()
329 return *static_cast<Derived*>(this);
332 Derived const& derived() const
334 return *static_cast<Derived const*>(this);
338 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
339 struct iterator_proxy_tag;
340 #endif
342 template<class AccessPolicy>
343 class iterator_proxy
344 : public object_interface<iterator_proxy<AccessPolicy> >
346 public:
347 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
348 typedef iterator_proxy_tag value_wrapper_tag;
349 #endif
351 iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
352 : m_interpreter(interpreter)
353 , m_table_index(lua_gettop(interpreter) + 1)
354 , m_key_index(m_table_index + 1)
356 table.push(m_interpreter);
357 key.push(m_interpreter);
360 iterator_proxy(iterator_proxy const& other)
361 : m_interpreter(other.m_interpreter)
362 , m_table_index(other.m_table_index)
363 , m_key_index(other.m_key_index)
365 other.m_interpreter = 0;
368 ~iterator_proxy()
370 if (m_interpreter)
371 lua_pop(m_interpreter, 2);
374 // this will set the value to nil
375 iterator_proxy & operator=(luabind::detail::nil_type)
377 lua_pushvalue(m_interpreter, m_key_index);
378 lua_pushnil(m_interpreter);
379 AccessPolicy::set(m_interpreter, m_table_index);
380 return *this;
383 template<class T>
384 iterator_proxy& operator=(T const& value)
386 lua_pushvalue(m_interpreter, m_key_index);
387 detail::push(m_interpreter, value);
388 AccessPolicy::set(m_interpreter, m_table_index);
389 return *this;
392 template<class Key>
393 index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
395 return index_proxy<iterator_proxy<AccessPolicy> >(
396 *this, m_interpreter, key
400 // This is non-const to prevent conversion on lvalues.
401 operator object();
403 lua_State* interpreter() const
405 return m_interpreter;
408 // TODO: Why is it non-const?
409 void push(lua_State* interpreter)
411 assert(interpreter == m_interpreter);
412 lua_pushvalue(m_interpreter, m_key_index);
413 AccessPolicy::get(m_interpreter, m_table_index);
416 private:
417 mutable lua_State* m_interpreter;
418 int m_table_index;
419 int m_key_index;
422 } // namespace adl
424 namespace detail
426 struct basic_access
428 static void set(lua_State* interpreter, int table)
430 lua_settable(interpreter, table);
433 static void get(lua_State* interpreter, int table)
435 lua_gettable(interpreter, table);
439 struct raw_access
441 static void set(lua_State* interpreter, int table)
443 lua_rawset(interpreter, table);
446 static void get(lua_State* interpreter, int table)
448 lua_rawget(interpreter, table);
452 template<class AccessPolicy>
453 class basic_iterator
454 : public boost::iterator_facade<
455 basic_iterator<AccessPolicy>
456 , adl::iterator_proxy<AccessPolicy>
457 , boost::single_pass_traversal_tag
458 , adl::iterator_proxy<AccessPolicy>
461 public:
462 basic_iterator()
463 : m_interpreter(0)
466 template<class ValueWrapper>
467 explicit basic_iterator(ValueWrapper const& value_wrapper)
468 : m_interpreter(
469 value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
472 detail::stack_pop pop(m_interpreter, 1);
473 value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
475 lua_pushnil(m_interpreter);
476 if (lua_next(m_interpreter, -2) != 0)
478 detail::stack_pop pop(m_interpreter, 2);
479 handle(m_interpreter, -2).swap(m_key);
481 else
483 m_interpreter = 0;
484 return;
487 handle(m_interpreter, -1).swap(m_table);
490 adl::object key() const;
492 private:
493 friend class boost::iterator_core_access;
495 void increment()
497 m_table.push(m_interpreter);
498 m_key.push(m_interpreter);
500 detail::stack_pop pop(m_interpreter, 1);
502 if (lua_next(m_interpreter, -2) != 0)
504 m_key.replace(m_interpreter, -2);
505 lua_pop(m_interpreter, 2);
507 else
509 m_interpreter = 0;
510 handle().swap(m_table);
511 handle().swap(m_key);
515 bool equal(basic_iterator const& other) const
517 if (m_interpreter == 0 && other.m_interpreter == 0)
518 return true;
520 if (m_interpreter != other.m_interpreter)
521 return false;
523 detail::stack_pop pop(m_interpreter, 2);
524 m_key.push(m_interpreter);
525 other.m_key.push(m_interpreter);
526 return lua_equal(m_interpreter, -2, -1) != 0;
529 adl::iterator_proxy<AccessPolicy> dereference() const
531 return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
534 lua_State* m_interpreter;
535 handle m_table;
536 handle m_key;
539 // Needed because of some strange ADL issues.
541 #define LUABIND_OPERATOR_ADL_WKND(op) \
542 inline bool operator op( \
543 basic_iterator<basic_access> const& x \
544 , basic_iterator<basic_access> const& y) \
546 return boost::operator op(x, y); \
549 inline bool operator op( \
550 basic_iterator<raw_access> const& x \
551 , basic_iterator<raw_access> const& y) \
553 return boost::operator op(x, y); \
556 LUABIND_OPERATOR_ADL_WKND(==)
557 LUABIND_OPERATOR_ADL_WKND(!=)
559 #undef LUABIND_OPERATOR_ADL_WKND
561 } // namespace detail
563 namespace adl
566 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
567 struct index_proxy_tag;
568 #endif
570 template<class Next>
571 class index_proxy
572 : public object_interface<index_proxy<Next> >
574 public:
575 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
576 typedef index_proxy_tag value_wrapper_tag;
577 #endif
579 typedef index_proxy<Next> this_type;
581 template<class Key>
582 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
583 : m_interpreter(interpreter)
584 , m_key_index(lua_gettop(interpreter) + 1)
585 , m_next(next)
587 detail::push(m_interpreter, key);
590 index_proxy(index_proxy const& other)
591 : m_interpreter(other.m_interpreter)
592 , m_key_index(other.m_key_index)
593 , m_next(other.m_next)
595 other.m_interpreter = 0;
598 ~index_proxy()
600 if (m_interpreter)
601 lua_pop(m_interpreter, 1);
604 // This is non-const to prevent conversion on lvalues.
605 operator object();
607 // this will set the value to nil
608 this_type& operator=(luabind::detail::nil_type)
610 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
611 detail::stack_pop pop(m_interpreter, 1);
613 lua_pushvalue(m_interpreter, m_key_index);
614 lua_pushnil(m_interpreter);
615 lua_settable(m_interpreter, -3);
616 return *this;
619 template<class T>
620 this_type& operator=(T const& value)
622 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
623 detail::stack_pop pop(m_interpreter, 1);
625 lua_pushvalue(m_interpreter, m_key_index);
626 detail::push(m_interpreter, value);
627 lua_settable(m_interpreter, -3);
628 return *this;
631 this_type& operator=(this_type const& value)
633 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
634 detail::stack_pop pop(m_interpreter, 1);
636 lua_pushvalue(m_interpreter, m_key_index);
637 detail::push(m_interpreter, value);
638 lua_settable(m_interpreter, -3);
639 return *this;
642 template<class T>
643 index_proxy<this_type> operator[](T const& key)
645 return index_proxy<this_type>(*this, m_interpreter, key);
648 void push(lua_State* interpreter);
650 lua_State* interpreter() const
652 return m_interpreter;
655 private:
656 struct hidden_type {};
658 // this_type& operator=(index_proxy<Next> const&);
660 mutable lua_State* m_interpreter;
661 int m_key_index;
663 Next const& m_next;
666 } // namespace adl
668 typedef detail::basic_iterator<detail::basic_access> iterator;
669 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
671 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
672 template<class T>
673 struct value_wrapper_traits<adl::index_proxy<T> >
674 #else
675 template<>
676 struct value_wrapper_traits<adl::index_proxy_tag>
677 #endif
679 typedef boost::mpl::true_ is_specialized;
681 template<class Next>
682 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
684 return proxy.interpreter();
687 template<class Next>
688 static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
690 const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
694 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
695 template<class AccessPolicy>
696 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
697 #else
698 template<>
699 struct value_wrapper_traits<adl::iterator_proxy_tag>
700 #endif
702 typedef boost::mpl::true_ is_specialized;
704 template<class Proxy>
705 static lua_State* interpreter(Proxy const& p)
707 return p.interpreter();
710 template<class Proxy>
711 static void unwrap(lua_State* interpreter, Proxy const& p)
713 // TODO: Why const_cast?
714 const_cast<Proxy&>(p).push(interpreter);
718 namespace adl
721 // An object holds a reference to a Lua value residing
722 // in the registry.
723 class object : public object_interface<object>
725 public:
726 object()
729 explicit object(handle const& other)
730 : m_handle(other)
733 explicit object(from_stack const& stack_reference)
734 : m_handle(stack_reference.interpreter, stack_reference.index)
738 template<class T>
739 object(lua_State* interpreter, T const& value)
741 detail::push(interpreter, value);
742 detail::stack_pop pop(interpreter, 1);
743 handle(interpreter, -1).swap(m_handle);
746 template<class T, class Policies>
747 object(lua_State* interpreter, T const& value, Policies const&)
749 detail::push(interpreter, value, Policies());
750 detail::stack_pop pop(interpreter, 1);
751 handle(interpreter, -1).swap(m_handle);
754 void push(lua_State* interpreter) const;
755 lua_State* interpreter() const;
756 bool is_valid() const;
758 template<class T>
759 index_proxy<object> operator[](T const& key) const
761 return index_proxy<object>(
762 *this, m_handle.interpreter(), key
766 void swap(object& other)
768 m_handle.swap(other.m_handle);
771 private:
772 handle m_handle;
775 inline void object::push(lua_State* interpreter) const
777 m_handle.push(interpreter);
780 inline lua_State* object::interpreter() const
782 return m_handle.interpreter();
785 inline bool object::is_valid() const
787 return m_handle.interpreter() != 0;
790 class argument : public object_interface<argument>
792 public:
793 argument(from_stack const& stack_reference)
794 : m_interpreter(stack_reference.interpreter)
795 , m_index(stack_reference.index)
797 if (m_index < 0)
798 m_index = lua_gettop(m_interpreter) - m_index + 1;
801 template<class T>
802 index_proxy<argument> operator[](T const& key) const
804 return index_proxy<argument>(*this, m_interpreter, key);
807 void push(lua_State* L) const
809 lua_pushvalue(L, m_index);
812 lua_State* interpreter() const
814 return m_interpreter;
817 private:
818 lua_State* m_interpreter;
819 int m_index;
822 } // namespace adl
824 using adl::object;
825 using adl::argument;
827 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
828 template <class ValueWrapper, class Arguments>
829 struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
830 #else
831 template<>
832 struct value_wrapper_traits<adl::call_proxy_tag>
833 #endif
835 typedef boost::mpl::true_ is_specialized;
837 template<class W, class A>
838 static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
840 return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
843 template<class W, class A>
844 static void unwrap(lua_State*, adl::call_proxy<W,A> const& proxy)
846 object result = const_cast<adl::call_proxy<W,A>&>(proxy);
847 result.push(result.interpreter());
851 template<>
852 struct value_wrapper_traits<object>
854 typedef boost::mpl::true_ is_specialized;
856 static lua_State* interpreter(object const& value)
858 return value.interpreter();
861 static void unwrap(lua_State* interpreter, object const& value)
863 value.push(interpreter);
866 static bool check(...)
868 return true;
872 template<>
873 struct value_wrapper_traits<argument>
875 typedef boost::mpl::true_ is_specialized;
877 static lua_State* interpreter(argument const& value)
879 return value.interpreter();
882 static void unwrap(lua_State* interpreter, argument const& value)
884 value.push(interpreter);
887 static bool check(...)
889 return true;
893 template<class Next>
894 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
896 assert(interpreter == m_interpreter);
898 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
900 lua_pushvalue(m_interpreter, m_key_index);
901 lua_gettable(m_interpreter, -2);
902 lua_remove(m_interpreter, -2);
905 template<class Next>
906 inline adl::index_proxy<Next>::operator object()
908 detail::stack_pop pop(m_interpreter, 1);
909 push(m_interpreter);
910 return object(from_stack(m_interpreter, -1));
913 template<class AccessPolicy>
914 adl::iterator_proxy<AccessPolicy>::operator object()
916 lua_pushvalue(m_interpreter, m_key_index);
917 AccessPolicy::get(m_interpreter, m_table_index);
918 detail::stack_pop pop(m_interpreter, 1);
919 return object(from_stack(m_interpreter, -1));
922 template<class AccessPolicy>
923 object detail::basic_iterator<AccessPolicy>::key() const
925 return object(m_key);
928 namespace detail
931 template<
932 class T
933 , class ValueWrapper
934 , class Policies
935 , class ErrorPolicy
936 , class ReturnType
938 ReturnType object_cast_aux(
939 ValueWrapper const& value_wrapper
940 , T*
941 , Policies*
942 , ErrorPolicy*
943 , ReturnType*
946 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
947 value_wrapper
950 #ifndef LUABIND_NO_ERROR_CHECKING
951 if (!interpreter)
952 return ErrorPolicy::handle_error(interpreter, typeid(void));
953 #endif
955 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
957 detail::stack_pop pop(interpreter, 1);
959 typedef typename detail::find_conversion_policy<
961 , Policies
962 >::type converter_generator;
964 typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
966 if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
968 return ErrorPolicy::handle_error(interpreter, typeid(T));
971 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
974 # ifdef BOOST_MSVC
975 # pragma warning(push)
976 # pragma warning(disable:4702) // unreachable code
977 # endif
979 template<class T>
980 struct throw_error_policy
982 static T handle_error(lua_State* interpreter, type_id const& type_info)
984 #ifndef LUABIND_NO_EXCEPTIONS
985 throw cast_failed(interpreter, type_info);
986 #else
987 cast_failed_callback_fun e = get_cast_failed_callback();
988 if (e) e(interpreter, type_info);
990 assert(0 && "object_cast failed. If you want to handle this error use "
991 "luabind::set_error_callback()");
992 std::terminate();
993 #endif
994 return *(typename boost::remove_reference<T>::type*)0;
998 # ifdef BOOST_MSVC
999 # pragma warning(pop)
1000 # endif
1002 template<class T>
1003 struct nothrow_error_policy
1005 static boost::optional<T> handle_error(lua_State*, type_id const&)
1007 return boost::optional<T>();
1011 } // namespace detail
1013 template<class T, class ValueWrapper>
1014 T object_cast(ValueWrapper const& value_wrapper)
1016 return detail::object_cast_aux(
1017 value_wrapper
1018 , (T*)0
1019 , (detail::null_type*)0
1020 , (detail::throw_error_policy<T>*)0
1021 , (T*)0
1025 template<class T, class ValueWrapper, class Policies>
1026 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
1028 return detail::object_cast_aux(
1029 value_wrapper
1030 , (T*)0
1031 , (Policies*)0
1032 , (detail::throw_error_policy<T>*)0
1033 , (T*)0
1037 template<class T, class ValueWrapper>
1038 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
1040 return detail::object_cast_aux(
1041 value_wrapper
1042 , (T*)0
1043 , (detail::null_type*)0
1044 , (detail::nothrow_error_policy<T>*)0
1045 , (boost::optional<T>*)0
1049 template<class T, class ValueWrapper, class Policies>
1050 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
1052 return detail::object_cast_aux(
1053 value_wrapper
1054 , (T*)0
1055 , (Policies*)0
1056 , (detail::nothrow_error_policy<T>*)0
1057 , (boost::optional<T>*)0
1061 namespace detail
1064 template<int Index>
1065 struct push_args_from_tuple
1067 template<class H, class T, class Policies>
1068 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
1070 convert_to_lua_p<Index>(L, *x.get_head(), p);
1071 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
1074 template<class H, class T>
1075 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
1077 convert_to_lua(L, *x.get_head());
1078 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
1081 template<class Policies>
1082 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
1084 inline static void apply(lua_State*, const boost::tuples::null_type&) {}
1087 } // namespace detail
1089 namespace adl
1092 template<class ValueWrapper, class Arguments>
1093 struct call_proxy
1095 call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
1096 : value_wrapper(&value_wrapper)
1097 , arguments(arguments)
1100 call_proxy(call_proxy const& other)
1101 : value_wrapper(other.value_wrapper)
1102 , arguments(other.arguments)
1104 other.value_wrapper = 0;
1107 ~call_proxy()
1109 if (value_wrapper)
1110 call((detail::null_type*)0);
1113 operator object()
1115 return call((detail::null_type*)0);
1118 template<class Policies>
1119 object operator[](Policies const&)
1121 return call((Policies*)0);
1124 template<class Policies>
1125 object call(Policies*)
1127 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1128 *value_wrapper
1131 value_wrapper_traits<ValueWrapper>::unwrap(
1132 interpreter
1133 , *value_wrapper
1136 value_wrapper = 0;
1138 detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
1140 if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
1142 #ifndef LUABIND_NO_EXCEPTIONS
1143 throw luabind::error(interpreter);
1144 #else
1145 error_callback_fun e = get_error_callback();
1146 if (e) e(interpreter);
1148 assert(0 && "the lua function threw an error and exceptions are disabled."
1149 "if you want to handle this error use luabind::set_error_callback()");
1150 std::terminate();
1151 #endif
1154 detail::stack_pop pop(interpreter, 1);
1155 return object(from_stack(interpreter, -1));
1158 mutable ValueWrapper* value_wrapper;
1159 Arguments arguments;
1162 template<class Derived>
1163 call_proxy<Derived, boost::tuples::tuple<> >
1164 object_interface<Derived>::operator()()
1166 return call_proxy<Derived, boost::tuples::tuple<> >(
1167 derived()
1168 , boost::tuples::tuple<>()
1172 // Simple value_wrapper adaptor with the sole purpose of helping with
1173 // overload resolution. Use this as a function parameter type instead
1174 // of "object" or "argument" to restrict the parameter to Lua tables.
1175 template <class Base = object>
1176 struct table : Base
1178 table(from_stack const& stack_reference)
1179 : Base(stack_reference)
1183 } // namespace adl
1185 using adl::table;
1187 template <class Base>
1188 struct value_wrapper_traits<adl::table<Base> >
1189 : value_wrapper_traits<Base>
1191 static bool check(lua_State* L, int idx)
1193 return value_wrapper_traits<Base>::check(L, idx) &&
1194 lua_istable(L, idx);
1198 inline object newtable(lua_State* interpreter)
1200 lua_newtable(interpreter);
1201 detail::stack_pop pop(interpreter, 1);
1202 return object(from_stack(interpreter, -1));
1205 // this could be optimized by returning a proxy
1206 inline object globals(lua_State* interpreter)
1208 lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1209 detail::stack_pop pop(interpreter, 1);
1210 return object(from_stack(interpreter, -1));
1213 // this could be optimized by returning a proxy
1214 inline object registry(lua_State* interpreter)
1216 lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
1217 detail::stack_pop pop(interpreter, 1);
1218 return object(from_stack(interpreter, -1));
1221 template<class ValueWrapper, class K>
1222 inline object gettable(ValueWrapper const& table, K const& key)
1224 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1225 table
1228 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1229 detail::stack_pop pop(interpreter, 2);
1230 detail::push(interpreter, key);
1231 lua_gettable(interpreter, -2);
1232 return object(from_stack(interpreter, -1));
1235 template<class ValueWrapper, class K, class T>
1236 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1238 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1239 table
1242 // TODO: Exception safe?
1244 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1245 detail::stack_pop pop(interpreter, 1);
1246 detail::push(interpreter, key);
1247 detail::push(interpreter, value);
1248 lua_settable(interpreter, -3);
1251 template<class ValueWrapper, class K>
1252 inline object rawget(ValueWrapper const& table, K const& key)
1254 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1255 table
1258 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1259 detail::stack_pop pop(interpreter, 2);
1260 detail::push(interpreter, key);
1261 lua_rawget(interpreter, -2);
1262 return object(from_stack(interpreter, -1));
1265 template<class ValueWrapper, class K, class T>
1266 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1268 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1269 table
1272 // TODO: Exception safe?
1274 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1275 detail::stack_pop pop(interpreter, 1);
1276 detail::push(interpreter, key);
1277 detail::push(interpreter, value);
1278 lua_rawset(interpreter, -3);
1281 template<class ValueWrapper>
1282 inline int type(ValueWrapper const& value)
1284 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1285 value
1288 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1289 detail::stack_pop pop(interpreter, 1);
1290 return lua_type(interpreter, -1);
1293 template <class ValueWrapper>
1294 inline object getmetatable(ValueWrapper const& obj)
1296 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1300 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, obj);
1301 detail::stack_pop pop(interpreter, 2);
1302 lua_getmetatable(interpreter, -1);
1303 return object(from_stack(interpreter, -1));
1306 template <class ValueWrapper1, class ValueWrapper2>
1307 inline void setmetatable(
1308 ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
1310 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1314 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, obj);
1315 detail::stack_pop pop(interpreter, 1);
1316 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, metatable);
1317 lua_setmetatable(interpreter, -2);
1320 template <class ValueWrapper>
1321 inline lua_CFunction tocfunction(ValueWrapper const& value)
1323 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1324 value
1327 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1328 detail::stack_pop pop(interpreter, 1);
1329 return lua_tocfunction(interpreter, -1);
1332 template <class T, class ValueWrapper>
1333 inline T* touserdata(ValueWrapper const& value)
1335 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1336 value
1339 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1340 detail::stack_pop pop(interpreter, 1);
1341 return static_cast<T*>(lua_touserdata(interpreter, -1));
1344 template <class ValueWrapper>
1345 inline object getupvalue(ValueWrapper const& value, int index)
1347 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1348 value
1351 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1352 detail::stack_pop pop(interpreter, 2);
1353 lua_getupvalue(interpreter, -1, index);
1354 return object(from_stack(interpreter, -1));
1357 template <class ValueWrapper1, class ValueWrapper2>
1358 inline void setupvalue(
1359 ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
1361 lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1362 function
1365 value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, function);
1366 detail::stack_pop pop(interpreter, 1);
1367 value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, value);
1368 lua_setupvalue(interpreter, -2, index);
1371 template <class GetValueWrapper>
1372 object property(GetValueWrapper const& get)
1374 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1378 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1379 lua_pushnil(interpreter);
1381 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1382 detail::stack_pop pop(interpreter, 1);
1384 return object(from_stack(interpreter, -1));
1387 template <class GetValueWrapper, class SetValueWrapper>
1388 object property(GetValueWrapper const& get, SetValueWrapper const& set)
1390 lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1394 value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1395 value_wrapper_traits<SetValueWrapper>::unwrap(interpreter, set);
1397 lua_pushcclosure(interpreter, &detail::property_tag, 2);
1398 detail::stack_pop pop(interpreter, 1);
1400 return object(from_stack(interpreter, -1));
1405 } // namespace luabind
1407 #endif // LUABIND_OBJECT_050419_HPP