1 // Copyright (c) 2005 Daniel Wallin and Arvid Norberg
2 
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:
9 
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 
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.
22 
23 #ifndef LUABIND_OBJECT_050419_HPP
24 #define LUABIND_OBJECT_050419_HPP
25 
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>
32 
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>
42 
43 #include <boost/iterator/iterator_facade.hpp> // iterator
44 
45 #include <boost/preprocessor/iteration/iterate.hpp>
46 #include <boost/utility/enable_if.hpp>
47 
48 namespace luabind {
49 
50 namespace detail
51 {
52   namespace mpl = boost::mpl;
53 
54   template<class T, class ConverterGenerator>
push_aux(lua_State * interpreter,T & value,ConverterGenerator *)55   void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
56   {
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;
62 
63       typename mpl::apply_wrap2<
64           ConverterGenerator,unwrapped_type,cpp_to_lua
65       >::type cv;
66 
67       cv.apply(
68           interpreter
69         , boost::implicit_cast<
70               BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
71           >(value)
72       );
73   }
74 
75   template<class T, class Policies>
push(lua_State * interpreter,T & value,Policies const &)76   void push(lua_State* interpreter, T& value, Policies const&)
77   {
78       typedef typename find_conversion_policy<
79           0
80         , Policies
81       >::type converter_policy;
82 
83       push_aux(interpreter, value, (converter_policy*)0);
84   }
85 
86   template<class T>
push(lua_State * interpreter,T & value)87   void push(lua_State* interpreter, T& value)
88   {
89       push(interpreter, value, null_type());
90   }
91 
92 } // namespace detail
93 
94 namespace adl
95 {
96   namespace mpl = boost::mpl;
97 
98   template <class T>
99   class object_interface;
100 
101   namespace is_object_interface_aux
102   {
103     typedef char (&yes)[1];
104     typedef char (&no)[2];
105 
106     template <class T>
107     yes check(object_interface<T>*);
108     no check(void*);
109 
110     template <class T>
111     struct impl
112     {
113         BOOST_STATIC_CONSTANT(bool, value =
114             sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
115         );
116 
117         typedef mpl::bool_<value> type;
118     };
119 
120   } // namespace detail
121 
122   template <class T>
123   struct is_object_interface
124     : is_object_interface_aux::impl<T>::type
125   {};
126 
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>
134           >
135         , R
136       >
137   {};
138 # else
139   {
140       typedef R type;
141   };
142 # endif
143 
144   template<class T, class U>
binary_interpreter(lua_State * & L,T const & lhs,U const & rhs,boost::mpl::true_,boost::mpl::true_)145   int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs
146     , boost::mpl::true_, boost::mpl::true_)
147   {
148        L = value_wrapper_traits<T>::interpreter(lhs);
149 		 lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs);
150 
151        // you are comparing objects with different interpreters
152        // that's not allowed.
153 		 assert(L == L2 || L == 0 || L2 == 0);
154 
155        // if the two objects we compare have different interpreters
156        // then they
157 
158        if (L != L2) return -1;
159        if (L == 0) return 1;
160        return 0;
161   }
162 
163   template<class T, class U>
binary_interpreter(lua_State * & L,T const & x,U const &,boost::mpl::true_,boost::mpl::false_)164   int binary_interpreter(lua_State*& L, T const& x, U const&
165     , boost::mpl::true_, boost::mpl::false_)
166   {
167        L = value_wrapper_traits<T>::interpreter(x);
168        return 0;
169   }
170 
171   template<class T, class U>
binary_interpreter(lua_State * & L,T const &,U const & x,boost::mpl::false_,boost::mpl::true_)172   int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
173   {
174       L = value_wrapper_traits<U>::interpreter(x);
175       return 0;
176   }
177 
178   template<class T, class U>
binary_interpreter(lua_State * & L,T const & x,U const & y)179   int binary_interpreter(lua_State*& L, T const& x, U const& y)
180   {
181       return binary_interpreter(
182           L
183         , x
184         , y
185         , is_value_wrapper<T>()
186         , is_value_wrapper<U>()
187       );
188   }
189 
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) \
194   { \
195       lua_State* L = 0; \
196       switch (binary_interpreter(L, lhs, rhs)) \
197       { \
198           case 1: \
199               return true; \
200           case -1: \
201               return false; \
202       } \
203 \
204       assert(L); \
205 \
206       detail::stack_pop pop1(L, 1); \
207       detail::push(L, lhs); \
208       detail::stack_pop pop2(L, 1); \
209       detail::push(L, rhs); \
210 \
211       return fn(L, -1, -2) != 0; \
212   }
213 
214 LUABIND_BINARY_OP_DEF(==, lua_equal)
215 LUABIND_BINARY_OP_DEF(<, lua_lessthan)
216 
217   template<class ValueWrapper>
operator <<(std::ostream & os,object_interface<ValueWrapper> const & v)218   std::ostream& operator<<(std::ostream& os
219     , object_interface<ValueWrapper> const& v)
220   {
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;
231 	}
232 
233 #undef LUABIND_BINARY_OP_DEF
234 
235   template<class LHS, class RHS>
236   typename enable_binary<bool,LHS,RHS>::type
operator >(LHS const & lhs,RHS const & rhs)237   operator>(LHS const& lhs, RHS const& rhs)
238   {
239       return !(lhs < rhs || lhs == rhs);
240   }
241 
242   template<class LHS, class RHS>
243   typename enable_binary<bool,LHS,RHS>::type
operator <=(LHS const & lhs,RHS const & rhs)244   operator<=(LHS const& lhs, RHS const& rhs)
245   {
246       return lhs < rhs || lhs == rhs;
247   }
248 
249   template<class LHS, class RHS>
250   typename enable_binary<bool,LHS,RHS>::type
operator >=(LHS const & lhs,RHS const & rhs)251   operator>=(LHS const& lhs, RHS const& rhs)
252   {
253       return !(lhs < rhs);
254   }
255 
256   template<class LHS, class RHS>
257   typename enable_binary<bool,LHS,RHS>::type
operator !=(LHS const & lhs,RHS const & rhs)258   operator!=(LHS const& lhs, RHS const& rhs)
259   {
260       return !(lhs < rhs);
261   }
262 
263   template<class ValueWrapper, class Arguments>
264   struct call_proxy;
265 
266   template<class Next>
267   class index_proxy;
268 
269   class object;
270 
271   template<class Derived>
272   class object_interface
273   {
274       struct safe_bool_type {};
275   public:
~object_interface()276       ~object_interface() {}
277 
278       call_proxy<Derived, boost::tuples::tuple<> > operator()();
279 
280       template<class A0>
281       call_proxy<
282           Derived
283         , boost::tuples::tuple<A0 const*>
operator ()(A0 const & a0)284       > operator()(A0 const& a0)
285       {
286           typedef boost::tuples::tuple<A0 const*> arguments;
287 
288           return call_proxy<Derived, arguments>(
289               derived()
290             , arguments(&a0)
291           );
292       }
293 
294       template<class A0, class A1>
295       call_proxy<
296           Derived
297         , boost::tuples::tuple<A0 const*, A1 const*>
operator ()(A0 const & a0,A1 const & a1)298       > operator()(A0 const& a0, A1 const& a1)
299       {
300           typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
301 
302           return call_proxy<Derived, arguments>(
303               derived()
304             , arguments(&a0, &a1)
305           );
306       }
307 
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()
312 
operator safe_bool_type*() const313       operator safe_bool_type*() const
314       {
315           lua_State* L = value_wrapper_traits<Derived>::interpreter(derived());
316 
317           if (!L)
318               return 0;
319 
320           value_wrapper_traits<Derived>::unwrap(L, derived());
321           detail::stack_pop pop(L, 1);
322 
323           return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0;
324       }
325 
326   private:
derived()327       Derived& derived()
328       {
329           return *static_cast<Derived*>(this);
330       }
331 
derived() const332       Derived const& derived() const
333       {
334           return *static_cast<Derived const*>(this);
335       }
336   };
337 
338 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
339   struct iterator_proxy_tag;
340 #endif
341 
342   template<class AccessPolicy>
343   class iterator_proxy
344     : public object_interface<iterator_proxy<AccessPolicy> >
345   {
346   public:
347 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
348       typedef iterator_proxy_tag value_wrapper_tag;
349 #endif
350 
iterator_proxy(lua_State * interpreter,handle const & table,handle const & key)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)
355       {
356           table.push(m_interpreter);
357           key.push(m_interpreter);
358       }
359 
iterator_proxy(iterator_proxy const & other)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)
364       {
365           other.m_interpreter = 0;
366       }
367 
~iterator_proxy()368       ~iterator_proxy()
369       {
370           if (m_interpreter)
371               lua_pop(m_interpreter, 2);
372       }
373 
374 		// this will set the value to nil
operator =(luabind::detail::nil_type)375 		iterator_proxy & operator=(luabind::detail::nil_type)
376 		{
377           lua_pushvalue(m_interpreter, m_key_index);
378 			 lua_pushnil(m_interpreter);
379           AccessPolicy::set(m_interpreter, m_table_index);
380           return *this;
381 		}
382 
383       template<class T>
operator =(T const & value)384       iterator_proxy& operator=(T const& value)
385       {
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;
390       }
391 
392       template<class Key>
operator [](Key const & key)393       index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
394       {
395           return index_proxy<iterator_proxy<AccessPolicy> >(
396               *this, m_interpreter, key
397           );
398       }
399 
400       // This is non-const to prevent conversion on lvalues.
401       operator object();
402 
interpreter() const403       lua_State* interpreter() const
404       {
405           return m_interpreter;
406       }
407 
408       // TODO: Why is it non-const?
push(lua_State * interpreter)409       void push(lua_State* interpreter)
410       {
411           assert(interpreter == m_interpreter);
412           lua_pushvalue(m_interpreter, m_key_index);
413           AccessPolicy::get(m_interpreter, m_table_index);
414       }
415 
416   private:
417       mutable lua_State* m_interpreter;
418       int m_table_index;
419       int m_key_index;
420   };
421 
422 } // namespace adl
423 
424 namespace detail
425 {
426   struct basic_access
427   {
setluabind::detail::basic_access428       static void set(lua_State* interpreter, int table)
429       {
430           lua_settable(interpreter, table);
431       }
432 
getluabind::detail::basic_access433       static void get(lua_State* interpreter, int table)
434       {
435           lua_gettable(interpreter, table);
436       }
437   };
438 
439   struct raw_access
440   {
setluabind::detail::raw_access441       static void set(lua_State* interpreter, int table)
442       {
443           lua_rawset(interpreter, table);
444       }
445 
getluabind::detail::raw_access446       static void get(lua_State* interpreter, int table)
447       {
448           lua_rawget(interpreter, table);
449       }
450   };
451 
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>
459     >
460   {
461   public:
basic_iterator()462       basic_iterator()
463         : m_interpreter(0)
464       {}
465 
466       template<class ValueWrapper>
basic_iterator(ValueWrapper const & value_wrapper)467       explicit basic_iterator(ValueWrapper const& value_wrapper)
468         : m_interpreter(
469               value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
470           )
471       {
472           detail::stack_pop pop(m_interpreter, 1);
473           value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
474 
475           lua_pushnil(m_interpreter);
476           if (lua_next(m_interpreter, -2) != 0)
477           {
478               detail::stack_pop pop(m_interpreter, 2);
479               handle(m_interpreter, -2).swap(m_key);
480           }
481           else
482           {
483               m_interpreter = 0;
484               return;
485           }
486 
487           handle(m_interpreter, -1).swap(m_table);
488       }
489 
490       adl::object key() const;
491 
492   private:
493       friend class boost::iterator_core_access;
494 
increment()495       void increment()
496       {
497           m_table.push(m_interpreter);
498           m_key.push(m_interpreter);
499 
500           detail::stack_pop pop(m_interpreter, 1);
501 
502           if (lua_next(m_interpreter, -2) != 0)
503           {
504               m_key.replace(m_interpreter, -2);
505               lua_pop(m_interpreter, 2);
506           }
507           else
508           {
509               m_interpreter = 0;
510               handle().swap(m_table);
511               handle().swap(m_key);
512           }
513       }
514 
equal(basic_iterator const & other) const515       bool equal(basic_iterator const& other) const
516       {
517           if (m_interpreter == 0 && other.m_interpreter == 0)
518               return true;
519 
520           if (m_interpreter != other.m_interpreter)
521               return false;
522 
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;
527       }
528 
dereference() const529       adl::iterator_proxy<AccessPolicy> dereference() const
530       {
531           return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
532       }
533 
534       lua_State* m_interpreter;
535       handle m_table;
536       handle m_key;
537   };
538 
539 #if BOOST_VERSION < 105700
540 // Needed because of some strange ADL issues.
541 
542 #define LUABIND_OPERATOR_ADL_WKND(op) \
543   inline bool operator op( \
544       basic_iterator<basic_access> const& x \
545     , basic_iterator<basic_access> const& y) \
546   { \
547       return boost::operator op(x, y); \
548   } \
549  \
550   inline bool operator op( \
551       basic_iterator<raw_access> const& x \
552     , basic_iterator<raw_access> const& y) \
553   { \
554       return boost::operator op(x, y); \
555   }
556 
557   LUABIND_OPERATOR_ADL_WKND(==)
558   LUABIND_OPERATOR_ADL_WKND(!=)
559 
560 #undef LUABIND_OPERATOR_ADL_WKND
561 #endif
562 
563 } // namespace detail
564 
565 namespace adl
566 {
567 
568 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
569   struct index_proxy_tag;
570 #endif
571 
572   template<class Next>
573   class index_proxy
574     : public object_interface<index_proxy<Next> >
575   {
576   public:
577 #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
578       typedef index_proxy_tag value_wrapper_tag;
579 #endif
580 
581       typedef index_proxy<Next> this_type;
582 
583       template<class Key>
index_proxy(Next const & next,lua_State * interpreter,Key const & key)584       index_proxy(Next const& next, lua_State* interpreter, Key const& key)
585         : m_interpreter(interpreter)
586         , m_key_index(lua_gettop(interpreter) + 1)
587         , m_next(next)
588       {
589           detail::push(m_interpreter, key);
590       }
591 
index_proxy(index_proxy const & other)592       index_proxy(index_proxy const& other)
593         : m_interpreter(other.m_interpreter)
594         , m_key_index(other.m_key_index)
595         , m_next(other.m_next)
596       {
597           other.m_interpreter = 0;
598       }
599 
~index_proxy()600       ~index_proxy()
601       {
602           if (m_interpreter)
603               lua_pop(m_interpreter, 1);
604       }
605 
606       // This is non-const to prevent conversion on lvalues.
607       operator object();
608 
609 		// this will set the value to nil
operator =(luabind::detail::nil_type)610 		this_type& operator=(luabind::detail::nil_type)
611 		{
612 	       value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
613           detail::stack_pop pop(m_interpreter, 1);
614 
615           lua_pushvalue(m_interpreter, m_key_index);
616 			 lua_pushnil(m_interpreter);
617           lua_settable(m_interpreter, -3);
618           return *this;
619 		}
620 
621       template<class T>
operator =(T const & value)622       this_type& operator=(T const& value)
623       {
624           value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
625           detail::stack_pop pop(m_interpreter, 1);
626 
627           lua_pushvalue(m_interpreter, m_key_index);
628           detail::push(m_interpreter, value);
629           lua_settable(m_interpreter, -3);
630           return *this;
631       }
632 
operator =(this_type const & value)633       this_type& operator=(this_type const& value)
634       {
635           value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
636           detail::stack_pop pop(m_interpreter, 1);
637 
638           lua_pushvalue(m_interpreter, m_key_index);
639           detail::push(m_interpreter, value);
640           lua_settable(m_interpreter, -3);
641           return *this;
642       }
643 
644       template<class T>
operator [](T const & key)645       index_proxy<this_type> operator[](T const& key)
646       {
647           return index_proxy<this_type>(*this, m_interpreter, key);
648       }
649 
650       void push(lua_State* interpreter);
651 
interpreter() const652       lua_State* interpreter() const
653       {
654           return m_interpreter;
655       }
656 
657   private:
658 		struct hidden_type {};
659 
660 //      this_type& operator=(index_proxy<Next> const&);
661 
662       mutable lua_State* m_interpreter;
663       int m_key_index;
664 
665       Next const& m_next;
666   };
667 
668 } // namespace adl
669 
670 typedef detail::basic_iterator<detail::basic_access> iterator;
671 typedef detail::basic_iterator<detail::raw_access> raw_iterator;
672 
673 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
674 template<class T>
675 struct value_wrapper_traits<adl::index_proxy<T> >
676 #else
677 template<>
678 struct value_wrapper_traits<adl::index_proxy_tag>
679 #endif
680 {
681     typedef boost::mpl::true_ is_specialized;
682 
683     template<class Next>
interpreterluabind::value_wrapper_traits684     static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
685     {
686         return proxy.interpreter();
687     }
688 
689     template<class Next>
unwrapluabind::value_wrapper_traits690     static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
691     {
692         const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
693     }
694 };
695 
696 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
697 template<class AccessPolicy>
698 struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
699 #else
700 template<>
701 struct value_wrapper_traits<adl::iterator_proxy_tag>
702 #endif
703 {
704     typedef boost::mpl::true_ is_specialized;
705 
706     template<class Proxy>
interpreterluabind::value_wrapper_traits707     static lua_State* interpreter(Proxy const& p)
708     {
709         return p.interpreter();
710     }
711 
712     template<class Proxy>
unwrapluabind::value_wrapper_traits713     static void unwrap(lua_State* interpreter, Proxy const& p)
714     {
715         // TODO: Why const_cast?
716         const_cast<Proxy&>(p).push(interpreter);
717     }
718 };
719 
720 namespace adl
721 {
722 
723   // An object holds a reference to a Lua value residing
724   // in the registry.
725   class object : public object_interface<object>
726   {
727   public:
object()728       object()
729       {}
730 
object(handle const & other)731       explicit object(handle const& other)
732         : m_handle(other)
733       {}
734 
object(from_stack const & stack_reference)735       explicit object(from_stack const& stack_reference)
736         : m_handle(stack_reference.interpreter, stack_reference.index)
737       {
738       }
739 
740       template<class T>
object(lua_State * interpreter,T const & value)741       object(lua_State* interpreter, T const& value)
742       {
743           detail::push(interpreter, value);
744           detail::stack_pop pop(interpreter, 1);
745           handle(interpreter, -1).swap(m_handle);
746       }
747 
748       template<class T, class Policies>
object(lua_State * interpreter,T const & value,Policies const &)749       object(lua_State* interpreter, T const& value, Policies const&)
750       {
751           detail::push(interpreter, value, Policies());
752           detail::stack_pop pop(interpreter, 1);
753           handle(interpreter, -1).swap(m_handle);
754       }
755 
756       void push(lua_State* interpreter) const;
757       lua_State* interpreter() const;
758       bool is_valid() const;
759 
760       template<class T>
operator [](T const & key) const761       index_proxy<object> operator[](T const& key) const
762       {
763           return index_proxy<object>(
764               *this, m_handle.interpreter(), key
765           );
766       }
767 
swap(object & other)768       void swap(object& other)
769       {
770           m_handle.swap(other.m_handle);
771       }
772 
773   private:
774       handle m_handle;
775   };
776 
push(lua_State * interpreter) const777   inline void object::push(lua_State* interpreter) const
778   {
779       m_handle.push(interpreter);
780   }
781 
interpreter() const782   inline lua_State* object::interpreter() const
783   {
784       return m_handle.interpreter();
785   }
786 
is_valid() const787   inline bool object::is_valid() const
788   {
789       return m_handle.interpreter() != 0;
790   }
791 
792   class argument : public object_interface<argument>
793   {
794   public:
argument(from_stack const & stack_reference)795 	  argument(from_stack const& stack_reference)
796 		: m_interpreter(stack_reference.interpreter)
797 		, m_index(stack_reference.index)
798 	  {
799 		  if (m_index < 0)
800 			  m_index = lua_gettop(m_interpreter) - m_index + 1;
801 	  }
802 
803       template<class T>
operator [](T const & key) const804       index_proxy<argument> operator[](T const& key) const
805       {
806           return index_proxy<argument>(*this, m_interpreter, key);
807       }
808 
push(lua_State * L) const809 	  void push(lua_State* L) const
810 	  {
811 		  lua_pushvalue(L, m_index);
812 	  }
813 
interpreter() const814 	  lua_State* interpreter() const
815 	  {
816 		  return m_interpreter;
817 	  }
818 
819   private:
820 	  lua_State* m_interpreter;
821 	  int m_index;
822   };
823 
824 } // namespace adl
825 
826 using adl::object;
827 using adl::argument;
828 
829 #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
830 template <class ValueWrapper, class Arguments>
831 struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
832 #else
833 template<>
834 struct value_wrapper_traits<adl::call_proxy_tag>
835 #endif
836 {
837     typedef boost::mpl::true_ is_specialized;
838 
839     template<class W, class A>
interpreterluabind::value_wrapper_traits840     static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
841     {
842         return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
843     }
844 
845     template<class W, class A>
unwrapluabind::value_wrapper_traits846     static void unwrap(lua_State*, adl::call_proxy<W,A> const& proxy)
847     {
848         object result = const_cast<adl::call_proxy<W,A>&>(proxy);
849         result.push(result.interpreter());
850     }
851 };
852 
853 template<>
854 struct value_wrapper_traits<object>
855 {
856     typedef boost::mpl::true_ is_specialized;
857 
interpreterluabind::value_wrapper_traits858     static lua_State* interpreter(object const& value)
859     {
860         return value.interpreter();
861     }
862 
unwrapluabind::value_wrapper_traits863     static void unwrap(lua_State* interpreter, object const& value)
864     {
865         value.push(interpreter);
866     }
867 
checkluabind::value_wrapper_traits868     static bool check(...)
869     {
870         return true;
871     }
872 };
873 
874 template<>
875 struct value_wrapper_traits<argument>
876 {
877     typedef boost::mpl::true_ is_specialized;
878 
interpreterluabind::value_wrapper_traits879     static lua_State* interpreter(argument const& value)
880     {
881         return value.interpreter();
882     }
883 
unwrapluabind::value_wrapper_traits884     static void unwrap(lua_State* interpreter, argument const& value)
885     {
886         value.push(interpreter);
887     }
888 
checkluabind::value_wrapper_traits889     static bool check(...)
890     {
891         return true;
892     }
893 };
894 
895 template<class Next>
push(lua_State * interpreter)896 inline void adl::index_proxy<Next>::push(lua_State* interpreter)
897 {
898     assert(interpreter == m_interpreter);
899 
900     value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
901 
902     lua_pushvalue(m_interpreter, m_key_index);
903     lua_gettable(m_interpreter, -2);
904     lua_remove(m_interpreter, -2);
905 }
906 
907 template<class Next>
operator object()908 inline adl::index_proxy<Next>::operator object()
909 {
910     detail::stack_pop pop(m_interpreter, 1);
911     push(m_interpreter);
912     return object(from_stack(m_interpreter, -1));
913 }
914 
915 template<class AccessPolicy>
operator object()916 adl::iterator_proxy<AccessPolicy>::operator object()
917 {
918     lua_pushvalue(m_interpreter, m_key_index);
919     AccessPolicy::get(m_interpreter, m_table_index);
920     detail::stack_pop pop(m_interpreter, 1);
921     return object(from_stack(m_interpreter, -1));
922 }
923 
924 template<class AccessPolicy>
key() const925 object detail::basic_iterator<AccessPolicy>::key() const
926 {
927     return object(m_key);
928 }
929 
930 namespace detail
931 {
932 
933   template<
934       class T
935     , class ValueWrapper
936     , class Policies
937     , class ErrorPolicy
938     , class ReturnType
939   >
object_cast_aux(ValueWrapper const & value_wrapper,T *,Policies *,ErrorPolicy *,ReturnType *)940   ReturnType object_cast_aux(
941       ValueWrapper const& value_wrapper
942     , T*
943     , Policies*
944     , ErrorPolicy*
945     , ReturnType*
946   )
947   {
948       lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
949           value_wrapper
950       );
951 
952 #ifndef LUABIND_NO_ERROR_CHECKING
953       if (!interpreter)
954           return ErrorPolicy::handle_error(interpreter, typeid(void));
955 #endif
956 
957       value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
958 
959       detail::stack_pop pop(interpreter, 1);
960 
961       typedef typename detail::find_conversion_policy<
962           0
963         , Policies
964       >::type converter_generator;
965 
966       typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
967 
968 #ifndef LUABIND_NO_ERROR_CHECKING
969       if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
970       {
971           return ErrorPolicy::handle_error(interpreter, typeid(T));
972       }
973 #endif
974 
975       return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
976   }
977 
978 # ifdef BOOST_MSVC
979 #  pragma warning(push)
980 #  pragma warning(disable:4702) // unreachable code
981 # endif
982 
983   template<class T>
984   struct throw_error_policy
985   {
handle_errorluabind::detail::throw_error_policy986       static T handle_error(lua_State* interpreter, type_id const& type_info)
987       {
988 #ifndef LUABIND_NO_EXCEPTIONS
989           throw cast_failed(interpreter, type_info);
990 #else
991           cast_failed_callback_fun e = get_cast_failed_callback();
992           if (e) e(interpreter, type_info);
993 
994           assert(0 && "object_cast failed. If you want to handle this error use "
995               "luabind::set_error_callback()");
996           std::terminate();
997 #endif
998           return *(typename boost::remove_reference<T>::type*)0;
999       }
1000   };
1001 
1002 # ifdef BOOST_MSVC
1003 #  pragma warning(pop)
1004 # endif
1005 
1006   template<class T>
1007   struct nothrow_error_policy
1008   {
handle_errorluabind::detail::nothrow_error_policy1009       static boost::optional<T> handle_error(lua_State*, type_id const&)
1010       {
1011           return boost::optional<T>();
1012       }
1013   };
1014 
1015 } // namespace detail
1016 
1017 template<class T, class ValueWrapper>
1018 T object_cast(ValueWrapper const& value_wrapper)
1019 {
1020     return detail::object_cast_aux(
1021         value_wrapper
1022       , (T*)0
1023       , (detail::null_type*)0
1024       , (detail::throw_error_policy<T>*)0
1025       , (T*)0
1026     );
1027 }
1028 
1029 template<class T, class ValueWrapper, class Policies>
1030 T object_cast(ValueWrapper const& value_wrapper, Policies const&)
1031 {
1032     return detail::object_cast_aux(
1033         value_wrapper
1034       , (T*)0
1035       , (Policies*)0
1036       , (detail::throw_error_policy<T>*)0
1037       , (T*)0
1038     );
1039 }
1040 
1041 template<class T, class ValueWrapper>
object_cast_nothrow(ValueWrapper const & value_wrapper)1042 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
1043 {
1044     return detail::object_cast_aux(
1045         value_wrapper
1046       , (T*)0
1047       , (detail::null_type*)0
1048       , (detail::nothrow_error_policy<T>*)0
1049       , (boost::optional<T>*)0
1050     );
1051 }
1052 
1053 template<class T, class ValueWrapper, class Policies>
object_cast_nothrow(ValueWrapper const & value_wrapper,Policies const &)1054 boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
1055 {
1056     return detail::object_cast_aux(
1057         value_wrapper
1058       , (T*)0
1059       , (Policies*)0
1060       , (detail::nothrow_error_policy<T>*)0
1061       , (boost::optional<T>*)0
1062     );
1063 }
1064 
1065 namespace detail
1066 {
1067 
1068   template<int Index>
1069   struct push_args_from_tuple
1070   {
1071       template<class H, class T, class Policies>
applyluabind::detail::push_args_from_tuple1072       inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
1073       {
1074           convert_to_lua_p<Index>(L, *x.get_head(), p);
1075           push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
1076       }
1077 
1078       template<class H, class T>
applyluabind::detail::push_args_from_tuple1079       inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
1080       {
1081           convert_to_lua(L, *x.get_head());
1082           push_args_from_tuple<Index+1>::apply(L, x.get_tail());
1083       }
1084 
1085       template<class Policies>
applyluabind::detail::push_args_from_tuple1086       inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
1087 
applyluabind::detail::push_args_from_tuple1088       inline static void apply(lua_State*, const boost::tuples::null_type&) {}
1089   };
1090 
1091 } // namespace detail
1092 
1093 namespace adl
1094 {
1095 
1096   template<class ValueWrapper, class Arguments>
1097   struct call_proxy
1098   {
call_proxyluabind::adl::call_proxy1099       call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
1100         : value_wrapper(&value_wrapper)
1101         , arguments(arguments)
1102       {}
1103 
call_proxyluabind::adl::call_proxy1104       call_proxy(call_proxy const& other)
1105         : value_wrapper(other.value_wrapper)
1106         , arguments(other.arguments)
1107       {
1108           other.value_wrapper = 0;
1109       }
1110 
~call_proxyluabind::adl::call_proxy1111       ~call_proxy()
1112       {
1113           if (value_wrapper)
1114               call((detail::null_type*)0);
1115       }
1116 
operator objectluabind::adl::call_proxy1117       operator object()
1118       {
1119           return call((detail::null_type*)0);
1120       }
1121 
1122       template<class Policies>
operator []luabind::adl::call_proxy1123       object operator[](Policies const&)
1124       {
1125           return call((Policies*)0);
1126       }
1127 
1128       template<class Policies>
callluabind::adl::call_proxy1129       object call(Policies*)
1130       {
1131           lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1132               *value_wrapper
1133           );
1134 
1135           value_wrapper_traits<ValueWrapper>::unwrap(
1136               interpreter
1137             , *value_wrapper
1138           );
1139 
1140           value_wrapper = 0;
1141 
1142           detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
1143 
1144           if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
1145           {
1146 #ifndef LUABIND_NO_EXCEPTIONS
1147               throw luabind::error(interpreter);
1148 #else
1149               error_callback_fun e = get_error_callback();
1150               if (e) e(interpreter);
1151 
1152               assert(0 && "the lua function threw an error and exceptions are disabled."
1153                   "if you want to handle this error use luabind::set_error_callback()");
1154               std::terminate();
1155 #endif
1156           }
1157 
1158           detail::stack_pop pop(interpreter, 1);
1159           return object(from_stack(interpreter, -1));
1160       }
1161 
1162       mutable ValueWrapper* value_wrapper;
1163       Arguments arguments;
1164   };
1165 
1166   template<class Derived>
1167   call_proxy<Derived, boost::tuples::tuple<> >
operator ()()1168   object_interface<Derived>::operator()()
1169   {
1170       return call_proxy<Derived, boost::tuples::tuple<> >(
1171           derived()
1172         , boost::tuples::tuple<>()
1173       );
1174   }
1175 
1176   // Simple value_wrapper adaptor with the sole purpose of helping with
1177   // overload resolution. Use this as a function parameter type instead
1178   // of "object" or "argument" to restrict the parameter to Lua tables.
1179   template <class Base = object>
1180   struct table : Base
1181   {
tableluabind::adl::table1182       table(from_stack const& stack_reference)
1183         : Base(stack_reference)
1184       {}
1185   };
1186 
1187 } // namespace adl
1188 
1189 using adl::table;
1190 
1191 template <class Base>
1192 struct value_wrapper_traits<adl::table<Base> >
1193   : value_wrapper_traits<Base>
1194 {
checkluabind::value_wrapper_traits1195     static bool check(lua_State* L, int idx)
1196     {
1197         return value_wrapper_traits<Base>::check(L, idx) &&
1198             lua_istable(L, idx);
1199     }
1200 };
1201 
newtable(lua_State * interpreter)1202 inline object newtable(lua_State* interpreter)
1203 {
1204     lua_newtable(interpreter);
1205     detail::stack_pop pop(interpreter, 1);
1206     return object(from_stack(interpreter, -1));
1207 }
1208 
1209 // this could be optimized by returning a proxy
globals(lua_State * interpreter)1210 inline object globals(lua_State* interpreter)
1211 {
1212     lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
1213     detail::stack_pop pop(interpreter, 1);
1214     return object(from_stack(interpreter, -1));
1215 }
1216 
1217 // this could be optimized by returning a proxy
registry(lua_State * interpreter)1218 inline object registry(lua_State* interpreter)
1219 {
1220     lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
1221     detail::stack_pop pop(interpreter, 1);
1222     return object(from_stack(interpreter, -1));
1223 }
1224 
1225 template<class ValueWrapper, class K>
gettable(ValueWrapper const & table,K const & key)1226 inline object gettable(ValueWrapper const& table, K const& key)
1227 {
1228     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1229         table
1230     );
1231 
1232     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1233     detail::stack_pop pop(interpreter, 2);
1234     detail::push(interpreter, key);
1235     lua_gettable(interpreter, -2);
1236     return object(from_stack(interpreter, -1));
1237 }
1238 
1239 template<class ValueWrapper, class K, class T>
settable(ValueWrapper const & table,K const & key,T const & value)1240 inline void settable(ValueWrapper const& table, K const& key, T const& value)
1241 {
1242     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1243         table
1244     );
1245 
1246     // TODO: Exception safe?
1247 
1248     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1249     detail::stack_pop pop(interpreter, 1);
1250     detail::push(interpreter, key);
1251     detail::push(interpreter, value);
1252     lua_settable(interpreter, -3);
1253 }
1254 
1255 template<class ValueWrapper, class K>
rawget(ValueWrapper const & table,K const & key)1256 inline object rawget(ValueWrapper const& table, K const& key)
1257 {
1258     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1259         table
1260     );
1261 
1262     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1263     detail::stack_pop pop(interpreter, 2);
1264     detail::push(interpreter, key);
1265     lua_rawget(interpreter, -2);
1266     return object(from_stack(interpreter, -1));
1267 }
1268 
1269 template<class ValueWrapper, class K, class T>
rawset(ValueWrapper const & table,K const & key,T const & value)1270 inline void rawset(ValueWrapper const& table, K const& key, T const& value)
1271 {
1272     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1273         table
1274     );
1275 
1276     // TODO: Exception safe?
1277 
1278     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
1279     detail::stack_pop pop(interpreter, 1);
1280     detail::push(interpreter, key);
1281     detail::push(interpreter, value);
1282     lua_rawset(interpreter, -3);
1283 }
1284 
1285 template<class ValueWrapper>
type(ValueWrapper const & value)1286 inline int type(ValueWrapper const& value)
1287 {
1288     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1289         value
1290     );
1291 
1292     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1293     detail::stack_pop pop(interpreter, 1);
1294     return lua_type(interpreter, -1);
1295 }
1296 
1297 template <class ValueWrapper>
getmetatable(ValueWrapper const & obj)1298 inline object getmetatable(ValueWrapper const& obj)
1299 {
1300     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1301         obj
1302     );
1303 
1304     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, obj);
1305     detail::stack_pop pop(interpreter, 2);
1306     lua_getmetatable(interpreter, -1);
1307     return object(from_stack(interpreter, -1));
1308 }
1309 
1310 template <class ValueWrapper1, class ValueWrapper2>
setmetatable(ValueWrapper1 const & obj,ValueWrapper2 const & metatable)1311 inline void setmetatable(
1312     ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
1313 {
1314     lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1315         obj
1316     );
1317 
1318     value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, obj);
1319     detail::stack_pop pop(interpreter, 1);
1320     value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, metatable);
1321     lua_setmetatable(interpreter, -2);
1322 }
1323 
1324 template <class ValueWrapper>
tocfunction(ValueWrapper const & value)1325 inline lua_CFunction tocfunction(ValueWrapper const& value)
1326 {
1327     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1328         value
1329     );
1330 
1331     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1332     detail::stack_pop pop(interpreter, 1);
1333     return lua_tocfunction(interpreter, -1);
1334 }
1335 
1336 template <class T, class ValueWrapper>
touserdata(ValueWrapper const & value)1337 inline T* touserdata(ValueWrapper const& value)
1338 {
1339     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1340         value
1341     );
1342 
1343     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1344     detail::stack_pop pop(interpreter, 1);
1345     return static_cast<T*>(lua_touserdata(interpreter, -1));
1346 }
1347 
1348 template <class ValueWrapper>
getupvalue(ValueWrapper const & value,int index)1349 inline object getupvalue(ValueWrapper const& value, int index)
1350 {
1351     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
1352         value
1353     );
1354 
1355     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
1356     detail::stack_pop pop(interpreter, 2);
1357     lua_getupvalue(interpreter, -1, index);
1358     return object(from_stack(interpreter, -1));
1359 }
1360 
1361 template <class ValueWrapper1, class ValueWrapper2>
setupvalue(ValueWrapper1 const & function,int index,ValueWrapper2 const & value)1362 inline void setupvalue(
1363     ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
1364 {
1365     lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
1366         function
1367     );
1368 
1369     value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, function);
1370     detail::stack_pop pop(interpreter, 1);
1371     value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, value);
1372     lua_setupvalue(interpreter, -2, index);
1373 }
1374 
1375 template <class GetValueWrapper>
property(GetValueWrapper const & get)1376 object property(GetValueWrapper const& get)
1377 {
1378     lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1379         get
1380     );
1381 
1382     value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1383     lua_pushnil(interpreter);
1384 
1385     lua_pushcclosure(interpreter, &detail::property_tag, 2);
1386     detail::stack_pop pop(interpreter, 1);
1387 
1388     return object(from_stack(interpreter, -1));
1389 }
1390 
1391 template <class GetValueWrapper, class SetValueWrapper>
property(GetValueWrapper const & get,SetValueWrapper const & set)1392 object property(GetValueWrapper const& get, SetValueWrapper const& set)
1393 {
1394     lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
1395         get
1396     );
1397 
1398     value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
1399     value_wrapper_traits<SetValueWrapper>::unwrap(interpreter, set);
1400 
1401     lua_pushcclosure(interpreter, &detail::property_tag, 2);
1402     detail::stack_pop pop(interpreter, 1);
1403 
1404     return object(from_stack(interpreter, -1));
1405 
1406 }
1407 
1408 
1409 } // namespace luabind
1410 
1411 #endif // LUABIND_OBJECT_050419_HPP
1412 
1413