bug fixes for gcc
[luabind.git] / luabind / object.hpp
blobfc0d98d62e3b90911d96e5d3339d2c87296eeec9
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 detail::getref(L, m_key_ref);
186 detail::convert_to_lua(L, val);
187 lua_settable(L, -3);
188 // pop table
189 lua_pop(L, 1);
190 return *this;
193 proxy_object& operator=(const object& p);
194 proxy_object& operator=(const proxy_object& p);
195 proxy_object& operator=(const proxy_raw_object& p);
196 proxy_object& operator=(const proxy_array_object& p);
198 void swap(const proxy_object& rhs);
200 operator luabind::object();
202 int type() const
204 pushvalue();
205 detail::stack_pop p(lua_state(), 1);
206 return lua_type(lua_state(), -1);
209 #define LUABIND_PROXY_RAW_AT_BODY \
211 lua_State* L = lua_state(); \
212 pushvalue(); \
213 detail::convert_to_lua(L, key); \
214 lua_rawget(L, -2); \
215 int ref = detail::ref(L); \
216 lua_pop(L, 1); \
217 return object(L, ref, true); \
220 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
221 template<class T>
222 inline object raw_at(const T& key)
223 LUABIND_PROXY_RAW_AT_BODY
224 #else
225 template<class T>
226 inline object raw_at(const T& key);
227 #endif
229 #define LUABIND_PROXY_AT_BODY \
231 lua_State* L = lua_state(); \
232 pushvalue(); \
233 detail::convert_to_lua(L, key); \
234 lua_gettable(L, -2); \
235 int ref = detail::ref(L); \
236 lua_pop(L, 1); \
237 return object(L, ref, true); \
240 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
241 template<class T>
242 inline object at(const T& key)
243 LUABIND_PROXY_AT_BODY
244 #else
245 template<class T>
246 inline object at(const T& key);
247 #endif
249 inline bool is_valid() const { return true; }
250 lua_State* lua_state() const;
251 void pushvalue() const;
252 void set() const;
254 // this is a safe substitute for an implicit converter to bool
255 typedef void (proxy_object::*member_ptr)() const;
256 operator member_ptr() const
258 if (is_valid()) return &proxy_object::dummy;
259 return 0;
262 private:
264 void dummy() const {}
266 proxy_object(luabind::object* o, int key)
267 : m_obj(o)
268 , m_key_ref(key)
272 luabind::object* m_obj;
273 int m_key_ref;
278 class LUABIND_API proxy_raw_object
280 friend class luabind::object;
281 friend class luabind::detail::proxy_array_object;
282 friend class luabind::detail::proxy_object;
283 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
284 public:
286 template<class T>
287 proxy_raw_object& operator=(const T& val)
289 //std::cout << "proxy assigment\n";
290 lua_State* L = m_obj->m_state;
291 m_obj->pushvalue();
292 detail::getref(L, m_key_ref);
293 detail::convert_to_lua(L, val);
294 lua_rawset(L, -3);
295 // pop table
296 lua_pop(L, 1);
297 return *this;
300 proxy_raw_object& operator=(const object& p);
301 proxy_raw_object& operator=(const proxy_object& p);
302 proxy_raw_object& operator=(const proxy_raw_object& p);
303 proxy_raw_object& operator=(const proxy_array_object& p);
304 void swap(const proxy_raw_object& rhs);
306 operator luabind::object();
308 int type() const
310 pushvalue();
311 detail::stack_pop p(lua_state(), 1);
312 return lua_type(lua_state(), -1);
315 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
316 template<class T>
317 inline object raw_at(const T& key)
318 LUABIND_PROXY_RAW_AT_BODY
319 #else
320 template<class T>
321 inline object raw_at(const T& key);
322 #endif
324 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
325 template<class T>
326 inline object at(const T& key)
327 LUABIND_PROXY_AT_BODY
328 #else
329 template<class T>
330 inline object at(const T& key);
331 #endif
333 inline bool is_valid() const { return true; }
334 lua_State* lua_state() const;
335 void pushvalue() const;
336 void set() const;
338 // this is a safe substitute for an implicit converter to bool
339 typedef void (proxy_raw_object::*member_ptr)() const;
340 operator member_ptr() const
342 if (is_valid()) return &proxy_raw_object::dummy;
343 return 0;
347 private:
349 void dummy() const {}
351 proxy_raw_object(luabind::object* o, int key)
352 : m_obj(o)
353 , m_key_ref(key)
357 luabind::object* m_obj;
358 int m_key_ref;
363 class LUABIND_API proxy_array_object
365 friend class luabind::object;
366 friend class luabind::detail::proxy_object;
367 friend class luabind::detail::proxy_raw_object;
368 // template<class T> friend T object_cast(const proxy_array_object& obj);
369 public:
371 template<class T>
372 proxy_array_object& operator=(const T& val)
374 //std::cout << "array proxy assigment\n";
375 lua_State* L = m_obj->m_state;
376 m_obj->pushvalue();
377 detail::convert_to_lua(L, val);
378 lua_rawseti(L, -2, m_key);
380 // pops the table
381 lua_pop(L, 1);
382 return *this;
385 proxy_array_object& operator=(const object& p);
386 proxy_array_object& operator=(const proxy_object& p);
387 proxy_array_object& operator=(const proxy_raw_object& p);
388 proxy_array_object& operator=(const proxy_array_object& p);
389 void swap(const proxy_array_object& rhs);
391 operator luabind::object();
393 int type() const
395 pushvalue();
396 detail::stack_pop p(lua_state(), 1);
397 return lua_type(lua_state(), -1);
400 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
402 pushvalue(); \
403 detail::convert_to_lua(m_state, key); \
404 lua_rawget(m_state, -2); \
405 int ref = detail::ref(m_state); \
406 lua_pop(m_state, 1); \
407 return object(m_state, ref, true); \
410 #define LUABIND_PROXY_ARRAY_AT_BODY \
412 pushvalue(); \
413 detail::convert_to_lua(m_state, key); \
414 lua_gettable(m_state, -2); \
415 int ref = detail::ref(m_state); \
416 lua_pop(m_state, 1); \
417 return object(m_state, ref, true); \
420 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
421 template<class T>
422 inline object at(const T& key)
423 LUABIND_PROXY_ARRAY_AT_BODY
424 #else
425 template<class T>
426 inline object at(const T& key);
427 #endif
430 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
431 template<class T>
432 inline object raw_at(const T& key)
433 LUABIND_PROXY_ARRAY_RAW_AT_BODY
434 #else
435 template<class T>
436 inline object raw_at(const T& key);
437 #endif
439 template<class T>
440 inline detail::proxy_object operator[](const T& key) const
442 detail::convert_to_lua(m_state, key);
443 int ref = detail::ref(m_state);
444 return detail::proxy_object(const_cast<object*>(this), ref);
447 inline bool is_valid() const { return true; }
448 lua_State* lua_state() const;
449 void pushvalue() const;
450 void set() const;
452 // this is a safe substitute for an implicit converter to bool
453 typedef void (proxy_array_object::*member_ptr)() const;
454 operator member_ptr() const
456 if (is_valid()) return &proxy_array_object::dummy;
457 return 0;
460 private:
462 void dummy() const {}
464 proxy_array_object(luabind::object* o, int key)
465 : m_obj(o)
466 , m_key(key)
469 luabind::object* m_obj;
470 int m_key;
473 template<class T>
474 struct primitive_converter;
476 } // detail
481 class LUABIND_API object
484 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
486 template<class T>
487 friend T object_cast(const object& obj);
488 template<class T>
489 friend struct detail::primitive_converter;
491 #endif
493 friend object get_globals(lua_State*);
494 friend object get_registry(lua_State*);
495 friend object newtable(lua_State*);
496 friend class detail::proxy_object;
497 friend class detail::proxy_array_object;
498 friend class detail::proxy_raw_object;
500 public:
502 class array_iterator
504 friend class object;
505 public:
507 typedef std::forward_iterator_tag iterator_category;
508 typedef luabind::object value_type;
509 typedef value_type& reference;
510 typedef value_type* pointer;
511 typedef void difference_type;
513 array_iterator()
514 : m_obj(0)
515 , m_key(LUA_NOREF)
519 array_iterator(const array_iterator& iter)
520 : m_obj(iter.m_obj)
521 , m_key(iter.m_key)
525 ~array_iterator() {}
527 array_iterator& operator=(const array_iterator& rhs)
529 //std::cout << "===\n";
530 m_obj = rhs.m_obj;
531 m_key = rhs.m_key;
532 return *this;
535 detail::proxy_array_object operator*()
537 return m_obj->make_array_proxy(m_key);
540 inline array_iterator& operator++()
542 m_key++;
544 // invalidate the iterator if we hit a nil element
545 lua_State* L = m_obj->lua_state();
546 m_obj->pushvalue();
547 lua_rawgeti(L, -1, m_key);
548 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
549 lua_pop(L, 1);
551 return *this;
554 inline array_iterator operator++(int)
556 int old_key = m_key;
557 m_key++;
559 // invalidate the iterator if we hit a nil element
560 lua_State* L = m_obj->lua_state();
561 m_obj->pushvalue();
562 lua_rawgeti(L, -1, m_key);
563 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
564 lua_pop(L, 1);
566 return array_iterator(m_obj, old_key);
569 bool operator!=(const array_iterator& rhs) const
571 return m_obj != rhs.m_obj || m_key != rhs.m_key;
574 private:
576 array_iterator(object* obj, int key)
577 : m_obj(obj)
578 , m_key(key)
582 object* m_obj;
583 int m_key;
591 class iterator
593 friend class object;
594 public:
596 typedef std::forward_iterator_tag iterator_category;
597 typedef luabind::object value_type;
598 typedef value_type& reference;
599 typedef value_type* pointer;
600 typedef void difference_type;
602 iterator()
603 : m_obj(0)
604 , m_key(LUA_NOREF)
608 iterator(const iterator& iter)
609 : m_obj(iter.m_obj)
610 , m_key(LUA_NOREF)
612 if (m_obj)
614 lua_State* L = m_obj->lua_state();
615 detail::getref(L, iter.m_key);
616 m_key = detail::ref(L);
620 ~iterator()
622 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
625 iterator& operator=(const iterator& rhs)
627 //std::cout << "===\n";
628 m_obj = rhs.m_obj;
629 if (m_obj)
631 lua_State* L = m_obj->lua_state();
632 detail::getref(L, rhs.m_key);
633 m_key = detail::ref(L);
635 else
637 m_key = LUA_NOREF;
639 return *this;
642 detail::proxy_object operator*()
644 return m_obj->make_proxy(m_key);
647 iterator& operator++()
649 lua_State* L = m_obj->lua_state();
650 m_obj->pushvalue();
651 detail::getref(L, m_key);
653 if (lua_next(L, -2) != 0)
655 lua_pop(L, 1);
656 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
657 lua_pop(L, 1);
659 else
661 lua_pop(L, 1);
662 detail::unref(L, m_key);
663 m_obj = 0;
664 m_key = LUA_NOREF;
667 return *this;
670 bool operator!=(const iterator& rhs) const
672 return m_obj != rhs.m_obj || m_key != rhs.m_key;
675 object key() const;
677 private:
679 iterator(object* obj, int key)
680 : m_obj(obj)
681 , m_key(key)
685 object* m_obj;
686 int m_key;
692 class raw_iterator
694 friend class object;
695 public:
697 typedef std::forward_iterator_tag iterator_category;
698 typedef luabind::object value_type;
699 typedef value_type& reference;
700 typedef value_type* pointer;
701 typedef void difference_type;
703 raw_iterator()
704 : m_obj(0)
705 , m_key(LUA_NOREF)
709 raw_iterator(const raw_iterator& iter)
710 : m_obj(iter.m_obj)
711 , m_key(LUA_NOREF)
713 if (m_obj)
715 lua_State* L = m_obj->lua_state();
716 detail::getref(L, iter.m_key);
717 m_key = detail::ref(L);
721 ~raw_iterator()
723 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
726 raw_iterator& operator=(const raw_iterator& rhs)
728 //std::cout << "===\n";
729 m_obj = rhs.m_obj;
730 if (m_obj)
732 lua_State* L = m_obj->lua_state();
733 detail::getref(L, rhs.m_key);
734 m_key = detail::ref(L);
736 else
738 m_key = LUA_NOREF;
740 return *this;
743 detail::proxy_raw_object operator*()
745 return m_obj->make_raw_proxy(m_key);
748 raw_iterator& operator++()
750 lua_State* L = m_obj->lua_state();
751 m_obj->pushvalue();
752 detail::getref(L, m_key);
754 if (lua_next(L, -2) != 0)
756 lua_pop(L, 1);
757 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
758 lua_pop(L, 1);
760 else
762 lua_pop(L, 1);
763 detail::unref(L, m_key);
764 m_obj = 0;
765 m_key = LUA_NOREF;
768 return *this;
771 object key() const;
773 bool operator!=(const raw_iterator& rhs) const
775 return m_obj != rhs.m_obj || m_key != rhs.m_key;
778 private:
780 raw_iterator(object* obj, int key)
781 : m_obj(obj)
782 , m_key(key)
786 object* m_obj;
787 int m_key;
795 object()
796 : m_state(0)
797 , m_ref(LUA_NOREF)
801 object(lua_State* L)
802 : m_state(L)
803 , m_ref(LUA_NOREF)
807 template<class T>
808 object(lua_State* L, const T& val)
809 : m_state(L)
810 , m_ref(LUA_NOREF)
812 *this = val;
815 object(const object& o)
816 : m_state(o.m_state)
817 , m_ref(LUA_NOREF)
819 lua_getref(m_state, o.m_ref);
820 m_ref = detail::ref(m_state);
823 inline ~object()
825 // If you crash in the detail::unref() call you have probably
826 // closed the lua_State before destructing all object instances.
827 if (m_ref != LUA_NOREF) detail::unref(m_state, m_ref);
830 inline bool is_valid() const { return m_ref != LUA_NOREF; }
832 // this is a safe substitute for an implicit converter to bool
833 typedef void (object::*member_ptr)() const;
834 operator member_ptr() const
836 if (is_valid()) return &object::dummy;
837 return 0;
840 int type() const
842 pushvalue();
843 detail::stack_pop p(lua_state(), 1);
844 return lua_type(lua_state(), -1);
847 inline iterator begin() const
849 lua_getref(m_state, m_ref);
850 lua_pushnil(m_state);
851 lua_next(m_state, -2);
852 lua_pop(m_state, 1);
853 iterator i(const_cast<object*>(this), detail::ref(m_state));
854 lua_pop(m_state, 1);
855 return i;
858 inline iterator end() const
860 return iterator(0, LUA_NOREF);
863 inline array_iterator abegin() const
865 return array_iterator(const_cast<object*>(this), 1);
868 inline array_iterator aend() const
870 return array_iterator(const_cast<object*>(this), LUA_NOREF);
873 raw_iterator raw_begin() const
875 lua_getref(m_state, m_ref);
876 lua_pushnil(m_state);
877 lua_next(m_state, -2);
878 lua_pop(m_state, 1);
879 raw_iterator i(const_cast<object*>(this), detail::ref(m_state));
880 lua_pop(m_state, 1);
881 return i;
884 raw_iterator raw_end() const
886 return raw_iterator(0, LUA_NOREF);
889 inline void set() const
891 // you are trying to access an invalid object
892 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
894 allocate_slot();
895 lua_rawseti(m_state, LUA_REGISTRYINDEX, m_ref);
897 inline lua_State* lua_state() const { return m_state; }
898 inline void pushvalue() const
900 // you are trying to dereference an invalid object
901 assert((m_ref != LUA_NOREF) && "you are trying to access an invalid (uninitialized) object");
902 assert((m_state != 0) && "internal error, please report");
904 lua_getref(m_state, m_ref);
907 void swap(object& rhs);
909 template<class T>
910 inline object raw_at(const T& key)
912 lua_State* L = lua_state();
913 pushvalue();
914 detail::convert_to_lua(L, key);
915 lua_rawget(L, -2);
916 int ref = detail::ref(L);
917 lua_pop(L, 1);
918 return object(L, ref, true);
921 template<class T>
922 inline object at(const T& key)
924 lua_State* L = lua_state();
925 pushvalue();
926 detail::convert_to_lua(L, key);
927 lua_gettable(L, -2);
928 int ref = detail::ref(L);
929 lua_pop(L, 1);
930 return object(L, ref, true);
933 template<class T>
934 inline detail::proxy_object operator[](const T& key) const
936 detail::convert_to_lua(m_state, key);
937 int ref = detail::ref(m_state);
938 return detail::proxy_object(const_cast<object*>(this), ref);
943 // *****************************
944 // OPERATOR =
946 object& operator=(const object& o) const;
947 object& operator=(const detail::proxy_object& o) const;
948 object& operator=(const detail::proxy_raw_object& o) const;
949 object& operator=(const detail::proxy_array_object& o) const;
951 template<class T>
952 object& operator=(const T& val) const
954 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
955 // you cannot assign a non-lua value to an uninitialized object
957 detail::convert_to_lua(m_state, val);
958 set();
959 return const_cast<luabind::object&>(*this);
963 // *****************************
964 // OPERATOR()
966 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
967 #include BOOST_PP_ITERATE()
971 inline detail::proxy_object make_proxy(int key)
973 return detail::proxy_object(this, key);
976 inline detail::proxy_raw_object make_raw_proxy(int key)
978 return detail::proxy_raw_object(this, key);
981 inline detail::proxy_array_object make_array_proxy(int key)
983 return detail::proxy_array_object(this, key);
986 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
987 // it's an inner class), that's why this interface is public
988 // private:
990 object(lua_State* L, int ref, bool/*, reference*/)
991 : m_state(L)
992 , m_ref(ref)
996 private:
998 void dummy() const {}
1000 void allocate_slot() const
1002 if (m_ref == LUA_NOREF)
1004 lua_pushboolean(m_state, 0);
1005 m_ref = detail::ref(m_state);
1009 mutable lua_State* m_state;
1010 mutable int m_ref;
1014 // *************************************
1015 // OBJECT
1017 inline void object::swap(object& rhs)
1019 // you cannot swap objects from different lua states
1020 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1021 std::swap(m_ref, rhs.m_ref);
1024 inline object object::iterator::key() const
1026 lua_State* L = m_obj->lua_state();
1027 detail::getref(L, m_key);
1028 return object(L, detail::ref(L), true);
1031 inline object object::raw_iterator::key() const
1033 lua_State* L = m_obj->lua_state();
1034 detail::getref(L, m_key);
1035 return object(L, detail::ref(L), true);
1038 namespace detail
1041 // *************************************
1042 // PROXY CALLER
1044 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1045 template<class Tuple>
1046 template<class Policies>
1047 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1049 m_called = true;
1050 lua_State* L = m_obj->lua_state();
1051 m_obj->pushvalue();
1052 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1053 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1055 #ifndef LUABIND_NO_EXCEPTIONS
1056 throw error(L);
1057 #else
1058 error_callback_fun e = detail::error_callback::get().err;
1059 if (e) e(L);
1061 assert(0 && "the lua function threw an error and exceptions are disabled."
1062 "if you want to handle this error use luabind::set_error_callback()");
1063 std::terminate();
1064 #endif
1066 int ref = detail::ref(L);
1067 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1069 #endif
1070 // *************************************
1071 // PROXY OBJECT
1073 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1074 template<class T>
1075 inline object proxy_object::raw_at(const T& key)
1076 LUABIND_PROXY_RAW_AT_BODY
1078 template<class T>
1079 inline object proxy_object::at(const T& key)
1080 LUABIND_PROXY_AT_BODY
1081 #endif
1083 inline lua_State* proxy_object::lua_state() const
1085 return m_obj->lua_state();
1088 inline proxy_object::operator luabind::object()
1090 lua_State* L = m_obj->lua_state();
1091 pushvalue();
1092 int ref = detail::ref(L);
1093 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1097 // *************************************
1098 // PROXY ARRAY OBJECT
1100 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1101 template<class T>
1102 inline object proxy_array_object::raw_at(const T& key)
1103 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1105 template<class T>
1106 inline object proxy_array_object::at(const T& key)
1107 LUABIND_PROXY_ARRAY_AT_BODY
1108 #endif
1110 #undef LUABIND_PROXY_ARRAY_AT_BODY
1111 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1113 inline lua_State* proxy_array_object::lua_state() const
1115 return m_obj->lua_state();
1118 inline proxy_array_object::operator luabind::object()
1120 lua_State* L = m_obj->lua_state();
1121 pushvalue();
1122 int ref = detail::ref(L);
1123 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1127 // *************************************
1128 // PROXY RAW OBJECT
1130 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1131 template<class T>
1132 inline object proxy_raw_object::raw_at(const T& key)
1133 LUABIND_PROXY_RAW_AT_BODY
1135 template<class T>
1136 inline object proxy_raw_object::at(const T& key)
1137 LUABIND_PROXY_AT_BODY
1138 #endif
1140 #undef LUABIND_PROXY_RAW_AT_BODY
1141 #undef LUABIND_PROXY_AT_BODY
1143 inline lua_State* proxy_raw_object::lua_state() const
1145 return m_obj->lua_state();
1148 inline proxy_raw_object::operator luabind::object()
1150 lua_State* L = lua_state();
1151 pushvalue();
1152 int ref = detail::ref(L);
1153 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1157 // *************************************
1158 // PROXY CALLER
1161 template<class Tuple>
1162 proxy_caller<Tuple>::~proxy_caller()
1164 if (m_called) return;
1166 m_called = true;
1167 lua_State* L = m_obj->lua_state();
1168 m_obj->pushvalue();
1170 push_args_from_tuple<1>::apply(L, m_args);
1171 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1173 #ifndef LUABIND_NO_EXCEPTIONS
1174 throw luabind::error(L);
1175 #else
1176 error_callback_fun e = detail::error_callback::get().err;
1177 if (e) e(L);
1179 assert(0 && "the lua function threw an error and exceptions are disabled."
1180 "if you want to handle this error use luabind::set_error_callback()");
1181 std::terminate();
1182 #endif
1186 template<class Tuple>
1187 proxy_caller<Tuple>::operator luabind::object()
1189 m_called = true;
1190 lua_State* L = m_obj->lua_state();
1191 m_obj->pushvalue();
1193 push_args_from_tuple<1>::apply(L, m_args);
1194 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1196 #ifndef LUABIND_NO_EXCEPTIONS
1197 throw luabind::error(L);
1198 #else
1199 error_callback_fun e = detail::error_callback::get().err;
1200 if (e) e(L);
1202 assert(0 && "the lua function threw an error and exceptions are disabled."
1203 "if you want to handle this error use luabind::set_error_callback()");
1204 std::terminate();
1205 #endif
1207 int ref = detail::ref(L);
1208 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1213 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1214 MACRO(object, object) \
1215 MACRO(object, detail::proxy_object) \
1216 MACRO(object, detail::proxy_array_object) \
1217 MACRO(object, detail::proxy_raw_object) \
1218 MACRO(detail::proxy_object, object) \
1219 MACRO(detail::proxy_object, detail::proxy_object) \
1220 MACRO(detail::proxy_object, detail::proxy_array_object) \
1221 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1222 MACRO(detail::proxy_array_object, object) \
1223 MACRO(detail::proxy_array_object, detail::proxy_object) \
1224 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1225 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1226 MACRO(detail::proxy_raw_object, object) \
1227 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1228 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1229 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1232 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1233 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1234 #undef LUABIND_EQUALITY_OPERATOR
1236 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1237 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1238 #undef LUABIND_LESSTHAN_OPERATOR
1240 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1241 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1242 #undef LUABIND_LESSOREQUAL_OPERATOR
1244 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1245 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1247 return !(rhs == lhs); \
1250 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1252 #undef LUABIND_INEQUALITY_OPERATOR
1254 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1255 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1257 return !(rhs < lhs); \
1260 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1262 #undef LUABIND_GREATEROREQUAL_OPERATOR
1264 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1265 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1267 return !(lhs <= rhs); \
1270 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1271 #undef LUABIND_GREATERTHAN_OPERATOR
1273 #undef LUABIND_DECLARE_OPERATOR
1277 namespace std
1280 #define LUABIND_DEFINE_SWAP(t1,t2)\
1281 inline void swap(t1 lhs, t2 rhs)\
1283 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1284 rhs.pushvalue();\
1285 lhs.pushvalue();\
1286 rhs.set();\
1287 lhs.set();\
1290 inline void swap(luabind::object& lhs, luabind::object& rhs)
1292 lhs.swap(rhs);
1295 // object against all other
1296 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1297 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1298 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1299 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1300 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1301 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1303 // proxy_object against all other
1304 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1305 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1306 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1307 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1308 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1310 // proxy_raw_object against all other
1311 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1312 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1313 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1315 // proxy_array_object against all other
1316 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1318 #undef LUABIND_DEFINE_SWAP
1320 } // std
1322 #endif // LUABIND_OBJECT_HPP_INCLUDED
1324 #elif BOOST_PP_ITERATION_FLAGS() == 1
1326 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1327 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1329 #if BOOST_PP_ITERATION() > 0
1330 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1331 #endif
1332 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1333 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1335 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1336 #if BOOST_PP_ITERATION() == 0
1337 tuple_t args;
1338 #else
1339 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1340 #endif
1341 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1344 #undef LUABIND_OPERATOR_PARAMS
1345 #undef LUABIND_TUPLE_PARAMS
1347 #endif