fixed leaking lua-references as reported by Tom Spilman.
[luabind.git] / luabind / object.hpp
blob0d1a2eb480c23a9a99872a6f3f7ad473e48666ce
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/config.hpp>
31 #include <luabind/detail/error.hpp>
33 #include <boost/preprocessor/repeat.hpp>
34 #include <boost/preprocessor/iteration/iterate.hpp>
35 #include <boost/preprocessor/repetition/enum.hpp>
36 #include <boost/preprocessor/repetition/enum_params.hpp>
37 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
38 #include <boost/tuple/tuple.hpp>
40 namespace luabind
42 class object;
44 namespace detail
46 class proxy_object;
47 class proxy_raw_object;
48 class proxy_array_object;
50 template<class T>
51 void convert_to_lua(lua_State*, const T&);
53 template<int Index, class T, class Policies>
54 void convert_to_lua_p(lua_State*, const T&, const Policies&);
56 template<int Index>
57 struct push_args_from_tuple
59 template<class H, class T, class Policies>
60 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
62 convert_to_lua_p<Index>(L, *x.get_head(), p);
63 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
66 template<class H, class T>
67 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
69 convert_to_lua(L, *x.get_head());
70 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
73 template<class Policies>
74 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
76 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
80 template<class Tuple>
81 class proxy_caller
83 friend class luabind::object;
84 public:
86 proxy_caller(luabind::object* o, const Tuple args)
87 : m_obj(o)
88 , m_args(args)
89 , m_called(false)
93 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
94 : m_obj(rhs.m_obj)
95 , m_args(rhs.m_args)
96 , m_called(rhs.m_called)
98 rhs.m_called = true;
101 ~proxy_caller();
102 operator luabind::object();
104 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
105 #define LUABIND_SEMICOLON
106 #else
107 #define LUABIND_SEMICOLON ;
108 #endif
110 template<class Policies>
111 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
112 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
114 m_called = true;
115 lua_State* L = m_obj->lua_state();
116 m_obj->pushvalue();
117 detail::push_args_from_tuple<1>::apply(L, m_args, p);
118 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
120 #ifndef LUABIND_NO_EXCEPTIONS
121 throw error(L);
122 #else
123 error_callback_fun e = detail::error_callback::get().err;
124 if (e) e(L);
126 assert(0 && "the lua function threw an error and exceptions are disabled."
127 "if you want to handle this error use luabind::set_error_callback()");
128 std::terminate();
129 #endif
131 int ref = detail::ref(L);
132 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
134 #endif
137 #undef LUABIND_SEMICOLON
138 private:
140 luabind::object* m_obj;
141 Tuple m_args;
142 mutable bool m_called;
148 struct stack_pop
150 stack_pop(lua_State* L, int n)
151 : m_state(L)
152 , m_n(n)
156 ~stack_pop()
158 lua_pop(m_state, m_n);
161 private:
163 lua_State* m_state;
164 int m_n;
171 class LUABIND_API proxy_object
173 friend class luabind::object;
174 friend class luabind::detail::proxy_array_object;
175 friend class luabind::detail::proxy_raw_object;
176 // template<class T> friend T object_cast(const proxy_object& obj);
177 public:
179 template<class T>
180 proxy_object& operator=(const T& val)
182 //std::cout << "proxy assigment\n";
183 lua_State* L = m_obj->m_state;
184 m_obj->pushvalue();
185 m_key.get(L);
186 detail::convert_to_lua(L, val);
187 lua_settable(L, -3);
188 // pop table
189 lua_pop(L, 1);
190 return *this;
193 template<class T, class Policies>
194 void assign(const T& val, const Policies& p)
196 //std::cout << "proxy assigment\n";
197 lua_State* L = m_obj->m_state;
198 m_obj->pushvalue();
199 detail::getref(L, m_key_ref);
200 detail::convert_to_lua_p(L, val, p);
201 lua_settable(L, -3);
202 // pop table
203 lua_pop(L, 1);
204 return *this;
207 proxy_object& operator=(const object& p);
208 proxy_object& operator=(const proxy_object& p);
209 proxy_object& operator=(const proxy_raw_object& p);
210 proxy_object& operator=(const proxy_array_object& p);
212 void swap(const proxy_object& rhs);
214 operator luabind::object();
216 int type() const
218 pushvalue();
219 detail::stack_pop p(lua_state(), 1);
220 return lua_type(lua_state(), -1);
223 #define LUABIND_PROXY_RAW_AT_BODY \
225 lua_State* L = lua_state(); \
226 pushvalue(); \
227 detail::convert_to_lua(L, key); \
228 lua_rawget(L, -2); \
229 int ref = detail::ref(L); \
230 lua_pop(L, 1); \
231 return object(L, ref, true); \
234 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
235 template<class T>
236 inline object raw_at(const T& key)
237 LUABIND_PROXY_RAW_AT_BODY
238 #else
239 template<class T>
240 inline object raw_at(const T& key);
241 #endif
243 #define LUABIND_PROXY_AT_BODY \
245 lua_State* L = lua_state(); \
246 pushvalue(); \
247 detail::convert_to_lua(L, key); \
248 lua_gettable(L, -2); \
249 int ref = detail::ref(L); \
250 lua_pop(L, 1); \
251 return object(L, ref, true); \
254 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
255 template<class T>
256 inline object at(const T& key)
257 LUABIND_PROXY_AT_BODY
258 #else
259 template<class T>
260 inline object at(const T& key);
261 #endif
263 inline bool is_valid() const { return true; }
264 lua_State* lua_state() const;
265 void pushvalue() const;
266 void set() const;
268 // this is a safe substitute for an implicit converter to bool
269 typedef void (proxy_object::*member_ptr)() const;
270 operator member_ptr() const
272 if (is_valid()) return &proxy_object::dummy;
273 return 0;
276 private:
278 void dummy() const {}
280 proxy_object(luabind::object* o, const lua_reference& key)
281 : m_obj(o)
282 , m_key(key)
286 luabind::object* m_obj;
287 detail::lua_reference m_key;
292 class LUABIND_API proxy_raw_object
294 friend class luabind::object;
295 friend class luabind::detail::proxy_array_object;
296 friend class luabind::detail::proxy_object;
297 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
298 public:
300 template<class T>
301 proxy_raw_object& operator=(const T& val)
303 //std::cout << "proxy assigment\n";
304 lua_State* L = m_obj->m_state;
305 m_obj->pushvalue();
306 detail::getref(L, m_key_ref);
307 detail::convert_to_lua(L, val);
308 lua_rawset(L, -3);
309 // pop table
310 lua_pop(L, 1);
311 return *this;
314 template<class T, class Policies>
315 void assign(const T& val, const Policies& p)
317 //std::cout << "proxy assigment\n";
318 lua_State* L = m_obj->m_state;
319 m_obj->pushvalue();
320 detail::getref(L, m_key_ref);
321 detail::convert_to_lua_p(L, val, p);
322 lua_settable(L, -3);
323 // pop table
324 lua_pop(L, 1);
325 return *this;
328 proxy_raw_object& operator=(const object& p);
329 proxy_raw_object& operator=(const proxy_object& p);
330 proxy_raw_object& operator=(const proxy_raw_object& p);
331 proxy_raw_object& operator=(const proxy_array_object& p);
332 void swap(const proxy_raw_object& rhs);
334 operator luabind::object();
336 int type() const
338 pushvalue();
339 detail::stack_pop p(lua_state(), 1);
340 return lua_type(lua_state(), -1);
343 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
344 template<class T>
345 inline object raw_at(const T& key)
346 LUABIND_PROXY_RAW_AT_BODY
347 #else
348 template<class T>
349 inline object raw_at(const T& key);
350 #endif
352 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
353 template<class T>
354 inline object at(const T& key)
355 LUABIND_PROXY_AT_BODY
356 #else
357 template<class T>
358 inline object at(const T& key);
359 #endif
361 inline bool is_valid() const { return true; }
362 lua_State* lua_state() const;
363 void pushvalue() const;
364 void set() const;
366 // this is a safe substitute for an implicit converter to bool
367 typedef void (proxy_raw_object::*member_ptr)() const;
368 operator member_ptr() const
370 if (is_valid()) return &proxy_raw_object::dummy;
371 return 0;
375 private:
377 void dummy() const {}
379 proxy_raw_object(luabind::object* o, const lua_reference& key)
380 : m_obj(o)
381 , m_key(key)
385 luabind::object* m_obj;
386 detail::lua_reference m_key;
391 class LUABIND_API proxy_array_object
393 friend class luabind::object;
394 friend class luabind::detail::proxy_object;
395 friend class luabind::detail::proxy_raw_object;
396 // template<class T> friend T object_cast(const proxy_array_object& obj);
397 public:
399 template<class T>
400 proxy_array_object& operator=(const T& val)
402 //std::cout << "array proxy assigment\n";
403 lua_State* L = m_obj->m_state;
404 m_obj->pushvalue();
405 detail::convert_to_lua(L, val);
406 lua_rawseti(L, -2, m_key);
408 // pops the table
409 lua_pop(L, 1);
410 return *this;
413 template<class T, class Policies>
414 void assign(const T& val, const Policies& p)
416 //std::cout << "proxy assigment\n";
417 lua_State* L = m_obj->m_state;
418 m_obj->pushvalue();
419 detail::convert_to_lua_p(L, val, p);
420 lua_rawseti(L, -2, m_key);
421 // pop table
422 lua_pop(L, 1);
423 return *this;
426 proxy_array_object& operator=(const object& p);
427 proxy_array_object& operator=(const proxy_object& p);
428 proxy_array_object& operator=(const proxy_raw_object& p);
429 proxy_array_object& operator=(const proxy_array_object& p);
430 void swap(const proxy_array_object& rhs);
432 operator luabind::object();
434 int type() const
436 pushvalue();
437 detail::stack_pop p(lua_state(), 1);
438 return lua_type(lua_state(), -1);
441 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
443 pushvalue();\
444 detail::convert_to_lua(m_state, key);\
445 lua_rawget(m_state, -2);\
446 lua_reference ref;\
447 ref.set(m_state);\
448 lua_pop(m_state, 1);\
449 return object(m_state, ref, true);\
452 #define LUABIND_PROXY_ARRAY_AT_BODY\
454 pushvalue();\
455 detail::convert_to_lua(m_state, key);\
456 lua_gettable(m_state, -2);\
457 lua_reference ref;\
458 ref.set(m_state);\
459 lua_pop(m_state, 1);\
460 return object(m_state, ref, true);\
463 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
464 template<class T>
465 inline object at(const T& key)
466 LUABIND_PROXY_ARRAY_AT_BODY
467 #else
468 template<class T>
469 inline object at(const T& key);
470 #endif
473 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
474 template<class T>
475 inline object raw_at(const T& key)
476 LUABIND_PROXY_ARRAY_RAW_AT_BODY
477 #else
478 template<class T>
479 inline object raw_at(const T& key);
480 #endif
482 template<class T>
483 inline detail::proxy_object operator[](const T& key) const
485 detail::convert_to_lua(m_state, key);
486 lua_reference ref;\
487 ref.set(m_state);\
488 return detail::proxy_object(const_cast<object*>(this), ref);
491 inline bool is_valid() const { return true; }
492 lua_State* lua_state() const;
493 void pushvalue() const;
494 void set() const;
496 // this is a safe substitute for an implicit converter to bool
497 typedef void (proxy_array_object::*member_ptr)() const;
498 operator member_ptr() const
500 if (is_valid()) return &proxy_array_object::dummy;
501 return 0;
504 private:
506 void dummy() const {}
508 proxy_array_object(luabind::object* o, int key)
509 : m_obj(o)
510 , m_key(key)
512 luabind::object* m_obj;
513 int m_key;
516 template<class T>
517 struct primitive_converter;
519 struct tuple_object_ref;
521 } // detail
523 class LUABIND_API object
526 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
528 template<class T>
529 friend T object_cast(const object& obj);
530 template<class T>
531 friend struct detail::primitive_converter;
533 #endif
535 friend object get_globals(lua_State*);
536 friend object get_registry(lua_State*);
537 friend object newtable(lua_State*);
538 friend class detail::proxy_object;
539 friend class detail::proxy_array_object;
540 friend class detail::proxy_raw_object;
542 public:
544 class array_iterator
546 friend class object;
547 public:
549 typedef std::forward_iterator_tag iterator_category;
550 typedef luabind::object value_type;
551 typedef value_type& reference;
552 typedef value_type* pointer;
553 typedef void difference_type;
555 array_iterator()
556 : m_obj(0)
557 , m_key(0)
561 array_iterator(const array_iterator& iter)
562 : m_obj(iter.m_obj)
563 , m_key(iter.m_key)
567 ~array_iterator() {}
569 array_iterator& operator=(const array_iterator& rhs)
571 m_obj = rhs.m_obj;
572 m_key = rhs.m_key;
573 return *this;
576 detail::proxy_array_object operator*()
578 return m_obj->make_array_proxy(m_key);
581 inline array_iterator& operator++()
583 m_key++;
585 // invalidate the iterator if we hit a nil element
586 lua_State* L = m_obj->lua_state();
587 m_obj->pushvalue();
588 lua_rawgeti(L, -1, m_key);
589 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
590 lua_pop(L, 1);
592 return *this;
595 inline array_iterator operator++(int)
597 int old_key = m_key;
598 m_key++;
600 // invalidate the iterator if we hit a nil element
601 lua_State* L = m_obj->lua_state();
602 m_obj->pushvalue();
603 lua_rawgeti(L, -1, m_key);
604 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
605 lua_pop(L, 1);
607 return array_iterator(m_obj, old_key);
610 bool operator!=(const array_iterator& rhs) const
612 return m_obj != rhs.m_obj || m_key != rhs.m_key;
615 private:
617 array_iterator(object* obj, int key)
618 : m_obj(obj)
619 , m_key(key)
623 object* m_obj;
624 int m_key;
632 class iterator
634 friend class object;
635 public:
637 typedef std::forward_iterator_tag iterator_category;
638 typedef luabind::object value_type;
639 typedef value_type& reference;
640 typedef value_type* pointer;
641 typedef void difference_type;
643 iterator()
644 : m_obj(0)
648 iterator(const iterator& iter)
649 : m_obj(iter.m_obj)
651 if (m_obj)
653 m_key = iter.m_key;
657 iterator& operator=(const iterator& rhs)
659 m_obj = rhs.m_obj;
660 if (m_obj)
662 m_key = rhs.m_key;
664 else
666 m_key.reset();
668 return *this;
671 detail::proxy_object operator*()
673 return m_obj->make_proxy(m_key);
676 iterator& operator++()
678 lua_State* L = m_obj->lua_state();
680 int n = lua_gettop(L);
682 m_obj->pushvalue();
683 m_key.get(L);
685 if (lua_next(L, -2) != 0)
687 lua_pop(L, 1);
688 m_key.replace(L);
689 lua_pop(L, 1);
691 else
693 lua_pop(L, 1);
694 m_obj = 0;
695 m_key.reset();
698 assert(n == lua_gettop(L));
699 return *this;
702 bool operator!=(const iterator& rhs) const
704 if (m_obj != rhs.m_obj) return true;
705 if (m_obj == 0) return false;
706 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
707 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
709 // TODO: fix this. add a real equality test of the keys
710 return true;
713 object key() const;
715 private:
717 iterator(luabind::object* obj, detail::lua_reference const& key)
718 : m_obj(obj)
719 , m_key(key)
723 object* m_obj;
724 detail::lua_reference m_key;
730 class raw_iterator
732 friend class object;
733 public:
735 typedef std::forward_iterator_tag iterator_category;
736 typedef luabind::object value_type;
737 typedef value_type& reference;
738 typedef value_type* pointer;
739 typedef void difference_type;
741 raw_iterator()
742 : m_obj(0)
746 raw_iterator(const raw_iterator& iter)
747 : m_obj(iter.m_obj)
748 , m_key()
750 if (m_obj)
752 m_key = iter.m_key;
756 raw_iterator& operator=(const raw_iterator& rhs)
758 //std::cout << "===\n";
759 m_obj = rhs.m_obj;
760 if (m_obj)
762 m_key = rhs.m_key;
764 else
766 m_key.reset();
768 return *this;
771 detail::proxy_raw_object operator*()
773 return m_obj->make_raw_proxy(m_key);
776 raw_iterator& operator++()
778 lua_State* L = m_obj->lua_state();
779 m_obj->pushvalue();
780 m_key.get(L);
782 if (lua_next(L, -2) != 0)
784 lua_pop(L, 1);
785 m_key.replace(L);
786 lua_pop(L, 1);
788 else
790 lua_pop(L, 1);
791 m_key.reset();
792 m_obj = 0;
795 return *this;
798 object key() const;
800 bool operator!=(const raw_iterator& rhs) const
802 if (m_obj != rhs.m_obj) return true;
803 if (m_obj == 0) return false;
804 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
805 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
807 // TODO: fix this. add a real equality test of the keys
808 return true;
811 private:
813 raw_iterator(object* obj, detail::lua_reference const& key)
814 : m_obj(obj)
815 , m_key(key)
818 object* m_obj;
819 detail::lua_reference m_key;
827 object()
828 : m_state(0)
832 explicit object(lua_State* L)
833 : m_state(L)
837 template<class T>
838 object(lua_State* L, const T& val)
839 : m_state(L)
841 *this = val;
844 object(const object& o)
845 : m_state(o.m_state)
847 o.m_ref.get(m_state);
848 m_ref.set(m_state);
851 inline ~object()
854 inline bool is_valid() const { return m_ref.is_valid(); }
856 // this is a safe substitute for an implicit converter to bool
857 typedef void (object::*member_ptr)() const;
858 operator member_ptr() const
860 if (is_valid()) return &object::dummy;
861 return 0;
864 int type() const
866 pushvalue();
867 detail::stack_pop p(lua_state(), 1);
868 return lua_type(lua_state(), -1);
871 inline iterator begin() const
873 m_ref.get(m_state);
874 lua_pushnil(m_state);
875 lua_next(m_state, -2);
876 lua_pop(m_state, 1);
877 detail::lua_reference r;
878 r.set(m_state);
879 iterator i(const_cast<object*>(this), r);
880 lua_pop(m_state, 1);
881 return i;
884 inline iterator end() const
886 return iterator(0, detail::lua_reference());
889 inline array_iterator abegin() const
891 return array_iterator(const_cast<object*>(this), 1);
894 inline array_iterator aend() const
896 return array_iterator(const_cast<object*>(this), -1);
899 raw_iterator raw_begin() const
901 m_ref.get(m_state);
902 lua_pushnil(m_state);
903 lua_next(m_state, -2);
904 lua_pop(m_state, 1);
905 detail::lua_reference r;
906 r.set(m_state);
907 raw_iterator i(const_cast<object*>(this), r);
908 lua_pop(m_state, 1);
909 return i;
912 raw_iterator raw_end() const
914 return raw_iterator(0, detail::lua_reference());
917 inline void set() const
919 // you are trying to access an invalid object
920 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
922 allocate_slot();
923 m_ref.replace(m_state);
925 inline lua_State* lua_state() const { return m_state; }
926 inline void pushvalue() const
928 // you are trying to dereference an invalid object
929 assert((!m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
930 assert((m_state != 0) && "internal error, please report");
932 m_ref.get(m_state);
935 void swap(object& rhs);
937 template<class T>
938 inline object raw_at(const T& key)
940 lua_State* L = lua_state();
941 pushvalue();
942 detail::convert_to_lua(L, key);
943 lua_rawget(L, -2);
944 detail::lua_reference ref;
945 ref.set(L);
946 lua_pop(L, 1);
947 return object(L, ref, true);
950 template<class T>
951 inline object at(const T& key)
953 lua_State* L = lua_state();
954 pushvalue();
955 detail::convert_to_lua(L, key);
956 lua_gettable(L, -2);
957 detail::lua_reference ref;
958 ref.set(L);
959 lua_pop(L, 1);
960 return object(L, ref, true);
963 template<class T>
964 inline detail::proxy_object operator[](const T& key) const
966 detail::convert_to_lua(m_state, key);
967 detail::lua_reference ref;
968 ref.set(m_state);
969 return detail::proxy_object(const_cast<object*>(this), ref);
974 // *****************************
975 // OPERATOR =
977 template<class T>
978 object& operator=(const T& val) const
980 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
981 // you cannot assign a non-lua value to an uninitialized object
983 detail::convert_to_lua(m_state, val);
984 set();
985 return const_cast<luabind::object&>(*this);
988 object& operator=(const object& o) const;
989 object& operator=(const detail::proxy_object& o) const;
990 object& operator=(const detail::proxy_raw_object& o) const;
991 object& operator=(const detail::proxy_array_object& o) const;
993 template<class T, class Policies>
994 void assign(const T& val, const Policies& p) const
996 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
997 // you cannot assign a non-lua value to an uninitialized object
999 detail::convert_to_lua_p(m_state, val, p);
1000 set();
1003 // const overload should return a tuple_object..?
1004 inline detail::tuple_object_ref operator,(const object& rhs) const;
1006 // *****************************
1007 // OPERATOR()
1009 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1010 #include BOOST_PP_ITERATE()
1014 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1016 return detail::proxy_object(this, key);
1019 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1021 return detail::proxy_raw_object(this, key);
1024 inline detail::proxy_array_object make_array_proxy(int key)
1026 return detail::proxy_array_object(this, key);
1029 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1030 // it's an inner class), that's why this interface is public
1031 // private:
1033 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1034 : m_state(L)
1035 , m_ref(ref)
1039 private:
1041 void dummy() const {}
1043 void allocate_slot() const
1045 if (!m_ref.is_valid())
1047 lua_pushboolean(m_state, 0);
1048 m_ref.set(m_state);
1052 mutable lua_State* m_state;
1053 mutable detail::lua_reference m_ref;
1057 // *************************************
1058 // OBJECT
1060 inline void object::swap(object& rhs)
1062 // you cannot swap objects from different lua states
1063 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1064 m_ref.swap(rhs.m_ref);
1067 inline object object::iterator::key() const
1069 lua_State* L = m_obj->lua_state();
1070 return object(L, m_key, true);
1073 inline object object::raw_iterator::key() const
1075 lua_State* L = m_obj->lua_state();
1076 return object(L, m_key, true);
1079 namespace detail
1081 // tuple object ----------------------------------------------
1083 struct tuple_object;
1085 struct tuple_object_ref
1087 tuple_object_ref(object* a, object* b)
1088 : n(2)
1089 { refs[0] = a; refs[1] = b; }
1091 tuple_object_ref& operator,(const object& x)
1092 { refs[n++] = const_cast<object*>(&x); return *this; }
1094 struct assign_into
1096 assign_into() {}
1098 template<class T>
1099 assign_into(tuple_object_ref& to, const T& val)
1100 : target(&to)
1101 , n(0)
1103 if (n >= target->n) return;
1104 *target->refs[n++] = val;
1107 template<class T>
1108 assign_into& operator,(const T& val)
1110 if (n >= target->n) return *this;
1111 *target->refs[n++] = val;
1112 return *this;
1115 tuple_object_ref* target;
1116 std::size_t n;
1119 template<class T>
1120 assign_into operator=(const T& val)
1121 { return assign_into(*this, val); }
1123 tuple_object_ref(const tuple_object_ref&);
1124 assign_into operator=(const tuple_object_ref& x)
1126 for (std::size_t i = 0; i < n && i < x.n; ++i)
1127 *refs[i] = *x.refs[i];
1128 return assign_into();
1131 inline assign_into operator=(const tuple_object&);
1133 std::size_t n;
1134 object* refs[10];
1137 struct tuple_object
1139 tuple_object(const object& x)
1140 : n(0)
1141 { objs[n++] = x; }
1143 tuple_object(const tuple_object_ref& x)
1145 for (std::size_t i = 0; i < x.n; ++i)
1146 objs[i] = *x.refs[i];
1149 std::size_t n;
1150 object objs[10];
1153 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1155 for (std::size_t i = 0; i < n && i < x.n; ++i)
1156 *refs[i] = x.objs[i];
1157 return assign_into();
1160 // *************************************
1161 // PROXY CALLER
1163 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1164 template<class Tuple>
1165 template<class Policies>
1166 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1168 m_called = true;
1169 lua_State* L = m_obj->lua_state();
1170 m_obj->pushvalue();
1171 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1172 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1174 #ifndef LUABIND_NO_EXCEPTIONS
1175 throw error(L);
1176 #else
1177 error_callback_fun e = detail::error_callback::get().err;
1178 if (e) e(L);
1180 assert(0 && "the lua function threw an error and exceptions are disabled."
1181 "if you want to handle this error use luabind::set_error_callback()");
1182 std::terminate();
1183 #endif
1185 detail::lua_reference ref;
1186 ref.set(L);
1187 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1189 #endif
1190 // *************************************
1191 // PROXY OBJECT
1193 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1194 template<class T>
1195 inline object proxy_object::raw_at(const T& key)
1196 LUABIND_PROXY_RAW_AT_BODY
1198 template<class T>
1199 inline object proxy_object::at(const T& key)
1200 LUABIND_PROXY_AT_BODY
1201 #endif
1203 inline lua_State* proxy_object::lua_state() const
1205 return m_obj->lua_state();
1208 inline proxy_object::operator luabind::object()
1210 lua_State* L = m_obj->lua_state();
1211 pushvalue();
1212 detail::lua_reference ref;
1213 ref.set(L);
1214 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1218 // *************************************
1219 // PROXY ARRAY OBJECT
1221 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1222 template<class T>
1223 inline object proxy_array_object::raw_at(const T& key)
1224 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1226 template<class T>
1227 inline object proxy_array_object::at(const T& key)
1228 LUABIND_PROXY_ARRAY_AT_BODY
1229 #endif
1231 #undef LUABIND_PROXY_ARRAY_AT_BODY
1232 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1234 inline lua_State* proxy_array_object::lua_state() const
1236 return m_obj->lua_state();
1239 inline proxy_array_object::operator luabind::object()
1241 lua_State* L = m_obj->lua_state();
1242 pushvalue();
1243 detail::lua_reference ref;
1244 ref.set(L);
1245 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1249 // *************************************
1250 // PROXY RAW OBJECT
1252 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1253 template<class T>
1254 inline object proxy_raw_object::raw_at(const T& key)
1255 LUABIND_PROXY_RAW_AT_BODY
1257 template<class T>
1258 inline object proxy_raw_object::at(const T& key)
1259 LUABIND_PROXY_AT_BODY
1260 #endif
1262 #undef LUABIND_PROXY_RAW_AT_BODY
1263 #undef LUABIND_PROXY_AT_BODY
1265 inline lua_State* proxy_raw_object::lua_state() const
1267 return m_obj->lua_state();
1270 inline proxy_raw_object::operator luabind::object()
1272 lua_State* L = lua_state();
1273 pushvalue();
1274 detail::lua_reference ref;
1275 ref.set(L);
1276 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1280 // *************************************
1281 // PROXY CALLER
1284 template<class Tuple>
1285 proxy_caller<Tuple>::~proxy_caller()
1287 if (m_called) return;
1289 m_called = true;
1290 lua_State* L = m_obj->lua_state();
1291 m_obj->pushvalue();
1293 push_args_from_tuple<1>::apply(L, m_args);
1294 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1296 #ifndef LUABIND_NO_EXCEPTIONS
1297 throw luabind::error(L);
1298 #else
1299 error_callback_fun e = detail::error_callback::get().err;
1300 if (e) e(L);
1302 assert(0 && "the lua function threw an error and exceptions are disabled."
1303 "if you want to handle this error use luabind::set_error_callback()");
1304 std::terminate();
1305 #endif
1309 template<class Tuple>
1310 proxy_caller<Tuple>::operator luabind::object()
1312 m_called = true;
1313 lua_State* L = m_obj->lua_state();
1314 m_obj->pushvalue();
1316 push_args_from_tuple<1>::apply(L, m_args);
1317 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1319 #ifndef LUABIND_NO_EXCEPTIONS
1320 throw luabind::error(L);
1321 #else
1322 error_callback_fun e = detail::error_callback::get().err;
1323 if (e) e(L);
1325 assert(0 && "the lua function threw an error and exceptions are disabled."
1326 "if you want to handle this error use luabind::set_error_callback()");
1327 std::terminate();
1328 #endif
1330 detail::lua_reference ref;
1331 ref.set(L);
1332 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1337 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1339 return detail::tuple_object_ref(
1340 const_cast<object*>(this), const_cast<object*>(&rhs));
1343 typedef detail::tuple_object function_;
1345 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1346 MACRO(object, object) \
1347 MACRO(object, detail::proxy_object) \
1348 MACRO(object, detail::proxy_array_object) \
1349 MACRO(object, detail::proxy_raw_object) \
1350 MACRO(detail::proxy_object, object) \
1351 MACRO(detail::proxy_object, detail::proxy_object) \
1352 MACRO(detail::proxy_object, detail::proxy_array_object) \
1353 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1354 MACRO(detail::proxy_array_object, object) \
1355 MACRO(detail::proxy_array_object, detail::proxy_object) \
1356 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1357 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1358 MACRO(detail::proxy_raw_object, object) \
1359 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1360 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1361 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1364 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1365 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1366 #undef LUABIND_EQUALITY_OPERATOR
1368 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1369 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1370 #undef LUABIND_LESSTHAN_OPERATOR
1372 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1373 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1374 #undef LUABIND_LESSOREQUAL_OPERATOR
1376 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1377 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1379 return !(rhs == lhs); \
1382 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1384 #undef LUABIND_INEQUALITY_OPERATOR
1386 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1387 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1389 return !(rhs < lhs); \
1392 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1394 #undef LUABIND_GREATEROREQUAL_OPERATOR
1396 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1397 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1399 return !(lhs <= rhs); \
1402 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1403 #undef LUABIND_GREATERTHAN_OPERATOR
1405 #undef LUABIND_DECLARE_OPERATOR
1409 namespace std
1412 #define LUABIND_DEFINE_SWAP(t1,t2)\
1413 inline void swap(t1 lhs, t2 rhs)\
1415 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1416 rhs.pushvalue();\
1417 lhs.pushvalue();\
1418 rhs.set();\
1419 lhs.set();\
1422 inline void swap(luabind::object& lhs, luabind::object& rhs)
1424 lhs.swap(rhs);
1427 // object against all other
1428 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1429 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1430 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1431 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1432 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1433 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1435 // proxy_object against all other
1436 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1437 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1438 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1439 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1440 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1442 // proxy_raw_object against all other
1443 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1444 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1445 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1447 // proxy_array_object against all other
1448 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1450 #undef LUABIND_DEFINE_SWAP
1452 } // std
1454 #endif // LUABIND_OBJECT_HPP_INCLUDED
1456 #elif BOOST_PP_ITERATION_FLAGS() == 1
1458 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1459 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1461 #if BOOST_PP_ITERATION() > 0
1462 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1463 #endif
1464 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1465 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1467 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1468 #if BOOST_PP_ITERATION() == 0
1469 tuple_t args;
1470 #else
1471 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1472 #endif
1473 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1476 #undef LUABIND_OPERATOR_PARAMS
1477 #undef LUABIND_TUPLE_PARAMS
1479 #endif