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