*** empty log message ***
[luabind.git] / luabind / object.hpp
blob8798dc98d122035ff61f157b0099f917a54d5ace
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #if !BOOST_PP_IS_ITERATING
25 #ifndef LUABIND_OBJECT_HPP_INCLUDED
26 #define LUABIND_OBJECT_HPP_INCLUDED
28 #include <iterator>
30 #include <luabind/prefix.hpp>
31 #include <luabind/config.hpp>
32 #include <luabind/error.hpp>
33 #include <luabind/detail/pcall.hpp>
35 #include <boost/preprocessor/repeat.hpp>
36 #include <boost/preprocessor/iteration/iterate.hpp>
37 #include <boost/preprocessor/repetition/enum.hpp>
38 #include <boost/preprocessor/repetition/enum_params.hpp>
39 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
40 #include <boost/tuple/tuple.hpp>
42 namespace luabind
44 class object;
46 namespace detail
48 class proxy_object;
49 class proxy_raw_object;
50 class proxy_array_object;
52 template<class T>
53 void convert_to_lua(lua_State*, const T&);
55 template<int Index, class T, class Policies>
56 void convert_to_lua_p(lua_State*, const T&, const Policies&);
58 template<int Index>
59 struct push_args_from_tuple
61 template<class H, class T, class Policies>
62 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
64 convert_to_lua_p<Index>(L, *x.get_head(), p);
65 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
68 template<class H, class T>
69 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
71 convert_to_lua(L, *x.get_head());
72 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
75 template<class Policies>
76 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
78 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
82 template<class Tuple>
83 class proxy_caller
85 friend class luabind::object;
86 public:
88 proxy_caller(luabind::object* o, const Tuple args)
89 : m_obj(o)
90 , m_args(args)
91 , m_called(false)
95 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
96 : m_obj(rhs.m_obj)
97 , m_args(rhs.m_args)
98 , m_called(rhs.m_called)
100 rhs.m_called = true;
103 ~proxy_caller();
104 operator luabind::object();
106 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
107 #define LUABIND_SEMICOLON
108 #else
109 #define LUABIND_SEMICOLON ;
110 #endif
112 template<class Policies>
113 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
114 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
116 m_called = true;
117 lua_State* L = m_obj->lua_state();
118 m_obj->pushvalue();
119 detail::push_args_from_tuple<1>::apply(L, m_args, p);
120 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
122 #ifndef LUABIND_NO_EXCEPTIONS
123 throw error(L);
124 #else
125 error_callback_fun e = get_error_callback();
126 if (e) e(L);
128 assert(0 && "the lua function threw an error and exceptions are disabled."
129 "if you want to handle this error use luabind::set_error_callback()");
130 std::terminate();
131 #endif
133 detail::lua_reference ref;
134 ref.set(L);
135 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
137 #endif
140 #undef LUABIND_SEMICOLON
141 private:
143 luabind::object* m_obj;
144 Tuple m_args;
145 mutable bool m_called;
151 struct stack_pop
153 stack_pop(lua_State* L, int n)
154 : m_state(L)
155 , m_n(n)
159 ~stack_pop()
161 lua_pop(m_state, m_n);
164 private:
166 lua_State* m_state;
167 int m_n;
174 class LUABIND_API proxy_object
176 friend class luabind::object;
177 friend class luabind::detail::proxy_array_object;
178 friend class luabind::detail::proxy_raw_object;
179 // template<class T> friend T object_cast(const proxy_object& obj);
180 public:
182 template<class T>
183 proxy_object& operator=(const T& val)
185 //std::cout << "proxy assigment\n";
186 lua_State* L = m_obj->m_state;
187 m_obj->pushvalue();
188 m_key.get(L);
189 detail::convert_to_lua(L, val);
190 lua_settable(L, -3);
191 // pop table
192 lua_pop(L, 1);
193 return *this;
196 template<class T, class Policies>
197 void assign(const T& val, const Policies& p)
199 //std::cout << "proxy assigment\n";
200 lua_State* L = m_obj->m_state;
201 m_obj->pushvalue();
202 detail::getref(L, m_key_ref);
203 detail::convert_to_lua_p(L, val, p);
204 lua_settable(L, -3);
205 // pop table
206 lua_pop(L, 1);
207 return *this;
210 proxy_object& operator=(const object& p);
211 proxy_object& operator=(const proxy_object& p);
212 proxy_object& operator=(const proxy_raw_object& p);
213 proxy_object& operator=(const proxy_array_object& p);
215 void swap(const proxy_object& rhs);
217 operator luabind::object();
219 int type() const
221 pushvalue();
222 detail::stack_pop p(lua_state(), 1);
223 return lua_type(lua_state(), -1);
226 #define LUABIND_PROXY_RAW_AT_BODY \
228 lua_State* L = lua_state();\
229 pushvalue();\
230 detail::convert_to_lua(L, key);\
231 lua_rawget(L, -2);\
232 detail::lua_reference ref;\
233 ref.set(L);\
234 lua_pop(L, 1);\
235 return object(L, ref, true);\
238 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
239 template<class T>
240 inline object raw_at(const T& key)
241 LUABIND_PROXY_RAW_AT_BODY
242 #else
243 template<class T>
244 inline object raw_at(const T& key);
245 #endif
247 #define LUABIND_PROXY_AT_BODY \
249 lua_State* L = lua_state();\
250 pushvalue();\
251 detail::convert_to_lua(L, key);\
252 lua_gettable(L, -2);\
253 detail::lua_reference ref;\
254 ref.set(L);\
255 lua_pop(L, 1);\
256 return object(L, ref, true);\
259 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
260 template<class T>
261 inline object at(const T& key)
262 LUABIND_PROXY_AT_BODY
263 #else
264 template<class T>
265 inline object at(const T& key);
266 #endif
268 inline bool is_valid() const { return true; }
269 lua_State* lua_state() const;
270 void pushvalue() const;
271 void set() const;
273 // this is a safe substitute for an implicit converter to bool
274 typedef void (proxy_object::*member_ptr)() const;
275 operator member_ptr() const
277 if (is_valid()) return &proxy_object::dummy;
278 return 0;
281 private:
283 void dummy() const {}
285 proxy_object(luabind::object* o, const lua_reference& key)
286 : m_obj(o)
287 , m_key(key)
291 luabind::object* m_obj;
292 detail::lua_reference m_key;
297 class LUABIND_API proxy_raw_object
299 friend class luabind::object;
300 friend class luabind::detail::proxy_array_object;
301 friend class luabind::detail::proxy_object;
302 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
303 public:
305 template<class T>
306 proxy_raw_object& operator=(const T& val)
308 //std::cout << "proxy assigment\n";
309 lua_State* L = m_obj->m_state;
310 m_obj->pushvalue();
311 detail::getref(L, m_key_ref);
312 detail::convert_to_lua(L, val);
313 lua_rawset(L, -3);
314 // pop table
315 lua_pop(L, 1);
316 return *this;
319 template<class T, class Policies>
320 void assign(const T& val, const Policies& p)
322 //std::cout << "proxy assigment\n";
323 lua_State* L = m_obj->m_state;
324 m_obj->pushvalue();
325 detail::getref(L, m_key_ref);
326 detail::convert_to_lua_p(L, val, p);
327 lua_settable(L, -3);
328 // pop table
329 lua_pop(L, 1);
330 return *this;
333 proxy_raw_object& operator=(const object& p);
334 proxy_raw_object& operator=(const proxy_object& p);
335 proxy_raw_object& operator=(const proxy_raw_object& p);
336 proxy_raw_object& operator=(const proxy_array_object& p);
337 void swap(const proxy_raw_object& rhs);
339 operator luabind::object();
341 int type() const
343 pushvalue();
344 detail::stack_pop p(lua_state(), 1);
345 return lua_type(lua_state(), -1);
348 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
349 template<class T>
350 inline object raw_at(const T& key)
351 LUABIND_PROXY_RAW_AT_BODY
352 #else
353 template<class T>
354 inline object raw_at(const T& key);
355 #endif
357 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
358 template<class T>
359 inline object at(const T& key)
360 LUABIND_PROXY_AT_BODY
361 #else
362 template<class T>
363 inline object at(const T& key);
364 #endif
366 inline bool is_valid() const { return true; }
367 lua_State* lua_state() const;
368 void pushvalue() const;
369 void set() const;
371 // this is a safe substitute for an implicit converter to bool
372 typedef void (proxy_raw_object::*member_ptr)() const;
373 operator member_ptr() const
375 if (is_valid()) return &proxy_raw_object::dummy;
376 return 0;
380 private:
382 void dummy() const {}
384 proxy_raw_object(luabind::object* o, const lua_reference& key)
385 : m_obj(o)
386 , m_key(key)
390 luabind::object* m_obj;
391 detail::lua_reference m_key;
396 class LUABIND_API proxy_array_object
398 friend class luabind::object;
399 friend class luabind::detail::proxy_object;
400 friend class luabind::detail::proxy_raw_object;
401 // template<class T> friend T object_cast(const proxy_array_object& obj);
402 public:
404 template<class T>
405 proxy_array_object& operator=(const T& val)
407 //std::cout << "array proxy assigment\n";
408 lua_State* L = m_obj->m_state;
409 m_obj->pushvalue();
410 detail::convert_to_lua(L, val);
411 lua_rawseti(L, -2, m_key);
413 // pops the table
414 lua_pop(L, 1);
415 return *this;
418 template<class T, class Policies>
419 void assign(const T& val, const Policies& p)
421 //std::cout << "proxy assigment\n";
422 lua_State* L = m_obj->m_state;
423 m_obj->pushvalue();
424 detail::convert_to_lua_p(L, val, p);
425 lua_rawseti(L, -2, m_key);
426 // pop table
427 lua_pop(L, 1);
428 return *this;
431 proxy_array_object& operator=(const object& p);
432 proxy_array_object& operator=(const proxy_object& p);
433 proxy_array_object& operator=(const proxy_raw_object& p);
434 proxy_array_object& operator=(const proxy_array_object& p);
435 void swap(const proxy_array_object& rhs);
437 operator luabind::object();
439 int type() const
441 pushvalue();
442 detail::stack_pop p(lua_state(), 1);
443 return lua_type(lua_state(), -1);
446 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
448 pushvalue();\
449 detail::convert_to_lua(m_state, key);\
450 lua_rawget(m_state, -2);\
451 lua_reference ref;\
452 ref.set(m_state);\
453 lua_pop(m_state, 1);\
454 return object(m_state, ref, true);\
457 #define LUABIND_PROXY_ARRAY_AT_BODY\
459 pushvalue();\
460 detail::convert_to_lua(m_state, key);\
461 lua_gettable(m_state, -2);\
462 lua_reference ref;\
463 ref.set(m_state);\
464 lua_pop(m_state, 1);\
465 return object(m_state, ref, true);\
468 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
469 template<class T>
470 inline object at(const T& key)
471 LUABIND_PROXY_ARRAY_AT_BODY
472 #else
473 template<class T>
474 inline object at(const T& key);
475 #endif
478 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
479 template<class T>
480 inline object raw_at(const T& key)
481 LUABIND_PROXY_ARRAY_RAW_AT_BODY
482 #else
483 template<class T>
484 inline object raw_at(const T& key);
485 #endif
487 template<class T>
488 inline detail::proxy_object operator[](const T& key) const
490 detail::convert_to_lua(m_state, key);
491 lua_reference ref;\
492 ref.set(m_state);\
493 return detail::proxy_object(const_cast<object*>(this), ref);
496 inline bool is_valid() const { return true; }
497 lua_State* lua_state() const;
498 void pushvalue() const;
499 void set() const;
501 // this is a safe substitute for an implicit converter to bool
502 typedef void (proxy_array_object::*member_ptr)() const;
503 operator member_ptr() const
505 if (is_valid()) return &proxy_array_object::dummy;
506 return 0;
509 private:
511 void dummy() const {}
513 proxy_array_object(luabind::object* o, int key)
514 : m_obj(o)
515 , m_key(key)
517 luabind::object* m_obj;
518 int m_key;
521 template<class T>
522 struct primitive_converter;
524 struct tuple_object_ref;
526 } // detail
528 class LUABIND_API object
531 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
533 template<class T>
534 friend T object_cast(const object& obj);
535 template<class T>
536 friend struct detail::primitive_converter;
538 #endif
540 friend object get_globals(lua_State*);
541 friend object get_registry(lua_State*);
542 friend object newtable(lua_State*);
543 friend class detail::proxy_object;
544 friend class detail::proxy_array_object;
545 friend class detail::proxy_raw_object;
547 public:
549 class array_iterator
551 friend class object;
552 public:
554 typedef std::forward_iterator_tag iterator_category;
555 typedef luabind::object value_type;
556 typedef value_type& reference;
557 typedef value_type* pointer;
558 typedef void difference_type;
560 array_iterator()
561 : m_obj(0)
562 , m_key(0)
566 array_iterator(const array_iterator& iter)
567 : m_obj(iter.m_obj)
568 , m_key(iter.m_key)
572 ~array_iterator() {}
574 array_iterator& operator=(const array_iterator& rhs)
576 m_obj = rhs.m_obj;
577 m_key = rhs.m_key;
578 return *this;
581 detail::proxy_array_object operator*()
583 return m_obj->make_array_proxy(m_key);
586 inline array_iterator& operator++()
588 LUABIND_CHECK_STACK(m_obj->lua_state());
590 m_key++;
592 // invalidate the iterator if we hit a nil element
593 lua_State* L = m_obj->lua_state();
594 m_obj->pushvalue();
595 lua_rawgeti(L, -1, m_key);
596 if (lua_isnil(L, -1)) m_key = -1;
597 lua_pop(L, 2);
599 return *this;
602 inline array_iterator operator++(int)
604 LUABIND_CHECK_STACK(m_obj->lua_state());
606 int old_key = m_key;
607 m_key++;
609 // invalidate the iterator if we hit a nil element
610 lua_State* L = m_obj->lua_state();
611 m_obj->pushvalue();
612 lua_rawgeti(L, -1, m_key);
613 if (lua_isnil(L, -1)) m_key = -1;
614 lua_pop(L, 2);
616 return array_iterator(m_obj, old_key);
619 bool operator!=(const array_iterator& rhs) const
621 return m_obj != rhs.m_obj || m_key != rhs.m_key;
624 private:
626 array_iterator(object* obj, int key)
627 : m_obj(obj)
628 , m_key(key)
632 object* m_obj;
633 int m_key;
641 class iterator
643 friend class object;
644 public:
646 typedef std::forward_iterator_tag iterator_category;
647 typedef luabind::object value_type;
648 typedef value_type& reference;
649 typedef value_type* pointer;
650 typedef void difference_type;
652 iterator()
653 : m_obj(0)
657 iterator(const iterator& iter)
658 : m_obj(iter.m_obj)
660 if (m_obj)
662 m_key = iter.m_key;
666 iterator& operator=(const iterator& rhs)
668 m_obj = rhs.m_obj;
669 if (m_obj)
671 m_key = rhs.m_key;
673 else
675 m_key.reset();
677 return *this;
680 detail::proxy_object operator*()
682 return m_obj->make_proxy(m_key);
685 iterator& operator++()
687 lua_State* L = m_obj->lua_state();
689 int n = lua_gettop(L);
691 m_obj->pushvalue();
692 m_key.get(L);
694 if (lua_next(L, -2) != 0)
696 lua_pop(L, 1);
697 m_key.replace(L);
698 lua_pop(L, 1);
700 else
702 lua_pop(L, 1);
703 m_obj = 0;
704 m_key.reset();
707 assert(n == lua_gettop(L));
708 return *this;
711 bool operator!=(const iterator& rhs) const
713 if (m_obj != rhs.m_obj) return true;
714 if (m_obj == 0) return false;
715 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
716 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
718 // TODO: fix this. add a real equality test of the keys
719 return true;
722 object key() const;
724 private:
726 iterator(luabind::object* obj, detail::lua_reference const& key)
727 : m_obj(obj)
728 , m_key(key)
732 object* m_obj;
733 detail::lua_reference m_key;
739 class raw_iterator
741 friend class object;
742 public:
744 typedef std::forward_iterator_tag iterator_category;
745 typedef luabind::object value_type;
746 typedef value_type& reference;
747 typedef value_type* pointer;
748 typedef void difference_type;
750 raw_iterator()
751 : m_obj(0)
755 raw_iterator(const raw_iterator& iter)
756 : m_obj(iter.m_obj)
757 , m_key()
759 if (m_obj)
761 m_key = iter.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 m_key = rhs.m_key;
773 else
775 m_key.reset();
777 return *this;
780 detail::proxy_raw_object operator*()
782 return m_obj->make_raw_proxy(m_key);
785 raw_iterator& operator++()
787 lua_State* L = m_obj->lua_state();
788 m_obj->pushvalue();
789 m_key.get(L);
791 if (lua_next(L, -2) != 0)
793 lua_pop(L, 1);
794 m_key.replace(L);
795 lua_pop(L, 1);
797 else
799 lua_pop(L, 1);
800 m_key.reset();
801 m_obj = 0;
804 return *this;
807 object key() const;
809 bool operator!=(const raw_iterator& rhs) const
811 if (m_obj != rhs.m_obj) return true;
812 if (m_obj == 0) return false;
813 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
814 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
816 // TODO: fix this. add a real equality test of the keys
817 return true;
820 private:
822 raw_iterator(object* obj, detail::lua_reference const& key)
823 : m_obj(obj)
824 , m_key(key)
827 object* m_obj;
828 detail::lua_reference m_key;
836 object()
837 : m_state(0)
841 explicit object(lua_State* L)
842 : m_state(L)
846 template<class T>
847 object(lua_State* L, const T& val)
848 : m_state(L)
850 *this = val;
853 object(const object& o)
854 : m_state(o.m_state)
856 o.m_ref.get(m_state);
857 m_ref.set(m_state);
860 inline ~object()
863 inline bool is_valid() const { return m_ref.is_valid(); }
865 // this is a safe substitute for an implicit converter to bool
866 typedef void (object::*member_ptr)() const;
867 operator member_ptr() const
869 if (is_valid()) return &object::dummy;
870 return 0;
873 int type() const
875 pushvalue();
876 detail::stack_pop p(lua_state(), 1);
877 return lua_type(lua_state(), -1);
880 inline iterator begin() const
882 m_ref.get(m_state);
883 lua_pushnil(m_state);
884 lua_next(m_state, -2);
885 lua_pop(m_state, 1);
886 detail::lua_reference r;
887 r.set(m_state);
888 iterator i(const_cast<object*>(this), r);
889 lua_pop(m_state, 1);
890 return i;
893 inline iterator end() const
895 return iterator(0, detail::lua_reference());
898 inline array_iterator abegin() const
900 return array_iterator(const_cast<object*>(this), 1);
903 inline array_iterator aend() const
905 return array_iterator(const_cast<object*>(this), -1);
908 raw_iterator raw_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 raw_iterator i(const_cast<object*>(this), r);
917 lua_pop(m_state, 1);
918 return i;
921 raw_iterator raw_end() const
923 return raw_iterator(0, detail::lua_reference());
926 inline void set() const
928 // you are trying to access an invalid object
929 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
931 allocate_slot();
932 m_ref.replace(m_state);
934 inline lua_State* lua_state() const { return m_state; }
935 inline void pushvalue() const
937 // you are trying to dereference an invalid object
938 assert((m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
939 assert((m_state != 0) && "internal error, please report");
941 m_ref.get(m_state);
944 void swap(object& rhs);
946 template<class T>
947 inline object raw_at(const T& key)
949 lua_State* L = lua_state();
950 pushvalue();
951 detail::convert_to_lua(L, key);
952 lua_rawget(L, -2);
953 detail::lua_reference ref;
954 ref.set(L);
955 lua_pop(L, 1);
956 return object(L, ref, true);
959 template<class T>
960 inline object at(const T& key)
962 LUABIND_CHECK_STACK(m_state);
964 lua_State* L = lua_state();
965 pushvalue();
966 detail::convert_to_lua(L, key);
967 lua_gettable(L, -2);
968 detail::lua_reference ref;
969 ref.set(L);
970 lua_pop(L, 1);
971 return object(L, ref, true);
974 template<class T>
975 inline detail::proxy_object operator[](const T& key) const
977 LUABIND_CHECK_STACK(m_state);
979 detail::convert_to_lua(m_state, key);
980 detail::lua_reference ref;
981 ref.set(m_state);
982 return detail::proxy_object(const_cast<object*>(this), ref);
987 // *****************************
988 // OPERATOR =
990 template<class T>
991 object& operator=(const T& val) const
993 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
994 // you cannot assign a non-lua value to an uninitialized object
996 detail::convert_to_lua(m_state, val);
997 set();
998 return const_cast<luabind::object&>(*this);
1001 object& operator=(const object& o) const;
1002 object& operator=(const detail::proxy_object& o) const;
1003 object& operator=(const detail::proxy_raw_object& o) const;
1004 object& operator=(const detail::proxy_array_object& o) const;
1006 template<class T, class Policies>
1007 void assign(const T& val, const Policies& p) const
1009 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1010 // you cannot assign a non-lua value to an uninitialized object
1012 detail::convert_to_lua_p(m_state, val, p);
1013 set();
1016 // const overload should return a tuple_object..?
1017 inline detail::tuple_object_ref operator,(const object& rhs) const;
1019 // *****************************
1020 // OPERATOR()
1022 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1023 #include BOOST_PP_ITERATE()
1027 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1029 return detail::proxy_object(this, key);
1032 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1034 return detail::proxy_raw_object(this, key);
1037 inline detail::proxy_array_object make_array_proxy(int key)
1039 return detail::proxy_array_object(this, key);
1042 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1043 // it's an inner class), that's why this interface is public
1044 // private:
1046 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1047 : m_state(L)
1048 , m_ref(ref)
1052 private:
1054 void dummy() const {}
1056 void allocate_slot() const
1058 if (!m_ref.is_valid())
1060 lua_pushboolean(m_state, 0);
1061 m_ref.set(m_state);
1065 mutable lua_State* m_state;
1066 mutable detail::lua_reference m_ref;
1070 // *************************************
1071 // OBJECT
1073 inline void object::swap(object& rhs)
1075 // you cannot swap objects from different lua states
1076 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1077 m_ref.swap(rhs.m_ref);
1080 inline object object::iterator::key() const
1082 lua_State* L = m_obj->lua_state();
1083 return object(L, m_key, true);
1086 inline object object::raw_iterator::key() const
1088 lua_State* L = m_obj->lua_state();
1089 return object(L, m_key, true);
1092 namespace detail
1094 // tuple object ----------------------------------------------
1096 struct tuple_object;
1098 struct tuple_object_ref
1100 tuple_object_ref(object* a, object* b)
1101 : n(2)
1102 { refs[0] = a; refs[1] = b; }
1104 tuple_object_ref& operator,(const object& x)
1105 { refs[n++] = const_cast<object*>(&x); return *this; }
1107 struct assign_into
1109 assign_into() {}
1111 template<class T>
1112 assign_into(tuple_object_ref& to, const T& val)
1113 : target(&to)
1114 , n(0)
1116 if (n >= target->n) return;
1117 *target->refs[n++] = val;
1120 template<class T>
1121 assign_into& operator,(const T& val)
1123 if (n >= target->n) return *this;
1124 *target->refs[n++] = val;
1125 return *this;
1128 tuple_object_ref* target;
1129 std::size_t n;
1132 template<class T>
1133 assign_into operator=(const T& val)
1134 { return assign_into(*this, val); }
1136 tuple_object_ref(const tuple_object_ref&);
1137 assign_into operator=(const tuple_object_ref& x)
1139 for (std::size_t i = 0; i < n && i < x.n; ++i)
1140 *refs[i] = *x.refs[i];
1141 return assign_into();
1144 inline assign_into operator=(const tuple_object&);
1146 std::size_t n;
1147 object* refs[10];
1150 struct tuple_object
1152 tuple_object(const object& x)
1153 : n(0)
1154 { objs[n++] = x; }
1156 tuple_object(const tuple_object_ref& x)
1158 for (std::size_t i = 0; i < x.n; ++i)
1159 objs[i] = *x.refs[i];
1162 std::size_t n;
1163 object objs[10];
1166 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1168 for (std::size_t i = 0; i < n && i < x.n; ++i)
1169 *refs[i] = x.objs[i];
1170 return assign_into();
1173 // *************************************
1174 // PROXY CALLER
1176 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1177 template<class Tuple>
1178 template<class Policies>
1179 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1181 m_called = true;
1182 lua_State* L = m_obj->lua_state();
1183 m_obj->pushvalue();
1184 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1185 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1187 #ifndef LUABIND_NO_EXCEPTIONS
1188 throw error(L);
1189 #else
1190 error_callback_fun e = get_error_callback();
1191 if (e) e(L);
1193 assert(0 && "the lua function threw an error and exceptions are disabled."
1194 "if you want to handle this error use luabind::set_error_callback()");
1195 std::terminate();
1196 #endif
1198 detail::lua_reference ref;
1199 ref.set(L);
1200 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1202 #endif
1203 // *************************************
1204 // PROXY OBJECT
1206 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1207 template<class T>
1208 inline object proxy_object::raw_at(const T& key)
1209 LUABIND_PROXY_RAW_AT_BODY
1211 template<class T>
1212 inline object proxy_object::at(const T& key)
1213 LUABIND_PROXY_AT_BODY
1214 #endif
1216 inline lua_State* proxy_object::lua_state() const
1218 return m_obj->lua_state();
1221 inline proxy_object::operator luabind::object()
1223 lua_State* L = m_obj->lua_state();
1224 pushvalue();
1225 detail::lua_reference ref;
1226 ref.set(L);
1227 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1231 // *************************************
1232 // PROXY ARRAY OBJECT
1234 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1235 template<class T>
1236 inline object proxy_array_object::raw_at(const T& key)
1237 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1239 template<class T>
1240 inline object proxy_array_object::at(const T& key)
1241 LUABIND_PROXY_ARRAY_AT_BODY
1242 #endif
1244 #undef LUABIND_PROXY_ARRAY_AT_BODY
1245 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1247 inline lua_State* proxy_array_object::lua_state() const
1249 return m_obj->lua_state();
1252 inline proxy_array_object::operator luabind::object()
1254 lua_State* L = m_obj->lua_state();
1255 pushvalue();
1256 detail::lua_reference ref;
1257 ref.set(L);
1258 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1262 // *************************************
1263 // PROXY RAW OBJECT
1265 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1266 template<class T>
1267 inline object proxy_raw_object::raw_at(const T& key)
1268 LUABIND_PROXY_RAW_AT_BODY
1270 template<class T>
1271 inline object proxy_raw_object::at(const T& key)
1272 LUABIND_PROXY_AT_BODY
1273 #endif
1275 #undef LUABIND_PROXY_RAW_AT_BODY
1276 #undef LUABIND_PROXY_AT_BODY
1278 inline lua_State* proxy_raw_object::lua_state() const
1280 return m_obj->lua_state();
1283 inline proxy_raw_object::operator luabind::object()
1285 lua_State* L = lua_state();
1286 pushvalue();
1287 detail::lua_reference ref;
1288 ref.set(L);
1289 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1293 // *************************************
1294 // PROXY CALLER
1297 template<class Tuple>
1298 proxy_caller<Tuple>::~proxy_caller()
1300 if (m_called) return;
1302 m_called = true;
1303 lua_State* L = m_obj->lua_state();
1304 m_obj->pushvalue();
1306 push_args_from_tuple<1>::apply(L, m_args);
1307 if (pcall(L, boost::tuples::length<Tuple>::value, 0))
1309 #ifndef LUABIND_NO_EXCEPTIONS
1310 throw luabind::error(L);
1311 #else
1312 error_callback_fun e = get_error_callback();
1313 if (e) e(L);
1315 assert(0 && "the lua function threw an error and exceptions are disabled."
1316 "if you want to handle this error use luabind::set_error_callback()");
1317 std::terminate();
1318 #endif
1322 template<class Tuple>
1323 proxy_caller<Tuple>::operator luabind::object()
1325 m_called = true;
1326 lua_State* L = m_obj->lua_state();
1327 m_obj->pushvalue();
1329 push_args_from_tuple<1>::apply(L, m_args);
1330 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1332 #ifndef LUABIND_NO_EXCEPTIONS
1333 throw luabind::error(L);
1334 #else
1335 error_callback_fun e = get_error_callback();
1336 if (e) e(L);
1338 assert(0 && "the lua function threw an error and exceptions are disabled."
1339 "if you want to handle this error use luabind::set_error_callback()");
1340 std::terminate();
1341 #endif
1343 detail::lua_reference ref;
1344 ref.set(L);
1345 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1350 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1352 return detail::tuple_object_ref(
1353 const_cast<object*>(this), const_cast<object*>(&rhs));
1356 typedef detail::tuple_object function_;
1358 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1359 MACRO(object, object) \
1360 MACRO(object, detail::proxy_object) \
1361 MACRO(object, detail::proxy_array_object) \
1362 MACRO(object, detail::proxy_raw_object) \
1363 MACRO(detail::proxy_object, object) \
1364 MACRO(detail::proxy_object, detail::proxy_object) \
1365 MACRO(detail::proxy_object, detail::proxy_array_object) \
1366 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1367 MACRO(detail::proxy_array_object, object) \
1368 MACRO(detail::proxy_array_object, detail::proxy_object) \
1369 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1370 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1371 MACRO(detail::proxy_raw_object, object) \
1372 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1373 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1374 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1377 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1378 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1379 #undef LUABIND_EQUALITY_OPERATOR
1381 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1382 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1383 #undef LUABIND_LESSTHAN_OPERATOR
1385 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1386 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1387 #undef LUABIND_LESSOREQUAL_OPERATOR
1389 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1390 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1392 return !(rhs == lhs); \
1395 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1397 #undef LUABIND_INEQUALITY_OPERATOR
1399 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1400 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1402 return !(rhs < lhs); \
1405 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1407 #undef LUABIND_GREATEROREQUAL_OPERATOR
1409 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1410 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1412 return !(lhs <= rhs); \
1415 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1416 #undef LUABIND_GREATERTHAN_OPERATOR
1418 #undef LUABIND_DECLARE_OPERATOR
1422 namespace std
1425 #define LUABIND_DEFINE_SWAP(t1,t2)\
1426 inline void swap(t1 lhs, t2 rhs)\
1428 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1429 rhs.pushvalue();\
1430 lhs.pushvalue();\
1431 rhs.set();\
1432 lhs.set();\
1435 inline void swap(luabind::object& lhs, luabind::object& rhs)
1437 lhs.swap(rhs);
1440 // object against all other
1441 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1442 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1443 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1444 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1445 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1446 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1448 // proxy_object against all other
1449 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1450 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1451 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1452 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1453 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1455 // proxy_raw_object against all other
1456 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1457 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1458 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1460 // proxy_array_object against all other
1461 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1463 #undef LUABIND_DEFINE_SWAP
1465 } // std
1467 #endif // LUABIND_OBJECT_HPP_INCLUDED
1469 #elif BOOST_PP_ITERATION_FLAGS() == 1
1471 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1472 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1474 #if BOOST_PP_ITERATION() > 0
1475 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1476 #endif
1477 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1478 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1480 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1481 #if BOOST_PP_ITERATION() == 0
1482 tuple_t args;
1483 #else
1484 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1485 #endif
1486 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1489 #undef LUABIND_OPERATOR_PARAMS
1490 #undef LUABIND_TUPLE_PARAMS
1492 #endif