*** empty log message ***
[luabind.git] / luabind / object.hpp
blob6372754c65325bf13d2c706c758e22d19d905010
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #if !BOOST_PP_IS_ITERATING
25 #ifndef LUABIND_OBJECT_HPP_INCLUDED
26 #define LUABIND_OBJECT_HPP_INCLUDED
28 #include <iterator>
30 #include <luabind/prefix.hpp>
31 #include <luabind/config.hpp>
32 #include <luabind/error.hpp>
33 #include <luabind/detail/pcall.hpp>
35 #include <boost/preprocessor/repeat.hpp>
36 #include <boost/preprocessor/iteration/iterate.hpp>
37 #include <boost/preprocessor/repetition/enum.hpp>
38 #include <boost/preprocessor/repetition/enum_params.hpp>
39 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
40 #include <boost/tuple/tuple.hpp>
42 namespace luabind
44 class object;
46 namespace detail
48 class proxy_object;
49 class proxy_raw_object;
50 class proxy_array_object;
52 template<class T>
53 void convert_to_lua(lua_State*, const T&);
55 template<int Index, class T, class Policies>
56 void convert_to_lua_p(lua_State*, const T&, const Policies&);
58 template<int Index>
59 struct push_args_from_tuple
61 template<class H, class T, class Policies>
62 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
64 convert_to_lua_p<Index>(L, *x.get_head(), p);
65 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
68 template<class H, class T>
69 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
71 convert_to_lua(L, *x.get_head());
72 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
75 template<class Policies>
76 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
78 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
82 template<class Tuple>
83 class proxy_caller
85 friend class luabind::object;
86 public:
88 proxy_caller(luabind::object* o, const Tuple args)
89 : m_obj(o)
90 , m_args(args)
91 , m_called(false)
95 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
96 : m_obj(rhs.m_obj)
97 , m_args(rhs.m_args)
98 , m_called(rhs.m_called)
100 rhs.m_called = true;
103 ~proxy_caller();
104 operator luabind::object();
106 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
107 #define LUABIND_SEMICOLON
108 #else
109 #define LUABIND_SEMICOLON ;
110 #endif
112 template<class Policies>
113 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
114 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
116 m_called = true;
117 lua_State* L = m_obj->lua_state();
118 m_obj->pushvalue();
119 detail::push_args_from_tuple<1>::apply(L, m_args, p);
120 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
122 #ifndef LUABIND_NO_EXCEPTIONS
123 throw error(L);
124 #else
125 error_callback_fun e = get_error_callback();
126 if (e) e(L);
128 assert(0 && "the lua function threw an error and exceptions are disabled."
129 "if you want to handle this error use luabind::set_error_callback()");
130 std::terminate();
131 #endif
133 detail::lua_reference ref;
134 ref.set(L);
135 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
137 #endif
140 #undef LUABIND_SEMICOLON
141 private:
143 luabind::object* m_obj;
144 Tuple m_args;
145 mutable bool m_called;
151 struct stack_pop
153 stack_pop(lua_State* L, int n)
154 : m_state(L)
155 , m_n(n)
159 ~stack_pop()
161 lua_pop(m_state, m_n);
164 private:
166 lua_State* m_state;
167 int m_n;
170 struct reset_stack
172 reset_stack(lua_State* L_, int offset = 0)
173 : L(L_)
174 , stack_size(lua_gettop(L_) - offset)
177 ~reset_stack()
179 assert(lua_gettop(L) >= stack_size);
180 lua_pop(L, lua_gettop(L) - stack_size);
182 lua_State* L;
183 int stack_size;
187 class LUABIND_API proxy_object
189 friend class luabind::object;
190 friend class luabind::detail::proxy_array_object;
191 friend class luabind::detail::proxy_raw_object;
192 // template<class T> friend T object_cast(const proxy_object& obj);
193 public:
195 template<class T>
196 proxy_object& operator=(const T& val)
198 //std::cout << "proxy assigment\n";
199 lua_State* L = m_obj->m_state;
200 m_obj->pushvalue();
201 m_key.get(L);
202 detail::convert_to_lua(L, val);
203 lua_settable(L, -3);
204 // pop table
205 lua_pop(L, 1);
206 return *this;
209 template<class T, class Policies>
210 void assign(const T& val, const Policies& p)
212 //std::cout << "proxy assigment\n";
213 lua_State* L = m_obj->m_state;
214 m_obj->pushvalue();
215 detail::getref(L, m_key_ref);
216 detail::convert_to_lua_p(L, val, p);
217 lua_settable(L, -3);
218 // pop table
219 lua_pop(L, 1);
220 return *this;
223 template<class T>
224 detail::proxy_object operator[](const T& key) const;
226 proxy_object& operator=(const object& p);
227 proxy_object& operator=(const proxy_object& p);
228 proxy_object& operator=(const proxy_raw_object& p);
229 proxy_object& operator=(const proxy_array_object& p);
231 void swap(const proxy_object& rhs);
232 proxy_object* operator->()
233 { return this; }
235 operator luabind::object();
237 int type() const
239 pushvalue();
240 detail::stack_pop p(lua_state(), 1);
241 return lua_type(lua_state(), -1);
244 #define LUABIND_PROXY_RAW_AT_BODY \
246 lua_State* L = lua_state();\
247 pushvalue();\
248 detail::convert_to_lua(L, key);\
249 lua_rawget(L, -2);\
250 detail::lua_reference ref;\
251 ref.set(L);\
252 lua_pop(L, 1);\
253 return object(L, ref, true);\
256 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
257 template<class T>
258 inline object raw_at(const T& key)
259 LUABIND_PROXY_RAW_AT_BODY
260 #else
261 template<class T>
262 inline object raw_at(const T& key);
263 #endif
265 #define LUABIND_PROXY_AT_BODY \
267 lua_State* L = lua_state();\
268 pushvalue();\
269 detail::convert_to_lua(L, key);\
270 lua_gettable(L, -2);\
271 detail::lua_reference ref;\
272 ref.set(L);\
273 lua_pop(L, 1);\
274 return object(L, ref, true);\
277 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
278 template<class T>
279 inline object at(const T& key)
280 LUABIND_PROXY_AT_BODY
281 #else
282 template<class T>
283 inline object at(const T& key);
284 #endif
286 inline bool is_valid() const { return true; }
287 lua_State* lua_state() const;
288 void pushvalue() const;
289 void set() const;
291 // this is a safe substitute for an implicit converter to bool
292 typedef void (proxy_object::*member_ptr)() const;
293 operator member_ptr() const
295 if (is_valid()) return &proxy_object::dummy;
296 return 0;
299 private:
301 void dummy() const {}
303 proxy_object(luabind::object* o, const lua_reference& key)
304 : m_obj(o)
305 , m_key(key)
309 luabind::object* m_obj;
310 detail::lua_reference m_key;
315 class LUABIND_API proxy_raw_object
317 friend class luabind::object;
318 friend class luabind::detail::proxy_array_object;
319 friend class luabind::detail::proxy_object;
320 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
321 public:
323 template<class T>
324 proxy_raw_object& operator=(const T& val)
326 //std::cout << "proxy assigment\n";
327 lua_State* L = m_obj->m_state;
328 m_obj->pushvalue();
329 detail::getref(L, m_key_ref);
330 detail::convert_to_lua(L, val);
331 lua_rawset(L, -3);
332 // pop table
333 lua_pop(L, 1);
334 return *this;
337 template<class T, class Policies>
338 void assign(const T& val, const Policies& p)
340 //std::cout << "proxy assigment\n";
341 lua_State* L = m_obj->m_state;
342 m_obj->pushvalue();
343 detail::getref(L, m_key_ref);
344 detail::convert_to_lua_p(L, val, p);
345 lua_settable(L, -3);
346 // pop table
347 lua_pop(L, 1);
348 return *this;
351 proxy_raw_object& operator=(const object& p);
352 proxy_raw_object& operator=(const proxy_object& p);
353 proxy_raw_object& operator=(const proxy_raw_object& p);
354 proxy_raw_object& operator=(const proxy_array_object& p);
355 void swap(const proxy_raw_object& rhs);
356 proxy_raw_object* operator->()
357 { return this; }
359 operator luabind::object();
361 int type() const
363 pushvalue();
364 detail::stack_pop p(lua_state(), 1);
365 return lua_type(lua_state(), -1);
368 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
369 template<class T>
370 inline object raw_at(const T& key)
371 LUABIND_PROXY_RAW_AT_BODY
372 #else
373 template<class T>
374 inline object raw_at(const T& key);
375 #endif
377 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
378 template<class T>
379 inline object at(const T& key)
380 LUABIND_PROXY_AT_BODY
381 #else
382 template<class T>
383 inline object at(const T& key);
384 #endif
386 inline bool is_valid() const { return true; }
387 lua_State* lua_state() const;
388 void pushvalue() const;
389 void set() const;
391 // this is a safe substitute for an implicit converter to bool
392 typedef void (proxy_raw_object::*member_ptr)() const;
393 operator member_ptr() const
395 if (is_valid()) return &proxy_raw_object::dummy;
396 return 0;
400 private:
402 void dummy() const {}
404 proxy_raw_object(luabind::object* o, const lua_reference& key)
405 : m_obj(o)
406 , m_key(key)
410 luabind::object* m_obj;
411 detail::lua_reference m_key;
416 class LUABIND_API proxy_array_object
418 friend class luabind::object;
419 friend class luabind::detail::proxy_object;
420 friend class luabind::detail::proxy_raw_object;
421 // template<class T> friend T object_cast(const proxy_array_object& obj);
422 public:
424 template<class T>
425 proxy_array_object& operator=(const T& val)
427 //std::cout << "array proxy assigment\n";
428 lua_State* L = m_obj->m_state;
429 m_obj->pushvalue();
430 detail::convert_to_lua(L, val);
431 lua_rawseti(L, -2, m_key);
433 // pops the table
434 lua_pop(L, 1);
435 return *this;
438 template<class T, class Policies>
439 void assign(const T& val, const Policies& p)
441 //std::cout << "proxy assigment\n";
442 lua_State* L = m_obj->m_state;
443 m_obj->pushvalue();
444 detail::convert_to_lua_p(L, val, p);
445 lua_rawseti(L, -2, m_key);
446 // pop table
447 lua_pop(L, 1);
448 return *this;
451 proxy_array_object& operator=(const object& p);
452 proxy_array_object& operator=(const proxy_object& p);
453 proxy_array_object& operator=(const proxy_raw_object& p);
454 proxy_array_object& operator=(const proxy_array_object& p);
455 void swap(const proxy_array_object& rhs);
457 proxy_array_object* operator->()
458 { return this; }
459 operator luabind::object();
461 int type() const
463 pushvalue();
464 detail::stack_pop p(lua_state(), 1);
465 return lua_type(lua_state(), -1);
468 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
470 pushvalue();\
471 detail::convert_to_lua(m_state, key);\
472 lua_rawget(m_state, -2);\
473 lua_reference ref;\
474 ref.set(m_state);\
475 lua_pop(m_state, 1);\
476 return object(m_state, ref, true);\
479 #define LUABIND_PROXY_ARRAY_AT_BODY\
481 pushvalue();\
482 detail::convert_to_lua(m_state, key);\
483 lua_gettable(m_state, -2);\
484 lua_reference ref;\
485 ref.set(m_state);\
486 lua_pop(m_state, 1);\
487 return object(m_state, ref, true);\
490 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
491 template<class T>
492 inline object at(const T& key)
493 LUABIND_PROXY_ARRAY_AT_BODY
494 #else
495 template<class T>
496 inline object at(const T& key);
497 #endif
500 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
501 template<class T>
502 inline object raw_at(const T& key)
503 LUABIND_PROXY_ARRAY_RAW_AT_BODY
504 #else
505 template<class T>
506 inline object raw_at(const T& key);
507 #endif
509 inline bool is_valid() const { return true; }
510 lua_State* lua_state() const;
511 void pushvalue() const;
512 void set() const;
514 // this is a safe substitute for an implicit converter to bool
515 typedef void (proxy_array_object::*member_ptr)() const;
516 operator member_ptr() const
518 if (is_valid()) return &proxy_array_object::dummy;
519 return 0;
522 private:
524 void dummy() const {}
526 proxy_array_object(luabind::object* o, int key)
527 : m_obj(o)
528 , m_key(key)
530 luabind::object* m_obj;
531 int m_key;
534 template<class T>
535 struct primitive_converter;
537 struct tuple_object_ref;
539 } // detail
541 class LUABIND_API object
544 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
546 template<class T>
547 friend T object_cast(const object& obj);
548 template<class T>
549 friend struct detail::primitive_converter;
551 #endif
553 friend object get_globals(lua_State*);
554 friend object get_registry(lua_State*);
555 friend object newtable(lua_State*);
556 friend class detail::proxy_object;
557 friend class detail::proxy_array_object;
558 friend class detail::proxy_raw_object;
560 public:
562 class array_iterator
564 friend class object;
565 public:
567 typedef std::forward_iterator_tag iterator_category;
568 typedef luabind::object value_type;
569 typedef value_type& reference;
570 typedef value_type* pointer;
571 typedef void difference_type;
573 array_iterator()
574 : m_obj(0)
575 , m_key(0)
579 array_iterator(const array_iterator& iter)
580 : m_obj(iter.m_obj)
581 , m_key(iter.m_key)
585 ~array_iterator() {}
587 array_iterator& operator=(const array_iterator& rhs)
589 m_obj = rhs.m_obj;
590 m_key = rhs.m_key;
591 return *this;
594 detail::proxy_array_object operator*()
596 return m_obj->make_array_proxy(m_key);
599 detail::proxy_array_object operator->()
601 return m_obj->make_array_proxy(m_key);
604 inline array_iterator& operator++()
606 LUABIND_CHECK_STACK(m_obj->lua_state());
608 m_key++;
610 // invalidate the iterator if we hit a nil element
611 lua_State* L = m_obj->lua_state();
612 m_obj->pushvalue();
613 lua_rawgeti(L, -1, m_key);
614 if (lua_isnil(L, -1)) m_key = -1;
615 lua_pop(L, 2);
617 return *this;
620 inline array_iterator operator++(int)
622 LUABIND_CHECK_STACK(m_obj->lua_state());
624 int old_key = m_key;
625 m_key++;
627 // invalidate the iterator if we hit a nil element
628 lua_State* L = m_obj->lua_state();
629 m_obj->pushvalue();
630 lua_rawgeti(L, -1, m_key);
631 if (lua_isnil(L, -1)) m_key = -1;
632 lua_pop(L, 2);
634 return array_iterator(m_obj, old_key);
637 bool operator!=(const array_iterator& rhs) const
639 return m_obj != rhs.m_obj || m_key != rhs.m_key;
642 private:
644 array_iterator(object* obj, int key)
645 : m_obj(obj)
646 , m_key(key)
650 object* m_obj;
651 int m_key;
659 class iterator
661 friend class object;
662 public:
664 typedef std::forward_iterator_tag iterator_category;
665 typedef luabind::object value_type;
666 typedef value_type& reference;
667 typedef value_type* pointer;
668 typedef void difference_type;
670 iterator()
671 : m_obj(0)
675 iterator(const iterator& iter)
676 : m_obj(iter.m_obj)
678 if (m_obj)
680 m_key = iter.m_key;
684 iterator& operator=(const iterator& rhs)
686 m_obj = rhs.m_obj;
687 if (m_obj)
689 m_key = rhs.m_key;
691 else
693 m_key.reset();
695 return *this;
698 detail::proxy_object operator*()
700 return m_obj->make_proxy(m_key);
703 detail::proxy_object operator->()
705 return m_obj->make_proxy(m_key);
708 iterator& operator++()
710 lua_State* L = m_obj->lua_state();
712 int n = lua_gettop(L);
714 m_obj->pushvalue();
715 m_key.get(L);
717 if (lua_next(L, -2) != 0)
719 lua_pop(L, 1);
720 m_key.replace(L);
721 lua_pop(L, 1);
723 else
725 lua_pop(L, 1);
726 m_obj = 0;
727 m_key.reset();
730 assert(n == lua_gettop(L));
731 return *this;
734 bool operator!=(const iterator& rhs) const
736 if (m_obj != rhs.m_obj) return true;
737 if (m_obj == 0) return false;
738 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
739 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
741 // TODO: fix this. add a real equality test of the keys
742 return true;
745 object key() const;
747 private:
749 iterator(luabind::object* obj, detail::lua_reference const& key)
750 : m_obj(obj)
751 , m_key(key)
755 object* m_obj;
756 detail::lua_reference m_key;
762 class raw_iterator
764 friend class object;
765 public:
767 typedef std::forward_iterator_tag iterator_category;
768 typedef luabind::object value_type;
769 typedef value_type& reference;
770 typedef value_type* pointer;
771 typedef void difference_type;
773 raw_iterator()
774 : m_obj(0)
778 raw_iterator(const raw_iterator& iter)
779 : m_obj(iter.m_obj)
780 , m_key()
782 if (m_obj)
784 m_key = iter.m_key;
788 raw_iterator& operator=(const raw_iterator& rhs)
790 //std::cout << "===\n";
791 m_obj = rhs.m_obj;
792 if (m_obj)
794 m_key = rhs.m_key;
796 else
798 m_key.reset();
800 return *this;
803 detail::proxy_raw_object operator*()
805 return m_obj->make_raw_proxy(m_key);
808 detail::proxy_raw_object operator->()
810 return m_obj->make_raw_proxy(m_key);
813 raw_iterator& operator++()
815 lua_State* L = m_obj->lua_state();
816 m_obj->pushvalue();
817 m_key.get(L);
819 if (lua_next(L, -2) != 0)
821 lua_pop(L, 1);
822 m_key.replace(L);
823 lua_pop(L, 1);
825 else
827 lua_pop(L, 1);
828 m_key.reset();
829 m_obj = 0;
832 return *this;
835 object key() const;
837 bool operator!=(const raw_iterator& rhs) const
839 if (m_obj != rhs.m_obj) return true;
840 if (m_obj == 0) return false;
841 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
842 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
844 // TODO: fix this. add a real equality test of the keys
845 return true;
848 private:
850 raw_iterator(object* obj, detail::lua_reference const& key)
851 : m_obj(obj)
852 , m_key(key)
855 object* m_obj;
856 detail::lua_reference m_key;
864 object()
865 : m_state(0)
869 explicit object(lua_State* L)
870 : m_state(L)
874 template<class T>
875 object(lua_State* L, const T& val)
876 : m_state(L)
878 *this = val;
881 object(const object& o)
882 : m_state(o.m_state)
884 o.m_ref.get(m_state);
885 m_ref.set(m_state);
888 inline ~object()
891 inline bool is_valid() const { return m_ref.is_valid(); }
893 // this is a safe substitute for an implicit converter to bool
894 typedef void (object::*member_ptr)() const;
895 operator member_ptr() const
897 if (is_valid()) return &object::dummy;
898 return 0;
901 int type() const
903 pushvalue();
904 detail::stack_pop p(lua_state(), 1);
905 return lua_type(lua_state(), -1);
908 inline iterator begin() const
910 m_ref.get(m_state);
911 lua_pushnil(m_state);
912 lua_next(m_state, -2);
913 lua_pop(m_state, 1);
914 detail::lua_reference r;
915 r.set(m_state);
916 iterator i(const_cast<object*>(this), r);
917 lua_pop(m_state, 1);
918 return i;
921 inline iterator end() const
923 return iterator(0, detail::lua_reference());
926 inline array_iterator abegin() const
928 return array_iterator(const_cast<object*>(this), 1);
931 inline array_iterator aend() const
933 return array_iterator(const_cast<object*>(this), -1);
936 raw_iterator raw_begin() const
938 m_ref.get(m_state);
939 lua_pushnil(m_state);
940 lua_next(m_state, -2);
941 lua_pop(m_state, 1);
942 detail::lua_reference r;
943 r.set(m_state);
944 raw_iterator i(const_cast<object*>(this), r);
945 lua_pop(m_state, 1);
946 return i;
949 raw_iterator raw_end() const
951 return raw_iterator(0, detail::lua_reference());
954 inline void set() const
956 // you are trying to access an invalid object
957 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
959 allocate_slot();
960 m_ref.replace(m_state);
962 inline lua_State* lua_state() const { return m_state; }
963 inline void pushvalue() const
965 // you are trying to dereference an invalid object
966 assert((m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
967 assert((m_state != 0) && "internal error, please report");
969 m_ref.get(m_state);
972 void swap(object& rhs);
974 template<class T>
975 inline object raw_at(const T& key)
977 lua_State* L = lua_state();
978 pushvalue();
979 detail::convert_to_lua(L, key);
980 lua_rawget(L, -2);
981 detail::lua_reference ref;
982 ref.set(L);
983 lua_pop(L, 1);
984 return object(L, ref, true);
987 template<class T>
988 inline object at(const T& key)
990 LUABIND_CHECK_STACK(m_state);
992 lua_State* L = lua_state();
993 pushvalue();
994 detail::convert_to_lua(L, key);
995 lua_gettable(L, -2);
996 detail::lua_reference ref;
997 ref.set(L);
998 lua_pop(L, 1);
999 return object(L, ref, true);
1002 template<class T>
1003 inline detail::proxy_object operator[](const T& key) const
1005 LUABIND_CHECK_STACK(m_state);
1007 detail::convert_to_lua(m_state, key);
1008 detail::lua_reference ref;
1009 ref.set(m_state);
1010 return detail::proxy_object(const_cast<object*>(this), ref);
1015 // *****************************
1016 // OPERATOR =
1018 template<class T>
1019 object& operator=(const T& val) const
1021 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1022 // you cannot assign a non-lua value to an uninitialized object
1024 detail::convert_to_lua(m_state, val);
1025 set();
1026 return const_cast<luabind::object&>(*this);
1029 object& operator=(const object& o) const;
1030 object& operator=(const detail::proxy_object& o) const;
1031 object& operator=(const detail::proxy_raw_object& o) const;
1032 object& operator=(const detail::proxy_array_object& o) const;
1034 template<class T, class Policies>
1035 void assign(const T& val, const Policies& p) const
1037 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1038 // you cannot assign a non-lua value to an uninitialized object
1040 detail::convert_to_lua_p(m_state, val, p);
1041 set();
1044 // const overload should return a tuple_object..?
1045 inline detail::tuple_object_ref operator,(const object& rhs) const;
1047 // *****************************
1048 // OPERATOR()
1050 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1051 #include BOOST_PP_ITERATE()
1055 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1057 return detail::proxy_object(this, key);
1060 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1062 return detail::proxy_raw_object(this, key);
1065 inline detail::proxy_array_object make_array_proxy(int key)
1067 return detail::proxy_array_object(this, key);
1070 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1071 // it's an inner class), that's why this interface is public
1072 // private:
1074 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1075 : m_state(L)
1076 , m_ref(ref)
1080 private:
1082 void dummy() const {}
1084 void allocate_slot() const
1086 if (!m_ref.is_valid())
1088 lua_pushboolean(m_state, 0);
1089 m_ref.set(m_state);
1093 mutable lua_State* m_state;
1094 mutable detail::lua_reference m_ref;
1098 // *************************************
1099 // OBJECT
1101 inline void object::swap(object& rhs)
1103 // you cannot swap objects from different lua states
1104 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1105 m_ref.swap(rhs.m_ref);
1108 inline object object::iterator::key() const
1110 lua_State* L = m_obj->lua_state();
1111 return object(L, m_key, true);
1114 inline object object::raw_iterator::key() const
1116 lua_State* L = m_obj->lua_state();
1117 return object(L, m_key, true);
1120 namespace detail
1122 // tuple object ----------------------------------------------
1124 struct tuple_object;
1126 struct tuple_object_ref
1128 tuple_object_ref(object* a, object* b)
1129 : n(2)
1130 { refs[0] = a; refs[1] = b; }
1132 tuple_object_ref& operator,(const object& x)
1133 { refs[n++] = const_cast<object*>(&x); return *this; }
1135 struct assign_into
1137 assign_into() {}
1139 template<class T>
1140 assign_into(tuple_object_ref& to, const T& val)
1141 : target(&to)
1142 , n(0)
1144 if (n >= target->n) return;
1145 *target->refs[n++] = val;
1148 template<class T>
1149 assign_into& operator,(const T& val)
1151 if (n >= target->n) return *this;
1152 *target->refs[n++] = val;
1153 return *this;
1156 tuple_object_ref* target;
1157 std::size_t n;
1160 template<class T>
1161 assign_into operator=(const T& val)
1162 { return assign_into(*this, val); }
1164 tuple_object_ref(const tuple_object_ref&);
1165 assign_into operator=(const tuple_object_ref& x)
1167 for (std::size_t i = 0; i < n && i < x.n; ++i)
1168 *refs[i] = *x.refs[i];
1169 return assign_into();
1172 inline assign_into operator=(const tuple_object&);
1174 std::size_t n;
1175 object* refs[10];
1178 struct tuple_object
1180 tuple_object(const object& x)
1181 : n(0)
1182 { objs[n++] = x; }
1184 tuple_object(const tuple_object_ref& x)
1186 for (std::size_t i = 0; i < x.n; ++i)
1187 objs[i] = *x.refs[i];
1190 std::size_t n;
1191 object objs[10];
1194 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1196 for (std::size_t i = 0; i < n && i < x.n; ++i)
1197 *refs[i] = x.objs[i];
1198 return assign_into();
1201 // *************************************
1202 // PROXY CALLER
1204 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1205 template<class Tuple>
1206 template<class Policies>
1207 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1209 m_called = true;
1210 lua_State* L = m_obj->lua_state();
1211 m_obj->pushvalue();
1212 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1213 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1215 #ifndef LUABIND_NO_EXCEPTIONS
1216 throw error(L);
1217 #else
1218 error_callback_fun e = get_error_callback();
1219 if (e) e(L);
1221 assert(0 && "the lua function threw an error and exceptions are disabled."
1222 "if you want to handle this error use luabind::set_error_callback()");
1223 std::terminate();
1224 #endif
1226 detail::lua_reference ref;
1227 ref.set(L);
1228 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1230 #endif
1231 // *************************************
1232 // PROXY OBJECT
1234 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1235 template<class T>
1236 inline object proxy_object::raw_at(const T& key)
1237 LUABIND_PROXY_RAW_AT_BODY
1239 template<class T>
1240 inline object proxy_object::at(const T& key)
1241 LUABIND_PROXY_AT_BODY
1242 #endif
1244 inline lua_State* proxy_object::lua_state() const
1246 return m_obj->lua_state();
1249 inline proxy_object::operator luabind::object()
1251 lua_State* L = m_obj->lua_state();
1252 pushvalue();
1253 detail::lua_reference ref;
1254 ref.set(L);
1255 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1259 // *************************************
1260 // PROXY ARRAY OBJECT
1262 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1263 template<class T>
1264 inline object proxy_array_object::raw_at(const T& key)
1265 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1267 template<class T>
1268 inline object proxy_array_object::at(const T& key)
1269 LUABIND_PROXY_ARRAY_AT_BODY
1270 #endif
1272 #undef LUABIND_PROXY_ARRAY_AT_BODY
1273 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1275 inline lua_State* proxy_array_object::lua_state() const
1277 return m_obj->lua_state();
1280 inline proxy_array_object::operator luabind::object()
1282 lua_State* L = m_obj->lua_state();
1283 pushvalue();
1284 detail::lua_reference ref;
1285 ref.set(L);
1286 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1290 // *************************************
1291 // PROXY RAW OBJECT
1293 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1294 template<class T>
1295 inline object proxy_raw_object::raw_at(const T& key)
1296 LUABIND_PROXY_RAW_AT_BODY
1298 template<class T>
1299 inline object proxy_raw_object::at(const T& key)
1300 LUABIND_PROXY_AT_BODY
1301 #endif
1303 #undef LUABIND_PROXY_RAW_AT_BODY
1304 #undef LUABIND_PROXY_AT_BODY
1306 inline lua_State* proxy_raw_object::lua_state() const
1308 return m_obj->lua_state();
1311 inline proxy_raw_object::operator luabind::object()
1313 lua_State* L = lua_state();
1314 pushvalue();
1315 detail::lua_reference ref;
1316 ref.set(L);
1317 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1321 // *************************************
1322 // PROXY CALLER
1325 template<class Tuple>
1326 proxy_caller<Tuple>::~proxy_caller()
1328 if (m_called) return;
1330 m_called = true;
1331 lua_State* L = m_obj->lua_state();
1332 m_obj->pushvalue();
1334 push_args_from_tuple<1>::apply(L, m_args);
1335 if (pcall(L, boost::tuples::length<Tuple>::value, 0))
1337 #ifndef LUABIND_NO_EXCEPTIONS
1338 throw luabind::error(L);
1339 #else
1340 error_callback_fun e = get_error_callback();
1341 if (e) e(L);
1343 assert(0 && "the lua function threw an error and exceptions are disabled."
1344 "if you want to handle this error use luabind::set_error_callback()");
1345 std::terminate();
1346 #endif
1350 template<class Tuple>
1351 proxy_caller<Tuple>::operator luabind::object()
1353 m_called = true;
1354 lua_State* L = m_obj->lua_state();
1355 m_obj->pushvalue();
1357 push_args_from_tuple<1>::apply(L, m_args);
1358 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1360 #ifndef LUABIND_NO_EXCEPTIONS
1361 throw luabind::error(L);
1362 #else
1363 error_callback_fun e = get_error_callback();
1364 if (e) e(L);
1366 assert(0 && "the lua function threw an error and exceptions are disabled."
1367 "if you want to handle this error use luabind::set_error_callback()");
1368 std::terminate();
1369 #endif
1371 detail::lua_reference ref;
1372 ref.set(L);
1373 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1378 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1380 return detail::tuple_object_ref(
1381 const_cast<object*>(this), const_cast<object*>(&rhs));
1384 typedef detail::tuple_object function_;
1386 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1387 MACRO(object, object) \
1388 MACRO(object, detail::proxy_object) \
1389 MACRO(object, detail::proxy_array_object) \
1390 MACRO(object, detail::proxy_raw_object) \
1391 MACRO(detail::proxy_object, object) \
1392 MACRO(detail::proxy_object, detail::proxy_object) \
1393 MACRO(detail::proxy_object, detail::proxy_array_object) \
1394 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1395 MACRO(detail::proxy_array_object, object) \
1396 MACRO(detail::proxy_array_object, detail::proxy_object) \
1397 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1398 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1399 MACRO(detail::proxy_raw_object, object) \
1400 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1401 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1402 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1405 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1406 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1407 #undef LUABIND_EQUALITY_OPERATOR
1409 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1410 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1411 #undef LUABIND_LESSTHAN_OPERATOR
1413 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1414 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1415 #undef LUABIND_LESSOREQUAL_OPERATOR
1417 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1418 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1420 return !(rhs == lhs); \
1423 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1425 #undef LUABIND_INEQUALITY_OPERATOR
1427 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1428 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1430 return !(rhs < lhs); \
1433 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1435 #undef LUABIND_GREATEROREQUAL_OPERATOR
1437 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1438 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1440 return !(lhs <= rhs); \
1443 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1444 #undef LUABIND_GREATERTHAN_OPERATOR
1446 #undef LUABIND_DECLARE_OPERATOR
1450 namespace std
1453 #define LUABIND_DEFINE_SWAP(t1,t2)\
1454 inline void swap(t1 lhs, t2 rhs)\
1456 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1457 rhs.pushvalue();\
1458 lhs.pushvalue();\
1459 rhs.set();\
1460 lhs.set();\
1463 inline void swap(luabind::object& lhs, luabind::object& rhs)
1465 lhs.swap(rhs);
1468 // object against all other
1469 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1470 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1471 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1472 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1473 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1474 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1476 // proxy_object against all other
1477 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1478 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1479 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1480 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1481 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1483 // proxy_raw_object against all other
1484 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1485 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1486 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1488 // proxy_array_object against all other
1489 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1491 #undef LUABIND_DEFINE_SWAP
1493 } // std
1495 #endif // LUABIND_OBJECT_HPP_INCLUDED
1497 #elif BOOST_PP_ITERATION_FLAGS() == 1
1499 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1500 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1502 #if BOOST_PP_ITERATION() > 0
1503 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1504 #endif
1505 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1506 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1508 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1509 #if BOOST_PP_ITERATION() == 0
1510 tuple_t args;
1511 #else
1512 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1513 #endif
1514 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1517 #undef LUABIND_OPERATOR_PARAMS
1518 #undef LUABIND_TUPLE_PARAMS
1520 #endif