Moved value_wrapper_traits<adl::call_proxy>.
[luabind.git] / luabind / object.hpp
blob8265f57fc71b3faef2e520feb3bb359573f2d281
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
42 #include <boost/iterator/iterator_facade.hpp> // iterator
43 #include <boost/python/detail/is_xxx.hpp>
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 public:
275 ~object_interface() {}
277 call_proxy<Derived, boost::tuples::tuple<> > operator()();
279 template<class A0>
280 call_proxy<
281 Derived
282 , boost::tuples::tuple<A0 const*>
283 > operator()(A0 const& a0)
285 typedef boost::tuples::tuple<A0 const*> arguments;
287 return call_proxy<Derived, arguments>(
288 derived()
289 , arguments(&a0)
293 template<class A0, class A1>
294 call_proxy<
295 Derived
296 , boost::tuples::tuple<A0 const*, A1 const*>
297 > operator()(A0 const& a0, A1 const& a1)
299 typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
301 return call_proxy<Derived, arguments>(
302 derived()
303 , arguments(&a0, &a1)
307 // The rest of the overloads are PP-generated.
308 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
309 (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
310 #include BOOST_PP_ITERATE()
312 private:
313 Derived& derived()
315 return *static_cast<Derived*>(this);
318 Derived const& derived() const
320 return *static_cast<Derived const*>(this);
324 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
325 struct iterator_proxy_tag;
326 #endif
328 template<class AccessPolicy>
329 class iterator_proxy
330 : public object_interface<iterator_proxy<AccessPolicy> >
332 public:
333 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
334 typedef iterator_proxy_tag value_wrapper_tag;
335 #endif
337 iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
338 : m_interpreter(interpreter)
339 , m_table_index(lua_gettop(interpreter) + 1)
340 , m_key_index(m_table_index + 1)
342 table.push(m_interpreter);
343 key.push(m_interpreter);
346 iterator_proxy(iterator_proxy const& other)
347 : m_interpreter(other.m_interpreter)
348 , m_table_index(other.m_table_index)
349 , m_key_index(other.m_key_index)
351 other.m_interpreter = 0;
354 ~iterator_proxy()
356 if (m_interpreter)
357 lua_pop(m_interpreter, 2);
360 // this will set the value to nil
361 iterator_proxy & operator=(luabind::detail::nil_type)
363 lua_pushvalue(m_interpreter, m_key_index);
364 lua_pushnil(m_interpreter);
365 AccessPolicy::set(m_interpreter, m_table_index);
366 return *this;
369 template<class T>
370 iterator_proxy& operator=(T const& value)
372 lua_pushvalue(m_interpreter, m_key_index);
373 detail::push(m_interpreter, value);
374 AccessPolicy::set(m_interpreter, m_table_index);
375 return *this;
378 template<class Key>
379 index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
381 return index_proxy<iterator_proxy<AccessPolicy> >(
382 *this, m_interpreter, key
386 // This is non-const to prevent conversion on lvalues.
387 operator object();
389 lua_State* interpreter() const
391 return m_interpreter;
394 // TODO: Why is it non-const?
395 void push(lua_State* interpreter)
397 assert(interpreter == m_interpreter);
398 lua_pushvalue(m_interpreter, m_key_index);
399 AccessPolicy::get(m_interpreter, m_table_index);
402 private:
403 mutable lua_State* m_interpreter;
404 int m_table_index;
405 int m_key_index;
408 } // namespace adl
410 namespace detail
412 struct basic_access
414 static void set(lua_State* interpreter, int table)
416 lua_settable(interpreter, table);
419 static void get(lua_State* interpreter, int table)
421 lua_gettable(interpreter, table);
425 struct raw_access
427 static void set(lua_State* interpreter, int table)
429 lua_rawset(interpreter, table);
432 static void get(lua_State* interpreter, int table)
434 lua_rawget(interpreter, table);
438 template<class AccessPolicy>
439 class basic_iterator
440 : public boost::iterator_facade<
441 basic_iterator<AccessPolicy>
442 , adl::iterator_proxy<AccessPolicy>
443 , boost::single_pass_traversal_tag
444 , adl::iterator_proxy<AccessPolicy>
447 public:
448 basic_iterator()
449 : m_interpreter(0)
452 template<class ValueWrapper>
453 explicit basic_iterator(ValueWrapper const& value_wrapper)
454 : m_interpreter(
455 value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
458 detail::stack_pop pop(m_interpreter, 1);
459 value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
461 lua_pushnil(m_interpreter);
462 if (lua_next(m_interpreter, -2) != 0)
464 detail::stack_pop pop(m_interpreter, 2);
465 handle(m_interpreter, -2).swap(m_key);
467 else
469 m_interpreter = 0;
470 return;
473 handle(m_interpreter, -1).swap(m_table);
476 adl::object key() const;
478 private:
479 friend class boost::iterator_core_access;
481 void increment()
483 m_table.push(m_interpreter);
484 m_key.push(m_interpreter);
486 detail::stack_pop pop(m_interpreter, 1);
488 if (lua_next(m_interpreter, -2) != 0)
490 m_key.replace(m_interpreter, -2);
491 lua_pop(m_interpreter, 2);
493 else
495 m_interpreter = 0;
496 handle().swap(m_table);
497 handle().swap(m_key);
501 bool equal(basic_iterator const& other) const
503 if (m_interpreter == 0 && other.m_interpreter == 0)
504 return true;
506 if (m_interpreter != other.m_interpreter)
507 return false;
509 detail::stack_pop pop(m_interpreter, 2);
510 m_key.push(m_interpreter);
511 other.m_key.push(m_interpreter);
512 return lua_equal(m_interpreter, -2, -1) != 0;
515 adl::iterator_proxy<AccessPolicy> dereference() const
517 return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
520 lua_State* m_interpreter;
521 handle m_table;
522 handle m_key;
525 // Needed because of some strange ADL issues.
527 #define LUABIND_OPERATOR_ADL_WKND(op) \
528 inline bool operator op( \
529 basic_iterator<basic_access> const& x \
530 , basic_iterator<basic_access> const& y) \
532 return boost::operator op(x, y); \
535 inline bool operator op( \
536 basic_iterator<raw_access> const& x \
537 , basic_iterator<raw_access> const& y) \
539 return boost::operator op(x, y); \
542 LUABIND_OPERATOR_ADL_WKND(==)
543 LUABIND_OPERATOR_ADL_WKND(!=)
545 #undef LUABIND_OPERATOR_ADL_WKND
547 } // namespace detail
549 namespace adl
552 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
553 struct index_proxy_tag;
554 #endif
556 template<class Next>
557 class index_proxy
558 : public object_interface<index_proxy<Next> >
560 public:
561 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
562 typedef index_proxy_tag value_wrapper_tag;
563 #endif
565 typedef index_proxy<Next> this_type;
567 template<class Key>
568 index_proxy(Next const& next, lua_State* interpreter, Key const& key)
569 : m_interpreter(interpreter)
570 , m_key_index(lua_gettop(interpreter) + 1)
571 , m_next(next)
573 detail::push(m_interpreter, key);
576 index_proxy(index_proxy const& other)
577 : m_interpreter(other.m_interpreter)
578 , m_key_index(other.m_key_index)
579 , m_next(other.m_next)
581 other.m_interpreter = 0;
584 ~index_proxy()
586 if (m_interpreter)
587 lua_pop(m_interpreter, 1);
590 // This is non-const to prevent conversion on lvalues.
591 operator object();
593 // this will set the value to nil
594 this_type& operator=(luabind::detail::nil_type)
596 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
597 detail::stack_pop pop(m_interpreter, 1);
599 lua_pushvalue(m_interpreter, m_key_index);
600 lua_pushnil(m_interpreter);
601 lua_settable(m_interpreter, -3);
602 return *this;
605 template<class T>
606 this_type& operator=(T const& value)
608 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
609 detail::stack_pop pop(m_interpreter, 1);
611 lua_pushvalue(m_interpreter, m_key_index);
612 detail::push(m_interpreter, value);
613 lua_settable(m_interpreter, -3);
614 return *this;
617 this_type& operator=(this_type const& value)
619 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
620 detail::stack_pop pop(m_interpreter, 1);
622 lua_pushvalue(m_interpreter, m_key_index);
623 detail::push(m_interpreter, value);
624 lua_settable(m_interpreter, -3);
625 return *this;
628 template<class T>
629 index_proxy<this_type> operator[](T const& key)
631 return index_proxy<this_type>(*this, m_interpreter, key);
634 void push(lua_State* interpreter);
636 lua_State* interpreter() const
638 return m_interpreter;
641 private:
642 struct hidden_type {};
644 // this_type& operator=(index_proxy<Next> const&);
646 mutable lua_State* m_interpreter;
647 int m_key_index;
649 Next const& m_next;
652 } // namespace adl
654 typedef detail::basic_iterator<detail::basic_access> iterator;
655 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
657 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
658 template<class T>
659 struct value_wrapper_traits<adl::index_proxy<T> >
660 #else
661 template<>
662 struct value_wrapper_traits<adl::index_proxy_tag>
663 #endif
665 typedef boost::mpl::true_ is_specialized;
667 template<class Next>
668 static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
670 return proxy.interpreter();
673 template<class Next>
674 static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
676 const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
680 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
681 template<class AccessPolicy>
682 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
683 #else
684 template<>
685 struct value_wrapper_traits<adl::iterator_proxy_tag>
686 #endif
688 typedef boost::mpl::true_ is_specialized;
690 template<class Proxy>
691 static lua_State* interpreter(Proxy const& p)
693 return p.interpreter();
696 template<class Proxy>
697 static void unwrap(lua_State* interpreter, Proxy const& p)
699 // TODO: Why const_cast?
700 const_cast<Proxy&>(p).push(interpreter);
704 namespace adl
706 class object_init
708 protected:
709 object_init()
712 explicit object_init(from_stack const& stack_reference, boost::mpl::true_)
713 : m_handle(stack_reference.interpreter, stack_reference.index)
717 template<class ValueWrapper>
718 explicit object_init(ValueWrapper const& value_wrapper, boost::mpl::false_)
720 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
721 value_wrapper
724 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
725 detail::stack_pop pop(interpreter, 1);
727 handle(interpreter, -1).swap(m_handle);
730 handle m_handle;
733 // An object holds a reference to a Lua value residing
734 // in the registry.
735 class object : public object_interface<object>
737 struct safe_bool_type {};
738 public:
739 object()
742 explicit object(handle const& other)
743 : m_handle(other)
746 explicit object(from_stack const& stack_reference)
747 : m_handle(stack_reference.interpreter, stack_reference.index)
751 template<class T>
752 object(lua_State* interpreter, T const& value)
754 detail::push(interpreter, value);
755 detail::stack_pop pop(interpreter, 1);
756 handle(interpreter, -1).swap(m_handle);
759 template<class T, class Policies>
760 object(lua_State* interpreter, T const& value, Policies const&)
762 detail::push(interpreter, value, Policies());
763 detail::stack_pop pop(interpreter, 1);
764 handle(interpreter, -1).swap(m_handle);
767 void push(lua_State* interpreter) const;
768 lua_State* interpreter() const;
769 bool is_valid() const;
770 operator safe_bool_type*() const;
772 template<class T>
773 index_proxy<object> operator[](T const& key) const
775 return index_proxy<object>(
776 *this, m_handle.interpreter(), key
780 void swap(object& other)
782 m_handle.swap(other.m_handle);
785 private:
786 handle m_handle;
789 inline void object::push(lua_State* interpreter) const
791 m_handle.push(interpreter);
794 inline lua_State* object::interpreter() const
796 return m_handle.interpreter();
799 inline bool object::is_valid() const
801 return m_handle.interpreter() != 0;
804 inline object::operator object::safe_bool_type*() const
806 return is_valid()?(safe_bool_type*)1:0;
809 } // namespace adl
811 using adl::object;
813 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
814 template <class ValueWrapper, class Arguments>
815 struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
816 #else
817 template<>
818 struct value_wrapper_traits<adl::call_proxy_tag>
819 #endif
821 typedef boost::mpl::true_ is_specialized;
823 template<class W, class A>
824 static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
826 return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
829 template<class W, class A>
830 static void unwrap(lua_State* interpreter, adl::call_proxy<W,A> const& proxy)
832 object result = const_cast<adl::call_proxy<W,A>&>(proxy);
833 result.push(result.interpreter());
837 template<>
838 struct value_wrapper_traits<object>
840 typedef boost::mpl::true_ is_specialized;
842 static lua_State* interpreter(object const& value)
844 return value.interpreter();
847 static void unwrap(lua_State* interpreter, object const& value)
849 value.push(interpreter);
852 static bool check(...)
854 return true;
858 template<class Next>
859 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
861 assert(interpreter == m_interpreter);
863 value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
865 lua_pushvalue(m_interpreter, m_key_index);
866 lua_gettable(m_interpreter, -2);
867 lua_remove(m_interpreter, -2);
870 template<class Next>
871 inline adl::index_proxy<Next>::operator object()
873 detail::stack_pop pop(m_interpreter, 1);
874 push(m_interpreter);
875 return object(from_stack(m_interpreter, -1));
878 template<class AccessPolicy>
879 adl::iterator_proxy<AccessPolicy>::operator object()
881 lua_pushvalue(m_interpreter, m_key_index);
882 AccessPolicy::get(m_interpreter, m_table_index);
883 detail::stack_pop pop(m_interpreter, 1);
884 return object(from_stack(m_interpreter, -1));
887 template<class AccessPolicy>
888 object detail::basic_iterator<AccessPolicy>::key() const
890 return object(m_key);
893 namespace detail
896 template<
897 class T
898 , class ValueWrapper
899 , class Policies
900 , class ErrorPolicy
901 , class ReturnType
903 ReturnType object_cast_aux(
904 ValueWrapper const& value_wrapper
905 , T*
906 , Policies*
907 , ErrorPolicy*
908 , ReturnType*
911 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
912 value_wrapper
915 #ifndef LUABIND_NO_ERROR_CHECKING
916 if (!interpreter)
917 return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(void));
918 #endif
920 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
922 detail::stack_pop pop(interpreter, 1);
924 typedef typename detail::find_conversion_policy<
926 , Policies
927 >::type converter_generator;
929 typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
931 #ifndef LUABIND_NO_ERROR_CHECKING
932 if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
934 return ErrorPolicy::handle_error(interpreter, LUABIND_TYPEID(T));
936 #endif
938 return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
941 template<class T>
942 struct throw_error_policy
944 static T handle_error(lua_State* interpreter, LUABIND_TYPE_INFO type_info)
946 #ifndef LUABIND_NO_EXCEPTIONS
947 throw cast_failed(interpreter, type_info);
948 #else
949 cast_failed_callback_fun e = get_cast_failed_callback();
950 if (e) e(interpreter, type_info);
952 assert(0 && "object_cast failed. If you want to handle this error use "
953 "luabind::set_error_callback()");
954 std::terminate();
955 #endif
956 return *(typename boost::remove_reference<T>::type*)0;
960 template<class T>
961 struct nothrow_error_policy
963 static boost::optional<T> handle_error(lua_State*, LUABIND_TYPE_INFO)
965 return boost::optional<T>();
969 } // namespace detail
971 template<class T, class ValueWrapper>
972 T object_cast(ValueWrapper const& value_wrapper)
974 return detail::object_cast_aux(
975 value_wrapper
976 , (T*)0
977 , (detail::null_type*)0
978 , (detail::throw_error_policy<T>*)0
979 , (T*)0
983 template<class T, class ValueWrapper, class Policies>
984 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
986 return detail::object_cast_aux(
987 value_wrapper
988 , (T*)0
989 , (Policies*)0
990 , (detail::throw_error_policy<T>*)0
991 , (T*)0
995 template<class T, class ValueWrapper>
996 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
998 return detail::object_cast_aux(
999 value_wrapper
1000 , (T*)0
1001 , (detail::null_type*)0
1002 , (detail::nothrow_error_policy<T>*)0
1003 , (boost::optional<T>*)0
1007 template<class T, class ValueWrapper, class Policies>
1008 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
1010 return detail::object_cast_aux(
1011 value_wrapper
1012 , (T*)0
1013 , (Policies*)0
1014 , (detail::nothrow_error_policy<T>*)0
1015 , (boost::optional<T>*)0
1019 namespace detail
1022 template<int Index>
1023 struct push_args_from_tuple
1025 template<class H, class T, class Policies>
1026 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
1028 convert_to_lua_p<Index>(L, *x.get_head(), p);
1029 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
1032 template<class H, class T>
1033 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
1035 convert_to_lua(L, *x.get_head());
1036 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
1039 template<class Policies>
1040 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
1042 inline static void apply(lua_State*, const boost::tuples::null_type&) {}
1045 } // namespace detail
1047 namespace adl
1050 template<class ValueWrapper, class Arguments>
1051 struct call_proxy
1053 call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
1054 : value_wrapper(&value_wrapper)
1055 , arguments(arguments)
1058 call_proxy(call_proxy const& other)
1059 : value_wrapper(other.value_wrapper)
1060 , arguments(other.arguments)
1062 other.value_wrapper = 0;
1065 ~call_proxy()
1067 if (value_wrapper)
1068 call((detail::null_type*)0);
1071 operator object()
1073 return call((detail::null_type*)0);
1076 template<class Policies>
1077 object operator[](Policies const&)
1079 return call((Policies*)0);
1082 template<class Policies>
1083 object call(Policies*)
1085 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1086 *value_wrapper
1089 value_wrapper_traits<ValueWrapper>::unwrap(
1090 interpreter
1091 , *value_wrapper
1094 value_wrapper = 0;
1096 detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
1098 if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
1100 #ifndef LUABIND_NO_EXCEPTIONS
1101 throw luabind::error(interpreter);
1102 #else
1103 error_callback_fun e = get_error_callback();
1104 if (e) e(interpreter);
1106 assert(0 && "the lua function threw an error and exceptions are disabled."
1107 "if you want to handle this error use luabind::set_error_callback()");
1108 std::terminate();
1109 #endif
1112 detail::stack_pop pop(interpreter, 1);
1113 return object(from_stack(interpreter, -1));
1116 mutable ValueWrapper* value_wrapper;
1117 Arguments arguments;
1120 template<class Derived>
1121 call_proxy<Derived, boost::tuples::tuple<> >
1122 object_interface<Derived>::operator()()
1124 return call_proxy<Derived, boost::tuples::tuple<> >(
1125 derived()
1126 , boost::tuples::tuple<>()
1130 } // namespace adl
1132 inline object newtable(lua_State* interpreter)
1134 lua_newtable(interpreter);
1135 detail::stack_pop pop(interpreter, 1);
1136 return object(from_stack(interpreter, -1));
1139 // this could be optimized by returning a proxy
1140 inline object globals(lua_State* interpreter)
1142 lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1143 detail::stack_pop pop(interpreter, 1);
1144 return object(from_stack(interpreter, -1));
1147 // this could be optimized by returning a proxy
1148 inline object registry(lua_State* interpreter)
1150 lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
1151 detail::stack_pop pop(interpreter, 1);
1152 return object(from_stack(interpreter, -1));
1155 template<class ValueWrapper, class K>
1156 inline object gettable(ValueWrapper const& table, K const& key)
1158 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1159 table
1162 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1163 detail::stack_pop pop(interpreter, 2);
1164 detail::push(interpreter, key);
1165 lua_gettable(interpreter, -2);
1166 return object(from_stack(interpreter, -1));
1169 template<class ValueWrapper, class K, class T>
1170 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1172 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1173 table
1176 // TODO: Exception safe?
1178 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1179 detail::stack_pop pop(interpreter, 1);
1180 detail::push(interpreter, key);
1181 detail::push(interpreter, value);
1182 lua_settable(interpreter, -3);
1185 template<class ValueWrapper, class K>
1186 inline object rawget(ValueWrapper const& table, K const& key)
1188 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1189 table
1192 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1193 detail::stack_pop pop(interpreter, 2);
1194 detail::push(interpreter, key);
1195 lua_rawget(interpreter, -2);
1196 return object(from_stack(interpreter, -1));
1199 template<class ValueWrapper, class K, class T>
1200 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1202 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1203 table
1206 // TODO: Exception safe?
1208 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1209 detail::stack_pop pop(interpreter, 1);
1210 detail::push(interpreter, key);
1211 detail::push(interpreter, value);
1212 lua_rawset(interpreter, -3);
1215 template<class ValueWrapper>
1216 inline int type(ValueWrapper const& value)
1218 lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1219 value
1222 value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1223 detail::stack_pop pop(interpreter, 1);
1224 return lua_type(interpreter, -1);
1227 } // namespace luabind
1229 #endif // LUABIND_OBJECT_050419_HPP