class_info added
[luabind.git] / luabind / object.hpp
bloba0d77172005ae637a9e4b01d7d276b104b639cbf
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 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, int key)
281 : m_obj(o)
282 , m_key_ref(key)
286 luabind::object* m_obj;
287 int m_key_ref;
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, int key)
380 : m_obj(o)
381 , m_key_ref(key)
385 luabind::object* m_obj;
386 int m_key_ref;
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::getref(L, m_key_ref);
420 detail::convert_to_lua_p(L, val, p);
421 lua_settable(L, -3);
422 // pop table
423 lua_pop(L, 1);
424 return *this;
427 proxy_array_object& operator=(const object& p);
428 proxy_array_object& operator=(const proxy_object& p);
429 proxy_array_object& operator=(const proxy_raw_object& p);
430 proxy_array_object& operator=(const proxy_array_object& p);
431 void swap(const proxy_array_object& rhs);
433 operator luabind::object();
435 int type() const
437 pushvalue();
438 detail::stack_pop p(lua_state(), 1);
439 return lua_type(lua_state(), -1);
442 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
444 pushvalue(); \
445 detail::convert_to_lua(m_state, key); \
446 lua_rawget(m_state, -2); \
447 int ref = detail::ref(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 int ref = detail::ref(m_state); \
458 lua_pop(m_state, 1); \
459 return object(m_state, ref, true); \
462 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
463 template<class T>
464 inline object at(const T& key)
465 LUABIND_PROXY_ARRAY_AT_BODY
466 #else
467 template<class T>
468 inline object at(const T& key);
469 #endif
472 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
473 template<class T>
474 inline object raw_at(const T& key)
475 LUABIND_PROXY_ARRAY_RAW_AT_BODY
476 #else
477 template<class T>
478 inline object raw_at(const T& key);
479 #endif
481 template<class T>
482 inline detail::proxy_object operator[](const T& key) const
484 detail::convert_to_lua(m_state, key);
485 int ref = detail::ref(m_state);
486 return detail::proxy_object(const_cast<object*>(this), ref);
489 inline bool is_valid() const { return true; }
490 lua_State* lua_state() const;
491 void pushvalue() const;
492 void set() const;
494 // this is a safe substitute for an implicit converter to bool
495 typedef void (proxy_array_object::*member_ptr)() const;
496 operator member_ptr() const
498 if (is_valid()) return &proxy_array_object::dummy;
499 return 0;
502 private:
504 void dummy() const {}
506 proxy_array_object(luabind::object* o, int key)
507 : m_obj(o)
508 , m_key(key)
511 luabind::object* m_obj;
512 int m_key;
515 template<class T>
516 struct primitive_converter;
518 } // detail
520 class LUABIND_API object
523 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
525 template<class T>
526 friend T object_cast(const object& obj);
527 template<class T>
528 friend struct detail::primitive_converter;
530 #endif
532 friend object get_globals(lua_State*);
533 friend object get_registry(lua_State*);
534 friend object newtable(lua_State*);
535 friend class detail::proxy_object;
536 friend class detail::proxy_array_object;
537 friend class detail::proxy_raw_object;
539 public:
541 class array_iterator
543 friend class object;
544 public:
546 typedef std::forward_iterator_tag iterator_category;
547 typedef luabind::object value_type;
548 typedef value_type& reference;
549 typedef value_type* pointer;
550 typedef void difference_type;
552 array_iterator()
553 : m_obj(0)
554 , m_key(LUA_NOREF)
558 array_iterator(const array_iterator& iter)
559 : m_obj(iter.m_obj)
560 , m_key(iter.m_key)
564 ~array_iterator() {}
566 array_iterator& operator=(const array_iterator& rhs)
568 //std::cout << "===\n";
569 m_obj = rhs.m_obj;
570 m_key = rhs.m_key;
571 return *this;
574 detail::proxy_array_object operator*()
576 return m_obj->make_array_proxy(m_key);
579 inline array_iterator& operator++()
581 m_key++;
583 // invalidate the iterator if we hit a nil element
584 lua_State* L = m_obj->lua_state();
585 m_obj->pushvalue();
586 lua_rawgeti(L, -1, m_key);
587 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
588 lua_pop(L, 1);
590 return *this;
593 inline array_iterator operator++(int)
595 int old_key = m_key;
596 m_key++;
598 // invalidate the iterator if we hit a nil element
599 lua_State* L = m_obj->lua_state();
600 m_obj->pushvalue();
601 lua_rawgeti(L, -1, m_key);
602 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
603 lua_pop(L, 1);
605 return array_iterator(m_obj, old_key);
608 bool operator!=(const array_iterator& rhs) const
610 return m_obj != rhs.m_obj || m_key != rhs.m_key;
613 private:
615 array_iterator(object* obj, int key)
616 : m_obj(obj)
617 , m_key(key)
621 object* m_obj;
622 int m_key;
630 class iterator
632 friend class object;
633 public:
635 typedef std::forward_iterator_tag iterator_category;
636 typedef luabind::object value_type;
637 typedef value_type& reference;
638 typedef value_type* pointer;
639 typedef void difference_type;
641 iterator()
642 : m_obj(0)
643 , m_key(LUA_NOREF)
647 iterator(const iterator& iter)
648 : m_obj(iter.m_obj)
649 , m_key(LUA_NOREF)
651 if (m_obj)
653 lua_State* L = m_obj->lua_state();
654 detail::getref(L, iter.m_key);
655 m_key = detail::ref(L);
659 ~iterator()
661 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
664 iterator& operator=(const iterator& rhs)
666 //std::cout << "===\n";
667 m_obj = rhs.m_obj;
668 if (m_obj)
670 lua_State* L = m_obj->lua_state();
671 detail::getref(L, rhs.m_key);
672 m_key = detail::ref(L);
674 else
676 m_key = LUA_NOREF;
678 return *this;
681 detail::proxy_object operator*()
683 return m_obj->make_proxy(m_key);
686 iterator& operator++()
688 lua_State* L = m_obj->lua_state();
689 m_obj->pushvalue();
690 detail::getref(L, m_key);
692 if (lua_next(L, -2) != 0)
694 lua_pop(L, 1);
695 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
696 lua_pop(L, 1);
698 else
700 lua_pop(L, 1);
701 detail::unref(L, m_key);
702 m_obj = 0;
703 m_key = LUA_NOREF;
706 return *this;
709 bool operator!=(const iterator& rhs) const
711 return m_obj != rhs.m_obj || m_key != rhs.m_key;
714 object key() const;
716 private:
718 iterator(object* obj, int key)
719 : m_obj(obj)
720 , m_key(key)
724 object* m_obj;
725 int m_key;
731 class raw_iterator
733 friend class object;
734 public:
736 typedef std::forward_iterator_tag iterator_category;
737 typedef luabind::object value_type;
738 typedef value_type& reference;
739 typedef value_type* pointer;
740 typedef void difference_type;
742 raw_iterator()
743 : m_obj(0)
744 , m_key(LUA_NOREF)
748 raw_iterator(const raw_iterator& iter)
749 : m_obj(iter.m_obj)
750 , m_key(LUA_NOREF)
752 if (m_obj)
754 lua_State* L = m_obj->lua_state();
755 detail::getref(L, iter.m_key);
756 m_key = detail::ref(L);
760 ~raw_iterator()
762 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
765 raw_iterator& operator=(const raw_iterator& rhs)
767 //std::cout << "===\n";
768 m_obj = rhs.m_obj;
769 if (m_obj)
771 lua_State* L = m_obj->lua_state();
772 detail::getref(L, rhs.m_key);
773 m_key = detail::ref(L);
775 else
777 m_key = LUA_NOREF;
779 return *this;
782 detail::proxy_raw_object operator*()
784 return m_obj->make_raw_proxy(m_key);
787 raw_iterator& operator++()
789 lua_State* L = m_obj->lua_state();
790 m_obj->pushvalue();
791 detail::getref(L, m_key);
793 if (lua_next(L, -2) != 0)
795 lua_pop(L, 1);
796 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
797 lua_pop(L, 1);
799 else
801 lua_pop(L, 1);
802 detail::unref(L, m_key);
803 m_obj = 0;
804 m_key = LUA_NOREF;
807 return *this;
810 object key() const;
812 bool operator!=(const raw_iterator& rhs) const
814 return m_obj != rhs.m_obj || m_key != rhs.m_key;
817 private:
819 raw_iterator(object* obj, int key)
820 : m_obj(obj)
821 , m_key(key)
825 object* m_obj;
826 int m_key;
834 object()
835 : m_state(0)
836 , m_ref(LUA_NOREF)
840 explicit object(lua_State* L)
841 : m_state(L)
842 , m_ref(LUA_NOREF)
846 template<class T>
847 object(lua_State* L, const T& val)
848 : m_state(L)
849 , m_ref(LUA_NOREF)
851 *this = val;
854 object(const object& o)
855 : m_state(o.m_state)
856 , m_ref(LUA_NOREF)
858 lua_getref(m_state, o.m_ref);
859 m_ref = detail::ref(m_state);
862 inline ~object()
864 // If you crash in the detail::unref() call you have probably
865 // closed the lua_State before destructing all object instances.
866 if (m_ref != LUA_NOREF) detail::unref(m_state, m_ref);
869 inline bool is_valid() const { return m_ref != LUA_NOREF; }
871 // this is a safe substitute for an implicit converter to bool
872 typedef void (object::*member_ptr)() const;
873 operator member_ptr() const
875 if (is_valid()) return &object::dummy;
876 return 0;
879 int type() const
881 pushvalue();
882 detail::stack_pop p(lua_state(), 1);
883 return lua_type(lua_state(), -1);
886 inline iterator begin() const
888 lua_getref(m_state, m_ref);
889 lua_pushnil(m_state);
890 lua_next(m_state, -2);
891 lua_pop(m_state, 1);
892 iterator i(const_cast<object*>(this), detail::ref(m_state));
893 lua_pop(m_state, 1);
894 return i;
897 inline iterator end() const
899 return iterator(0, LUA_NOREF);
902 inline array_iterator abegin() const
904 return array_iterator(const_cast<object*>(this), 1);
907 inline array_iterator aend() const
909 return array_iterator(const_cast<object*>(this), LUA_NOREF);
912 raw_iterator raw_begin() const
914 lua_getref(m_state, m_ref);
915 lua_pushnil(m_state);
916 lua_next(m_state, -2);
917 lua_pop(m_state, 1);
918 raw_iterator i(const_cast<object*>(this), detail::ref(m_state));
919 lua_pop(m_state, 1);
920 return i;
923 raw_iterator raw_end() const
925 return raw_iterator(0, LUA_NOREF);
928 inline void set() const
930 // you are trying to access an invalid object
931 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
933 allocate_slot();
934 lua_rawseti(m_state, LUA_REGISTRYINDEX, m_ref);
936 inline lua_State* lua_state() const { return m_state; }
937 inline void pushvalue() const
939 // you are trying to dereference an invalid object
940 assert((m_ref != LUA_NOREF) && "you are trying to access an invalid (uninitialized) object");
941 assert((m_state != 0) && "internal error, please report");
943 lua_getref(m_state, m_ref);
946 void swap(object& rhs);
948 template<class T>
949 inline object raw_at(const T& key)
951 lua_State* L = lua_state();
952 pushvalue();
953 detail::convert_to_lua(L, key);
954 lua_rawget(L, -2);
955 int ref = detail::ref(L);
956 lua_pop(L, 1);
957 return object(L, ref, true);
960 template<class T>
961 inline object at(const T& key)
963 lua_State* L = lua_state();
964 pushvalue();
965 detail::convert_to_lua(L, key);
966 lua_gettable(L, -2);
967 int ref = detail::ref(L);
968 lua_pop(L, 1);
969 return object(L, ref, true);
972 template<class T>
973 inline detail::proxy_object operator[](const T& key) const
975 detail::convert_to_lua(m_state, key);
976 int ref = detail::ref(m_state);
977 return detail::proxy_object(const_cast<object*>(this), ref);
982 // *****************************
983 // OPERATOR =
985 template<class T>
986 object& operator=(const T& val) const
988 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
989 // you cannot assign a non-lua value to an uninitialized object
991 detail::convert_to_lua(m_state, val);
992 set();
993 return const_cast<luabind::object&>(*this);
996 object& operator=(const object& o) const;
997 object& operator=(const detail::proxy_object& o) const;
998 object& operator=(const detail::proxy_raw_object& o) const;
999 object& operator=(const detail::proxy_array_object& o) const;
1001 template<class T, class Policies>
1002 void assign(const T& val, const Policies& p) const
1004 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1005 // you cannot assign a non-lua value to an uninitialized object
1007 detail::convert_to_lua_p(m_state, val, p);
1008 set();
1012 // *****************************
1013 // OPERATOR()
1015 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1016 #include BOOST_PP_ITERATE()
1020 inline detail::proxy_object make_proxy(int key)
1022 return detail::proxy_object(this, key);
1025 inline detail::proxy_raw_object make_raw_proxy(int key)
1027 return detail::proxy_raw_object(this, key);
1030 inline detail::proxy_array_object make_array_proxy(int key)
1032 return detail::proxy_array_object(this, key);
1035 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1036 // it's an inner class), that's why this interface is public
1037 // private:
1039 object(lua_State* L, int ref, bool/*, reference*/)
1040 : m_state(L)
1041 , m_ref(ref)
1045 private:
1047 void dummy() const {}
1049 void allocate_slot() const
1051 if (m_ref == LUA_NOREF)
1053 lua_pushboolean(m_state, 0);
1054 m_ref = detail::ref(m_state);
1058 mutable lua_State* m_state;
1059 mutable int m_ref;
1063 // *************************************
1064 // OBJECT
1066 inline void object::swap(object& rhs)
1068 // you cannot swap objects from different lua states
1069 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1070 std::swap(m_ref, rhs.m_ref);
1073 inline object object::iterator::key() const
1075 lua_State* L = m_obj->lua_state();
1076 detail::getref(L, m_key);
1077 return object(L, detail::ref(L), true);
1080 inline object object::raw_iterator::key() const
1082 lua_State* L = m_obj->lua_state();
1083 detail::getref(L, m_key);
1084 return object(L, detail::ref(L), true);
1087 namespace detail
1090 // *************************************
1091 // PROXY CALLER
1093 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1094 template<class Tuple>
1095 template<class Policies>
1096 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1098 m_called = true;
1099 lua_State* L = m_obj->lua_state();
1100 m_obj->pushvalue();
1101 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1102 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1104 #ifndef LUABIND_NO_EXCEPTIONS
1105 throw error(L);
1106 #else
1107 error_callback_fun e = detail::error_callback::get().err;
1108 if (e) e(L);
1110 assert(0 && "the lua function threw an error and exceptions are disabled."
1111 "if you want to handle this error use luabind::set_error_callback()");
1112 std::terminate();
1113 #endif
1115 int ref = detail::ref(L);
1116 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1118 #endif
1119 // *************************************
1120 // PROXY OBJECT
1122 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1123 template<class T>
1124 inline object proxy_object::raw_at(const T& key)
1125 LUABIND_PROXY_RAW_AT_BODY
1127 template<class T>
1128 inline object proxy_object::at(const T& key)
1129 LUABIND_PROXY_AT_BODY
1130 #endif
1132 inline lua_State* proxy_object::lua_state() const
1134 return m_obj->lua_state();
1137 inline proxy_object::operator luabind::object()
1139 lua_State* L = m_obj->lua_state();
1140 pushvalue();
1141 int ref = detail::ref(L);
1142 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1146 // *************************************
1147 // PROXY ARRAY OBJECT
1149 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1150 template<class T>
1151 inline object proxy_array_object::raw_at(const T& key)
1152 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1154 template<class T>
1155 inline object proxy_array_object::at(const T& key)
1156 LUABIND_PROXY_ARRAY_AT_BODY
1157 #endif
1159 #undef LUABIND_PROXY_ARRAY_AT_BODY
1160 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1162 inline lua_State* proxy_array_object::lua_state() const
1164 return m_obj->lua_state();
1167 inline proxy_array_object::operator luabind::object()
1169 lua_State* L = m_obj->lua_state();
1170 pushvalue();
1171 int ref = detail::ref(L);
1172 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1176 // *************************************
1177 // PROXY RAW OBJECT
1179 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1180 template<class T>
1181 inline object proxy_raw_object::raw_at(const T& key)
1182 LUABIND_PROXY_RAW_AT_BODY
1184 template<class T>
1185 inline object proxy_raw_object::at(const T& key)
1186 LUABIND_PROXY_AT_BODY
1187 #endif
1189 #undef LUABIND_PROXY_RAW_AT_BODY
1190 #undef LUABIND_PROXY_AT_BODY
1192 inline lua_State* proxy_raw_object::lua_state() const
1194 return m_obj->lua_state();
1197 inline proxy_raw_object::operator luabind::object()
1199 lua_State* L = lua_state();
1200 pushvalue();
1201 int ref = detail::ref(L);
1202 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1206 // *************************************
1207 // PROXY CALLER
1210 template<class Tuple>
1211 proxy_caller<Tuple>::~proxy_caller()
1213 if (m_called) return;
1215 m_called = true;
1216 lua_State* L = m_obj->lua_state();
1217 m_obj->pushvalue();
1219 push_args_from_tuple<1>::apply(L, m_args);
1220 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1222 #ifndef LUABIND_NO_EXCEPTIONS
1223 throw luabind::error(L);
1224 #else
1225 error_callback_fun e = detail::error_callback::get().err;
1226 if (e) e(L);
1228 assert(0 && "the lua function threw an error and exceptions are disabled."
1229 "if you want to handle this error use luabind::set_error_callback()");
1230 std::terminate();
1231 #endif
1235 template<class Tuple>
1236 proxy_caller<Tuple>::operator luabind::object()
1238 m_called = true;
1239 lua_State* L = m_obj->lua_state();
1240 m_obj->pushvalue();
1242 push_args_from_tuple<1>::apply(L, m_args);
1243 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1245 #ifndef LUABIND_NO_EXCEPTIONS
1246 throw luabind::error(L);
1247 #else
1248 error_callback_fun e = detail::error_callback::get().err;
1249 if (e) e(L);
1251 assert(0 && "the lua function threw an error and exceptions are disabled."
1252 "if you want to handle this error use luabind::set_error_callback()");
1253 std::terminate();
1254 #endif
1256 int ref = detail::ref(L);
1257 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1262 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1263 MACRO(object, object) \
1264 MACRO(object, detail::proxy_object) \
1265 MACRO(object, detail::proxy_array_object) \
1266 MACRO(object, detail::proxy_raw_object) \
1267 MACRO(detail::proxy_object, object) \
1268 MACRO(detail::proxy_object, detail::proxy_object) \
1269 MACRO(detail::proxy_object, detail::proxy_array_object) \
1270 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1271 MACRO(detail::proxy_array_object, object) \
1272 MACRO(detail::proxy_array_object, detail::proxy_object) \
1273 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1274 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1275 MACRO(detail::proxy_raw_object, object) \
1276 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1277 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1278 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1281 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1282 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1283 #undef LUABIND_EQUALITY_OPERATOR
1285 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1286 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1287 #undef LUABIND_LESSTHAN_OPERATOR
1289 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1290 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1291 #undef LUABIND_LESSOREQUAL_OPERATOR
1293 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1294 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1296 return !(rhs == lhs); \
1299 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1301 #undef LUABIND_INEQUALITY_OPERATOR
1303 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1304 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1306 return !(rhs < lhs); \
1309 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1311 #undef LUABIND_GREATEROREQUAL_OPERATOR
1313 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1314 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1316 return !(lhs <= rhs); \
1319 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1320 #undef LUABIND_GREATERTHAN_OPERATOR
1322 #undef LUABIND_DECLARE_OPERATOR
1326 namespace std
1329 #define LUABIND_DEFINE_SWAP(t1,t2)\
1330 inline void swap(t1 lhs, t2 rhs)\
1332 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1333 rhs.pushvalue();\
1334 lhs.pushvalue();\
1335 rhs.set();\
1336 lhs.set();\
1339 inline void swap(luabind::object& lhs, luabind::object& rhs)
1341 lhs.swap(rhs);
1344 // object against all other
1345 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1346 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1347 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1348 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1349 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1350 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1352 // proxy_object against all other
1353 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1354 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1355 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1356 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1357 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1359 // proxy_raw_object against all other
1360 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1361 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1362 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1364 // proxy_array_object against all other
1365 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1367 #undef LUABIND_DEFINE_SWAP
1369 } // std
1371 #endif // LUABIND_OBJECT_HPP_INCLUDED
1373 #elif BOOST_PP_ITERATION_FLAGS() == 1
1375 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1376 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1378 #if BOOST_PP_ITERATION() > 0
1379 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1380 #endif
1381 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1382 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1384 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1385 #if BOOST_PP_ITERATION() == 0
1386 tuple_t args;
1387 #else
1388 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1389 #endif
1390 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1393 #undef LUABIND_OPERATOR_PARAMS
1394 #undef LUABIND_TUPLE_PARAMS
1396 #endif