*** empty log message ***
[luabind.git] / luabind / object.hpp
blobe47b803e85140fb31da43e9aab8911ef73287e25
1 // Copyright (c) 2003 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 #if !BOOST_PP_IS_ITERATING
25 #ifndef LUABIND_OBJECT_HPP_INCLUDED
26 #define LUABIND_OBJECT_HPP_INCLUDED
28 #include <iterator>
30 #include <luabind/prefix.hpp>
31 #include <luabind/config.hpp>
32 #include <luabind/error.hpp>
33 #include <luabind/detail/pcall.hpp>
35 #include <boost/preprocessor/repeat.hpp>
36 #include <boost/preprocessor/iteration/iterate.hpp>
37 #include <boost/preprocessor/repetition/enum.hpp>
38 #include <boost/preprocessor/repetition/enum_params.hpp>
39 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
40 #include <boost/tuple/tuple.hpp>
42 namespace luabind
44 class object;
46 namespace detail
48 class proxy_object;
49 class proxy_raw_object;
50 class proxy_array_object;
52 template<class T>
53 void convert_to_lua(lua_State*, const T&);
55 template<int Index, class T, class Policies>
56 void convert_to_lua_p(lua_State*, const T&, const Policies&);
58 template<int Index>
59 struct push_args_from_tuple
61 template<class H, class T, class Policies>
62 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
64 convert_to_lua_p<Index>(L, *x.get_head(), p);
65 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
68 template<class H, class T>
69 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
71 convert_to_lua(L, *x.get_head());
72 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
75 template<class Policies>
76 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
78 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
82 template<class Tuple>
83 class proxy_caller
85 friend class luabind::object;
86 public:
88 proxy_caller(luabind::object* o, const Tuple args)
89 : m_obj(o)
90 , m_args(args)
91 , m_called(false)
95 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
96 : m_obj(rhs.m_obj)
97 , m_args(rhs.m_args)
98 , m_called(rhs.m_called)
100 rhs.m_called = true;
103 ~proxy_caller();
104 operator luabind::object();
106 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
107 #define LUABIND_SEMICOLON
108 #else
109 #define LUABIND_SEMICOLON ;
110 #endif
112 template<class Policies>
113 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
114 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
116 m_called = true;
117 lua_State* L = m_obj->lua_state();
118 m_obj->pushvalue();
119 detail::push_args_from_tuple<1>::apply(L, m_args, p);
120 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
122 #ifndef LUABIND_NO_EXCEPTIONS
123 throw error(L);
124 #else
125 error_callback_fun e = get_error_callback();
126 if (e) e(L);
128 assert(0 && "the lua function threw an error and exceptions are disabled."
129 "if you want to handle this error use luabind::set_error_callback()");
130 std::terminate();
131 #endif
133 detail::lua_reference ref;
134 ref.set(L);
135 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
137 #endif
140 #undef LUABIND_SEMICOLON
141 private:
143 luabind::object* m_obj;
144 Tuple m_args;
145 mutable bool m_called;
151 struct stack_pop
153 stack_pop(lua_State* L, int n)
154 : m_state(L)
155 , m_n(n)
159 ~stack_pop()
161 lua_pop(m_state, m_n);
164 private:
166 lua_State* m_state;
167 int m_n;
174 class LUABIND_API proxy_object
176 friend class luabind::object;
177 friend class luabind::detail::proxy_array_object;
178 friend class luabind::detail::proxy_raw_object;
179 // template<class T> friend T object_cast(const proxy_object& obj);
180 public:
182 template<class T>
183 proxy_object& operator=(const T& val)
185 //std::cout << "proxy assigment\n";
186 lua_State* L = m_obj->m_state;
187 m_obj->pushvalue();
188 m_key.get(L);
189 detail::convert_to_lua(L, val);
190 lua_settable(L, -3);
191 // pop table
192 lua_pop(L, 1);
193 return *this;
196 template<class T, class Policies>
197 void assign(const T& val, const Policies& p)
199 //std::cout << "proxy assigment\n";
200 lua_State* L = m_obj->m_state;
201 m_obj->pushvalue();
202 detail::getref(L, m_key_ref);
203 detail::convert_to_lua_p(L, val, p);
204 lua_settable(L, -3);
205 // pop table
206 lua_pop(L, 1);
207 return *this;
210 template<class T>
211 detail::proxy_object operator[](const T& key) const;
213 proxy_object& operator=(const object& p);
214 proxy_object& operator=(const proxy_object& p);
215 proxy_object& operator=(const proxy_raw_object& p);
216 proxy_object& operator=(const proxy_array_object& p);
218 void swap(const proxy_object& rhs);
219 proxy_object* operator->()
220 { return this; }
222 operator luabind::object();
224 int type() const
226 pushvalue();
227 detail::stack_pop p(lua_state(), 1);
228 return lua_type(lua_state(), -1);
231 #define LUABIND_PROXY_RAW_AT_BODY \
233 lua_State* L = lua_state();\
234 pushvalue();\
235 detail::convert_to_lua(L, key);\
236 lua_rawget(L, -2);\
237 detail::lua_reference ref;\
238 ref.set(L);\
239 lua_pop(L, 1);\
240 return object(L, ref, true);\
243 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
244 template<class T>
245 inline object raw_at(const T& key)
246 LUABIND_PROXY_RAW_AT_BODY
247 #else
248 template<class T>
249 inline object raw_at(const T& key);
250 #endif
252 #define LUABIND_PROXY_AT_BODY \
254 lua_State* L = lua_state();\
255 pushvalue();\
256 detail::convert_to_lua(L, key);\
257 lua_gettable(L, -2);\
258 detail::lua_reference ref;\
259 ref.set(L);\
260 lua_pop(L, 1);\
261 return object(L, ref, true);\
264 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
265 template<class T>
266 inline object at(const T& key)
267 LUABIND_PROXY_AT_BODY
268 #else
269 template<class T>
270 inline object at(const T& key);
271 #endif
273 inline bool is_valid() const { return true; }
274 lua_State* lua_state() const;
275 void pushvalue() const;
276 void set() const;
278 // this is a safe substitute for an implicit converter to bool
279 typedef void (proxy_object::*member_ptr)() const;
280 operator member_ptr() const
282 if (is_valid()) return &proxy_object::dummy;
283 return 0;
286 private:
288 void dummy() const {}
290 proxy_object(luabind::object* o, const lua_reference& key)
291 : m_obj(o)
292 , m_key(key)
296 luabind::object* m_obj;
297 detail::lua_reference m_key;
302 class LUABIND_API proxy_raw_object
304 friend class luabind::object;
305 friend class luabind::detail::proxy_array_object;
306 friend class luabind::detail::proxy_object;
307 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
308 public:
310 template<class T>
311 proxy_raw_object& operator=(const T& val)
313 //std::cout << "proxy assigment\n";
314 lua_State* L = m_obj->m_state;
315 m_obj->pushvalue();
316 detail::getref(L, m_key_ref);
317 detail::convert_to_lua(L, val);
318 lua_rawset(L, -3);
319 // pop table
320 lua_pop(L, 1);
321 return *this;
324 template<class T, class Policies>
325 void assign(const T& val, const Policies& p)
327 //std::cout << "proxy assigment\n";
328 lua_State* L = m_obj->m_state;
329 m_obj->pushvalue();
330 detail::getref(L, m_key_ref);
331 detail::convert_to_lua_p(L, val, p);
332 lua_settable(L, -3);
333 // pop table
334 lua_pop(L, 1);
335 return *this;
338 template<class T>
339 detail::proxy_object operator[](const T& key) const;
341 proxy_raw_object& operator=(const object& p);
342 proxy_raw_object& operator=(const proxy_object& p);
343 proxy_raw_object& operator=(const proxy_raw_object& p);
344 proxy_raw_object& operator=(const proxy_array_object& p);
345 void swap(const proxy_raw_object& rhs);
346 proxy_raw_object* operator->()
347 { return this; }
349 operator luabind::object();
351 int type() const
353 pushvalue();
354 detail::stack_pop p(lua_state(), 1);
355 return lua_type(lua_state(), -1);
358 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
359 template<class T>
360 inline object raw_at(const T& key)
361 LUABIND_PROXY_RAW_AT_BODY
362 #else
363 template<class T>
364 inline object raw_at(const T& key);
365 #endif
367 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
368 template<class T>
369 inline object at(const T& key)
370 LUABIND_PROXY_AT_BODY
371 #else
372 template<class T>
373 inline object at(const T& key);
374 #endif
376 inline bool is_valid() const { return true; }
377 lua_State* lua_state() const;
378 void pushvalue() const;
379 void set() const;
381 // this is a safe substitute for an implicit converter to bool
382 typedef void (proxy_raw_object::*member_ptr)() const;
383 operator member_ptr() const
385 if (is_valid()) return &proxy_raw_object::dummy;
386 return 0;
390 private:
392 void dummy() const {}
394 proxy_raw_object(luabind::object* o, const lua_reference& key)
395 : m_obj(o)
396 , m_key(key)
400 luabind::object* m_obj;
401 detail::lua_reference m_key;
406 class LUABIND_API proxy_array_object
408 friend class luabind::object;
409 friend class luabind::detail::proxy_object;
410 friend class luabind::detail::proxy_raw_object;
411 // template<class T> friend T object_cast(const proxy_array_object& obj);
412 public:
414 template<class T>
415 proxy_array_object& operator=(const T& val)
417 //std::cout << "array proxy assigment\n";
418 lua_State* L = m_obj->m_state;
419 m_obj->pushvalue();
420 detail::convert_to_lua(L, val);
421 lua_rawseti(L, -2, m_key);
423 // pops the table
424 lua_pop(L, 1);
425 return *this;
428 template<class T, class Policies>
429 void assign(const T& val, const Policies& p)
431 //std::cout << "proxy assigment\n";
432 lua_State* L = m_obj->m_state;
433 m_obj->pushvalue();
434 detail::convert_to_lua_p(L, val, p);
435 lua_rawseti(L, -2, m_key);
436 // pop table
437 lua_pop(L, 1);
438 return *this;
441 template<class T>
442 detail::proxy_object operator[](const T& key) const;
444 proxy_array_object& operator=(const object& p);
445 proxy_array_object& operator=(const proxy_object& p);
446 proxy_array_object& operator=(const proxy_raw_object& p);
447 proxy_array_object& operator=(const proxy_array_object& p);
448 void swap(const proxy_array_object& rhs);
450 proxy_array_object* operator->()
451 { return this; }
452 operator luabind::object();
454 int type() const
456 pushvalue();
457 detail::stack_pop p(lua_state(), 1);
458 return lua_type(lua_state(), -1);
461 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
463 pushvalue();\
464 detail::convert_to_lua(m_state, key);\
465 lua_rawget(m_state, -2);\
466 lua_reference ref;\
467 ref.set(m_state);\
468 lua_pop(m_state, 1);\
469 return object(m_state, ref, true);\
472 #define LUABIND_PROXY_ARRAY_AT_BODY\
474 pushvalue();\
475 detail::convert_to_lua(m_state, key);\
476 lua_gettable(m_state, -2);\
477 lua_reference ref;\
478 ref.set(m_state);\
479 lua_pop(m_state, 1);\
480 return object(m_state, ref, true);\
483 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
484 template<class T>
485 inline object at(const T& key)
486 LUABIND_PROXY_ARRAY_AT_BODY
487 #else
488 template<class T>
489 inline object at(const T& key);
490 #endif
493 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
494 template<class T>
495 inline object raw_at(const T& key)
496 LUABIND_PROXY_ARRAY_RAW_AT_BODY
497 #else
498 template<class T>
499 inline object raw_at(const T& key);
500 #endif
502 template<class T>
503 inline detail::proxy_object operator[](const T& key) const
505 detail::convert_to_lua(m_state, key);
506 lua_reference ref;
507 ref.set(m_state);
508 return detail::proxy_object(const_cast<object*>(this), ref);
511 inline bool is_valid() const { return true; }
512 lua_State* lua_state() const;
513 void pushvalue() const;
514 void set() const;
516 // this is a safe substitute for an implicit converter to bool
517 typedef void (proxy_array_object::*member_ptr)() const;
518 operator member_ptr() const
520 if (is_valid()) return &proxy_array_object::dummy;
521 return 0;
524 private:
526 void dummy() const {}
528 proxy_array_object(luabind::object* o, int key)
529 : m_obj(o)
530 , m_key(key)
532 luabind::object* m_obj;
533 int m_key;
536 template<class T>
537 struct primitive_converter;
539 struct tuple_object_ref;
541 } // detail
543 class LUABIND_API object
546 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
548 template<class T>
549 friend T object_cast(const object& obj);
550 template<class T>
551 friend struct detail::primitive_converter;
553 #endif
555 friend object get_globals(lua_State*);
556 friend object get_registry(lua_State*);
557 friend object newtable(lua_State*);
558 friend class detail::proxy_object;
559 friend class detail::proxy_array_object;
560 friend class detail::proxy_raw_object;
562 public:
564 class array_iterator
566 friend class object;
567 public:
569 typedef std::forward_iterator_tag iterator_category;
570 typedef luabind::object value_type;
571 typedef value_type& reference;
572 typedef value_type* pointer;
573 typedef void difference_type;
575 array_iterator()
576 : m_obj(0)
577 , m_key(0)
581 array_iterator(const array_iterator& iter)
582 : m_obj(iter.m_obj)
583 , m_key(iter.m_key)
587 ~array_iterator() {}
589 array_iterator& operator=(const array_iterator& rhs)
591 m_obj = rhs.m_obj;
592 m_key = rhs.m_key;
593 return *this;
596 detail::proxy_array_object operator*()
598 return m_obj->make_array_proxy(m_key);
601 detail::proxy_array_object operator->()
603 return m_obj->make_array_proxy(m_key);
606 inline array_iterator& operator++()
608 LUABIND_CHECK_STACK(m_obj->lua_state());
610 m_key++;
612 // invalidate the iterator if we hit a nil element
613 lua_State* L = m_obj->lua_state();
614 m_obj->pushvalue();
615 lua_rawgeti(L, -1, m_key);
616 if (lua_isnil(L, -1)) m_key = -1;
617 lua_pop(L, 2);
619 return *this;
622 inline array_iterator operator++(int)
624 LUABIND_CHECK_STACK(m_obj->lua_state());
626 int old_key = m_key;
627 m_key++;
629 // invalidate the iterator if we hit a nil element
630 lua_State* L = m_obj->lua_state();
631 m_obj->pushvalue();
632 lua_rawgeti(L, -1, m_key);
633 if (lua_isnil(L, -1)) m_key = -1;
634 lua_pop(L, 2);
636 return array_iterator(m_obj, old_key);
639 bool operator!=(const array_iterator& rhs) const
641 return m_obj != rhs.m_obj || m_key != rhs.m_key;
644 private:
646 array_iterator(object* obj, int key)
647 : m_obj(obj)
648 , m_key(key)
652 object* m_obj;
653 int m_key;
661 class iterator
663 friend class object;
664 public:
666 typedef std::forward_iterator_tag iterator_category;
667 typedef luabind::object value_type;
668 typedef value_type& reference;
669 typedef value_type* pointer;
670 typedef void difference_type;
672 iterator()
673 : m_obj(0)
677 iterator(const iterator& iter)
678 : m_obj(iter.m_obj)
680 if (m_obj)
682 m_key = iter.m_key;
686 iterator& operator=(const iterator& rhs)
688 m_obj = rhs.m_obj;
689 if (m_obj)
691 m_key = rhs.m_key;
693 else
695 m_key.reset();
697 return *this;
700 detail::proxy_object operator*()
702 return m_obj->make_proxy(m_key);
705 detail::proxy_object operator->()
707 return m_obj->make_proxy(m_key);
710 iterator& operator++()
712 lua_State* L = m_obj->lua_state();
714 int n = lua_gettop(L);
716 m_obj->pushvalue();
717 m_key.get(L);
719 if (lua_next(L, -2) != 0)
721 lua_pop(L, 1);
722 m_key.replace(L);
723 lua_pop(L, 1);
725 else
727 lua_pop(L, 1);
728 m_obj = 0;
729 m_key.reset();
732 assert(n == lua_gettop(L));
733 return *this;
736 bool operator!=(const iterator& rhs) const
738 if (m_obj != rhs.m_obj) return true;
739 if (m_obj == 0) return false;
740 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
741 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
743 // TODO: fix this. add a real equality test of the keys
744 return true;
747 object key() const;
749 private:
751 iterator(luabind::object* obj, detail::lua_reference const& key)
752 : m_obj(obj)
753 , m_key(key)
757 object* m_obj;
758 detail::lua_reference m_key;
764 class raw_iterator
766 friend class object;
767 public:
769 typedef std::forward_iterator_tag iterator_category;
770 typedef luabind::object value_type;
771 typedef value_type& reference;
772 typedef value_type* pointer;
773 typedef void difference_type;
775 raw_iterator()
776 : m_obj(0)
780 raw_iterator(const raw_iterator& iter)
781 : m_obj(iter.m_obj)
782 , m_key()
784 if (m_obj)
786 m_key = iter.m_key;
790 raw_iterator& operator=(const raw_iterator& rhs)
792 //std::cout << "===\n";
793 m_obj = rhs.m_obj;
794 if (m_obj)
796 m_key = rhs.m_key;
798 else
800 m_key.reset();
802 return *this;
805 detail::proxy_raw_object operator*()
807 return m_obj->make_raw_proxy(m_key);
810 detail::proxy_raw_object operator->()
812 return m_obj->make_raw_proxy(m_key);
815 raw_iterator& operator++()
817 lua_State* L = m_obj->lua_state();
818 m_obj->pushvalue();
819 m_key.get(L);
821 if (lua_next(L, -2) != 0)
823 lua_pop(L, 1);
824 m_key.replace(L);
825 lua_pop(L, 1);
827 else
829 lua_pop(L, 1);
830 m_key.reset();
831 m_obj = 0;
834 return *this;
837 object key() const;
839 bool operator!=(const raw_iterator& rhs) const
841 if (m_obj != rhs.m_obj) return true;
842 if (m_obj == 0) return false;
843 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
844 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
846 // TODO: fix this. add a real equality test of the keys
847 return true;
850 private:
852 raw_iterator(object* obj, detail::lua_reference const& key)
853 : m_obj(obj)
854 , m_key(key)
857 object* m_obj;
858 detail::lua_reference m_key;
866 object()
867 : m_state(0)
871 explicit object(lua_State* L)
872 : m_state(L)
876 template<class T>
877 object(lua_State* L, const T& val)
878 : m_state(L)
880 *this = val;
883 object(const object& o)
884 : m_state(o.m_state)
886 o.m_ref.get(m_state);
887 m_ref.set(m_state);
890 inline ~object()
893 inline bool is_valid() const { return m_ref.is_valid(); }
895 // this is a safe substitute for an implicit converter to bool
896 typedef void (object::*member_ptr)() const;
897 operator member_ptr() const
899 if (is_valid()) return &object::dummy;
900 return 0;
903 int type() const
905 pushvalue();
906 detail::stack_pop p(lua_state(), 1);
907 return lua_type(lua_state(), -1);
910 inline iterator begin() const
912 m_ref.get(m_state);
913 lua_pushnil(m_state);
914 lua_next(m_state, -2);
915 lua_pop(m_state, 1);
916 detail::lua_reference r;
917 r.set(m_state);
918 iterator i(const_cast<object*>(this), r);
919 lua_pop(m_state, 1);
920 return i;
923 inline iterator end() const
925 return iterator(0, detail::lua_reference());
928 inline array_iterator abegin() const
930 return array_iterator(const_cast<object*>(this), 1);
933 inline array_iterator aend() const
935 return array_iterator(const_cast<object*>(this), -1);
938 raw_iterator raw_begin() const
940 m_ref.get(m_state);
941 lua_pushnil(m_state);
942 lua_next(m_state, -2);
943 lua_pop(m_state, 1);
944 detail::lua_reference r;
945 r.set(m_state);
946 raw_iterator i(const_cast<object*>(this), r);
947 lua_pop(m_state, 1);
948 return i;
951 raw_iterator raw_end() const
953 return raw_iterator(0, detail::lua_reference());
956 inline void set() const
958 // you are trying to access an invalid object
959 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
961 allocate_slot();
962 m_ref.replace(m_state);
964 inline lua_State* lua_state() const { return m_state; }
965 inline void pushvalue() const
967 // you are trying to dereference an invalid object
968 assert((m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
969 assert((m_state != 0) && "internal error, please report");
971 m_ref.get(m_state);
974 void swap(object& rhs);
976 template<class T>
977 inline object raw_at(const T& key)
979 lua_State* L = lua_state();
980 pushvalue();
981 detail::convert_to_lua(L, key);
982 lua_rawget(L, -2);
983 detail::lua_reference ref;
984 ref.set(L);
985 lua_pop(L, 1);
986 return object(L, ref, true);
989 template<class T>
990 inline object at(const T& key)
992 LUABIND_CHECK_STACK(m_state);
994 lua_State* L = lua_state();
995 pushvalue();
996 detail::convert_to_lua(L, key);
997 lua_gettable(L, -2);
998 detail::lua_reference ref;
999 ref.set(L);
1000 lua_pop(L, 1);
1001 return object(L, ref, true);
1004 template<class T>
1005 inline detail::proxy_object operator[](const T& key) const
1007 LUABIND_CHECK_STACK(m_state);
1009 detail::convert_to_lua(m_state, key);
1010 detail::lua_reference ref;
1011 ref.set(m_state);
1012 return detail::proxy_object(const_cast<object*>(this), ref);
1017 // *****************************
1018 // OPERATOR =
1020 template<class T>
1021 object& operator=(const T& val) const
1023 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1024 // you cannot assign a non-lua value to an uninitialized object
1026 detail::convert_to_lua(m_state, val);
1027 set();
1028 return const_cast<luabind::object&>(*this);
1031 object& operator=(const object& o) const;
1032 object& operator=(const detail::proxy_object& o) const;
1033 object& operator=(const detail::proxy_raw_object& o) const;
1034 object& operator=(const detail::proxy_array_object& o) const;
1036 template<class T, class Policies>
1037 void assign(const T& val, const Policies& p) const
1039 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1040 // you cannot assign a non-lua value to an uninitialized object
1042 detail::convert_to_lua_p(m_state, val, p);
1043 set();
1046 // const overload should return a tuple_object..?
1047 inline detail::tuple_object_ref operator,(const object& rhs) const;
1049 // *****************************
1050 // OPERATOR()
1052 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1053 #include BOOST_PP_ITERATE()
1057 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1059 return detail::proxy_object(this, key);
1062 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1064 return detail::proxy_raw_object(this, key);
1067 inline detail::proxy_array_object make_array_proxy(int key)
1069 return detail::proxy_array_object(this, key);
1072 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1073 // it's an inner class), that's why this interface is public
1074 // private:
1076 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1077 : m_state(L)
1078 , m_ref(ref)
1082 private:
1084 void dummy() const {}
1086 void allocate_slot() const
1088 if (!m_ref.is_valid())
1090 lua_pushboolean(m_state, 0);
1091 m_ref.set(m_state);
1095 mutable lua_State* m_state;
1096 mutable detail::lua_reference m_ref;
1100 // *************************************
1101 // OBJECT
1103 inline void object::swap(object& rhs)
1105 // you cannot swap objects from different lua states
1106 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1107 m_ref.swap(rhs.m_ref);
1110 inline object object::iterator::key() const
1112 lua_State* L = m_obj->lua_state();
1113 return object(L, m_key, true);
1116 inline object object::raw_iterator::key() const
1118 lua_State* L = m_obj->lua_state();
1119 return object(L, m_key, true);
1122 namespace detail
1124 // tuple object ----------------------------------------------
1126 struct tuple_object;
1128 struct tuple_object_ref
1130 tuple_object_ref(object* a, object* b)
1131 : n(2)
1132 { refs[0] = a; refs[1] = b; }
1134 tuple_object_ref& operator,(const object& x)
1135 { refs[n++] = const_cast<object*>(&x); return *this; }
1137 struct assign_into
1139 assign_into() {}
1141 template<class T>
1142 assign_into(tuple_object_ref& to, const T& val)
1143 : target(&to)
1144 , n(0)
1146 if (n >= target->n) return;
1147 *target->refs[n++] = val;
1150 template<class T>
1151 assign_into& operator,(const T& val)
1153 if (n >= target->n) return *this;
1154 *target->refs[n++] = val;
1155 return *this;
1158 tuple_object_ref* target;
1159 std::size_t n;
1162 template<class T>
1163 assign_into operator=(const T& val)
1164 { return assign_into(*this, val); }
1166 tuple_object_ref(const tuple_object_ref&);
1167 assign_into operator=(const tuple_object_ref& x)
1169 for (std::size_t i = 0; i < n && i < x.n; ++i)
1170 *refs[i] = *x.refs[i];
1171 return assign_into();
1174 inline assign_into operator=(const tuple_object&);
1176 std::size_t n;
1177 object* refs[10];
1180 struct tuple_object
1182 tuple_object(const object& x)
1183 : n(0)
1184 { objs[n++] = x; }
1186 tuple_object(const tuple_object_ref& x)
1188 for (std::size_t i = 0; i < x.n; ++i)
1189 objs[i] = *x.refs[i];
1192 std::size_t n;
1193 object objs[10];
1196 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1198 for (std::size_t i = 0; i < n && i < x.n; ++i)
1199 *refs[i] = x.objs[i];
1200 return assign_into();
1203 // *************************************
1204 // PROXY CALLER
1206 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1207 template<class Tuple>
1208 template<class Policies>
1209 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1211 m_called = true;
1212 lua_State* L = m_obj->lua_state();
1213 m_obj->pushvalue();
1214 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1215 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1217 #ifndef LUABIND_NO_EXCEPTIONS
1218 throw error(L);
1219 #else
1220 error_callback_fun e = get_error_callback();
1221 if (e) e(L);
1223 assert(0 && "the lua function threw an error and exceptions are disabled."
1224 "if you want to handle this error use luabind::set_error_callback()");
1225 std::terminate();
1226 #endif
1228 detail::lua_reference ref;
1229 ref.set(L);
1230 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1232 #endif
1233 // *************************************
1234 // PROXY OBJECT
1236 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1237 template<class T>
1238 inline object proxy_object::raw_at(const T& key)
1239 LUABIND_PROXY_RAW_AT_BODY
1241 template<class T>
1242 inline object proxy_object::at(const T& key)
1243 LUABIND_PROXY_AT_BODY
1244 #endif
1246 inline lua_State* proxy_object::lua_state() const
1248 return m_obj->lua_state();
1251 inline proxy_object::operator luabind::object()
1253 lua_State* L = m_obj->lua_state();
1254 pushvalue();
1255 detail::lua_reference ref;
1256 ref.set(L);
1257 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1261 // *************************************
1262 // PROXY ARRAY OBJECT
1264 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1265 template<class T>
1266 inline object proxy_array_object::raw_at(const T& key)
1267 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1269 template<class T>
1270 inline object proxy_array_object::at(const T& key)
1271 LUABIND_PROXY_ARRAY_AT_BODY
1272 #endif
1274 #undef LUABIND_PROXY_ARRAY_AT_BODY
1275 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1277 inline lua_State* proxy_array_object::lua_state() const
1279 return m_obj->lua_state();
1282 inline proxy_array_object::operator luabind::object()
1284 lua_State* L = m_obj->lua_state();
1285 pushvalue();
1286 detail::lua_reference ref;
1287 ref.set(L);
1288 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1292 // *************************************
1293 // PROXY RAW OBJECT
1295 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1296 template<class T>
1297 inline object proxy_raw_object::raw_at(const T& key)
1298 LUABIND_PROXY_RAW_AT_BODY
1300 template<class T>
1301 inline object proxy_raw_object::at(const T& key)
1302 LUABIND_PROXY_AT_BODY
1303 #endif
1305 #undef LUABIND_PROXY_RAW_AT_BODY
1306 #undef LUABIND_PROXY_AT_BODY
1308 inline lua_State* proxy_raw_object::lua_state() const
1310 return m_obj->lua_state();
1313 inline proxy_raw_object::operator luabind::object()
1315 lua_State* L = lua_state();
1316 pushvalue();
1317 detail::lua_reference ref;
1318 ref.set(L);
1319 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1323 // *************************************
1324 // PROXY CALLER
1327 template<class Tuple>
1328 proxy_caller<Tuple>::~proxy_caller()
1330 if (m_called) return;
1332 m_called = true;
1333 lua_State* L = m_obj->lua_state();
1334 m_obj->pushvalue();
1336 push_args_from_tuple<1>::apply(L, m_args);
1337 if (pcall(L, boost::tuples::length<Tuple>::value, 0))
1339 #ifndef LUABIND_NO_EXCEPTIONS
1340 throw luabind::error(L);
1341 #else
1342 error_callback_fun e = get_error_callback();
1343 if (e) e(L);
1345 assert(0 && "the lua function threw an error and exceptions are disabled."
1346 "if you want to handle this error use luabind::set_error_callback()");
1347 std::terminate();
1348 #endif
1352 template<class Tuple>
1353 proxy_caller<Tuple>::operator luabind::object()
1355 m_called = true;
1356 lua_State* L = m_obj->lua_state();
1357 m_obj->pushvalue();
1359 push_args_from_tuple<1>::apply(L, m_args);
1360 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1362 #ifndef LUABIND_NO_EXCEPTIONS
1363 throw luabind::error(L);
1364 #else
1365 error_callback_fun e = get_error_callback();
1366 if (e) e(L);
1368 assert(0 && "the lua function threw an error and exceptions are disabled."
1369 "if you want to handle this error use luabind::set_error_callback()");
1370 std::terminate();
1371 #endif
1373 detail::lua_reference ref;
1374 ref.set(L);
1375 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1380 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1382 return detail::tuple_object_ref(
1383 const_cast<object*>(this), const_cast<object*>(&rhs));
1386 typedef detail::tuple_object function_;
1388 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1389 MACRO(object, object) \
1390 MACRO(object, detail::proxy_object) \
1391 MACRO(object, detail::proxy_array_object) \
1392 MACRO(object, detail::proxy_raw_object) \
1393 MACRO(detail::proxy_object, object) \
1394 MACRO(detail::proxy_object, detail::proxy_object) \
1395 MACRO(detail::proxy_object, detail::proxy_array_object) \
1396 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1397 MACRO(detail::proxy_array_object, object) \
1398 MACRO(detail::proxy_array_object, detail::proxy_object) \
1399 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1400 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1401 MACRO(detail::proxy_raw_object, object) \
1402 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1403 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1404 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1407 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1408 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1409 #undef LUABIND_EQUALITY_OPERATOR
1411 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1412 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1413 #undef LUABIND_LESSTHAN_OPERATOR
1415 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1416 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1417 #undef LUABIND_LESSOREQUAL_OPERATOR
1419 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1420 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1422 return !(rhs == lhs); \
1425 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1427 #undef LUABIND_INEQUALITY_OPERATOR
1429 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1430 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1432 return !(rhs < lhs); \
1435 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1437 #undef LUABIND_GREATEROREQUAL_OPERATOR
1439 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1440 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1442 return !(lhs <= rhs); \
1445 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1446 #undef LUABIND_GREATERTHAN_OPERATOR
1448 #undef LUABIND_DECLARE_OPERATOR
1452 namespace std
1455 #define LUABIND_DEFINE_SWAP(t1,t2)\
1456 inline void swap(t1 lhs, t2 rhs)\
1458 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1459 rhs.pushvalue();\
1460 lhs.pushvalue();\
1461 rhs.set();\
1462 lhs.set();\
1465 inline void swap(luabind::object& lhs, luabind::object& rhs)
1467 lhs.swap(rhs);
1470 // object against all other
1471 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1472 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1473 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1474 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1475 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1476 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1478 // proxy_object against all other
1479 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1480 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1481 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1482 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1483 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1485 // proxy_raw_object against all other
1486 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1487 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1488 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1490 // proxy_array_object against all other
1491 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1493 #undef LUABIND_DEFINE_SWAP
1495 } // std
1497 #endif // LUABIND_OBJECT_HPP_INCLUDED
1499 #elif BOOST_PP_ITERATION_FLAGS() == 1
1501 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1502 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1504 #if BOOST_PP_ITERATION() > 0
1505 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1506 #endif
1507 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1508 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1510 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1511 #if BOOST_PP_ITERATION() == 0
1512 tuple_t args;
1513 #else
1514 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1515 #endif
1516 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1519 #undef LUABIND_OPERATOR_PARAMS
1520 #undef LUABIND_TUPLE_PARAMS
1522 #endif