cleanup
[luabind.git] / luabind / object.hpp
blob54e17d093911150d5382dd6d8dc0f4fe72579578
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>
34 #include <luabind/detail/stack_utils.hpp>
36 #include <boost/preprocessor/repeat.hpp>
37 #include <boost/preprocessor/iteration/iterate.hpp>
38 #include <boost/preprocessor/repetition/enum.hpp>
39 #include <boost/preprocessor/repetition/enum_params.hpp>
40 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
41 #include <boost/tuple/tuple.hpp>
43 namespace luabind
45 class object;
47 namespace detail
49 class proxy_object;
50 class proxy_raw_object;
51 class proxy_array_object;
53 template<class T>
54 void convert_to_lua(lua_State*, const T&);
56 template<int Index, class T, class Policies>
57 void convert_to_lua_p(lua_State*, const T&, const Policies&);
59 template<int Index>
60 struct push_args_from_tuple
62 template<class H, class T, class Policies>
63 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
65 convert_to_lua_p<Index>(L, *x.get_head(), p);
66 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
69 template<class H, class T>
70 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
72 convert_to_lua(L, *x.get_head());
73 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
76 template<class Policies>
77 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
79 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
83 template<class Tuple>
84 class proxy_caller
86 friend class luabind::object;
87 public:
89 proxy_caller(luabind::object* o, const Tuple args)
90 : m_obj(o)
91 , m_args(args)
92 , m_called(false)
96 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
97 : m_obj(rhs.m_obj)
98 , m_args(rhs.m_args)
99 , m_called(rhs.m_called)
101 rhs.m_called = true;
104 ~proxy_caller();
105 operator luabind::object();
107 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
108 #define LUABIND_SEMICOLON
109 #else
110 #define LUABIND_SEMICOLON ;
111 #endif
113 template<class Policies>
114 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
115 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
117 m_called = true;
118 lua_State* L = m_obj->lua_state();
119 m_obj->pushvalue();
120 detail::push_args_from_tuple<1>::apply(L, m_args, p);
121 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
123 #ifndef LUABIND_NO_EXCEPTIONS
124 throw error(L);
125 #else
126 error_callback_fun e = get_error_callback();
127 if (e) e(L);
129 assert(0 && "the lua function threw an error and exceptions are disabled."
130 "if you want to handle this error use luabind::set_error_callback()");
131 std::terminate();
132 #endif
134 detail::lua_reference ref;
135 ref.set(L);
136 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
138 #endif
141 #undef LUABIND_SEMICOLON
142 private:
144 luabind::object* m_obj;
145 Tuple m_args;
146 mutable bool m_called;
151 class LUABIND_API proxy_object
153 friend class luabind::object;
154 friend class luabind::detail::proxy_array_object;
155 friend class luabind::detail::proxy_raw_object;
156 // template<class T> friend T object_cast(const proxy_object& obj);
157 public:
159 template<class T>
160 proxy_object& operator=(const T& val)
162 //std::cout << "proxy assigment\n";
163 lua_State* L = m_obj->m_state;
164 m_obj->pushvalue();
165 m_key.get(L);
166 detail::convert_to_lua(L, val);
167 lua_settable(L, -3);
168 // pop table
169 lua_pop(L, 1);
170 return *this;
173 template<class T, class Policies>
174 void assign(const T& val, const Policies& p)
176 //std::cout << "proxy assigment\n";
177 lua_State* L = m_obj->m_state;
178 m_obj->pushvalue();
179 detail::getref(L, m_key_ref);
180 detail::convert_to_lua_p(L, val, p);
181 lua_settable(L, -3);
182 // pop table
183 lua_pop(L, 1);
184 return *this;
187 template<class T>
188 detail::proxy_object operator[](const T& key) const;
190 proxy_object& operator=(const object& p);
191 proxy_object& operator=(const proxy_object& p);
192 proxy_object& operator=(const proxy_raw_object& p);
193 proxy_object& operator=(const proxy_array_object& p);
195 void swap(const proxy_object& rhs);
196 proxy_object* operator->()
197 { return this; }
199 operator luabind::object();
201 int type() const
203 pushvalue();
204 detail::stack_pop p(lua_state(), 1);
205 return lua_type(lua_state(), -1);
208 #define LUABIND_PROXY_RAW_AT_BODY \
210 lua_State* L = lua_state();\
211 pushvalue();\
212 detail::convert_to_lua(L, key);\
213 lua_rawget(L, -2);\
214 detail::lua_reference ref;\
215 ref.set(L);\
216 lua_pop(L, 1);\
217 return object(L, ref, true);\
220 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
221 template<class T>
222 inline object raw_at(const T& key)
223 LUABIND_PROXY_RAW_AT_BODY
224 #else
225 template<class T>
226 inline object raw_at(const T& key);
227 #endif
229 #define LUABIND_PROXY_AT_BODY \
231 lua_State* L = lua_state();\
232 pushvalue();\
233 detail::convert_to_lua(L, key);\
234 lua_gettable(L, -2);\
235 detail::lua_reference ref;\
236 ref.set(L);\
237 lua_pop(L, 1);\
238 return object(L, ref, true);\
241 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
242 template<class T>
243 inline object at(const T& key)
244 LUABIND_PROXY_AT_BODY
245 #else
246 template<class T>
247 inline object at(const T& key);
248 #endif
250 inline bool is_valid() const { return true; }
251 lua_State* lua_state() const;
252 void pushvalue() const;
253 void set() const;
255 // this is a safe substitute for an implicit converter to bool
256 typedef void (proxy_object::*member_ptr)() const;
257 operator member_ptr() const
259 if (is_valid()) return &proxy_object::dummy;
260 return 0;
263 private:
265 void dummy() const {}
267 proxy_object(luabind::object* o, const lua_reference& key)
268 : m_obj(o)
269 , m_key(key)
273 luabind::object* m_obj;
274 detail::lua_reference m_key;
279 class LUABIND_API proxy_raw_object
281 friend class luabind::object;
282 friend class luabind::detail::proxy_array_object;
283 friend class luabind::detail::proxy_object;
284 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
285 public:
287 template<class T>
288 proxy_raw_object& operator=(const T& val)
290 //std::cout << "proxy assigment\n";
291 lua_State* L = m_obj->m_state;
292 m_obj->pushvalue();
293 detail::getref(L, m_key_ref);
294 detail::convert_to_lua(L, val);
295 lua_rawset(L, -3);
296 // pop table
297 lua_pop(L, 1);
298 return *this;
301 template<class T, class Policies>
302 void assign(const T& val, const Policies& p)
304 //std::cout << "proxy assigment\n";
305 lua_State* L = m_obj->m_state;
306 m_obj->pushvalue();
307 detail::getref(L, m_key_ref);
308 detail::convert_to_lua_p(L, val, p);
309 lua_settable(L, -3);
310 // pop table
311 lua_pop(L, 1);
312 return *this;
315 proxy_raw_object& operator=(const object& p);
316 proxy_raw_object& operator=(const proxy_object& p);
317 proxy_raw_object& operator=(const proxy_raw_object& p);
318 proxy_raw_object& operator=(const proxy_array_object& p);
319 void swap(const proxy_raw_object& rhs);
320 proxy_raw_object* operator->()
321 { return this; }
323 operator luabind::object();
325 int type() const
327 pushvalue();
328 detail::stack_pop p(lua_state(), 1);
329 return lua_type(lua_state(), -1);
332 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
333 template<class T>
334 inline object raw_at(const T& key)
335 LUABIND_PROXY_RAW_AT_BODY
336 #else
337 template<class T>
338 inline object raw_at(const T& key);
339 #endif
341 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
342 template<class T>
343 inline object at(const T& key)
344 LUABIND_PROXY_AT_BODY
345 #else
346 template<class T>
347 inline object at(const T& key);
348 #endif
350 inline bool is_valid() const { return true; }
351 lua_State* lua_state() const;
352 void pushvalue() const;
353 void set() const;
355 // this is a safe substitute for an implicit converter to bool
356 typedef void (proxy_raw_object::*member_ptr)() const;
357 operator member_ptr() const
359 if (is_valid()) return &proxy_raw_object::dummy;
360 return 0;
364 private:
366 void dummy() const {}
368 proxy_raw_object(luabind::object* o, const lua_reference& key)
369 : m_obj(o)
370 , m_key(key)
374 luabind::object* m_obj;
375 detail::lua_reference m_key;
380 class LUABIND_API proxy_array_object
382 friend class luabind::object;
383 friend class luabind::detail::proxy_object;
384 friend class luabind::detail::proxy_raw_object;
385 // template<class T> friend T object_cast(const proxy_array_object& obj);
386 public:
388 template<class T>
389 proxy_array_object& operator=(const T& val)
391 //std::cout << "array proxy assigment\n";
392 lua_State* L = m_obj->m_state;
393 m_obj->pushvalue();
394 detail::convert_to_lua(L, val);
395 lua_rawseti(L, -2, m_key);
397 // pops the table
398 lua_pop(L, 1);
399 return *this;
402 template<class T, class Policies>
403 void assign(const T& val, const Policies& p)
405 //std::cout << "proxy assigment\n";
406 lua_State* L = m_obj->m_state;
407 m_obj->pushvalue();
408 detail::convert_to_lua_p(L, val, p);
409 lua_rawseti(L, -2, m_key);
410 // pop table
411 lua_pop(L, 1);
412 return *this;
415 proxy_array_object& operator=(const object& p);
416 proxy_array_object& operator=(const proxy_object& p);
417 proxy_array_object& operator=(const proxy_raw_object& p);
418 proxy_array_object& operator=(const proxy_array_object& p);
419 void swap(const proxy_array_object& rhs);
421 proxy_array_object* operator->()
422 { return this; }
423 operator luabind::object();
425 int type() const
427 pushvalue();
428 detail::stack_pop p(lua_state(), 1);
429 return lua_type(lua_state(), -1);
432 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
434 pushvalue();\
435 detail::convert_to_lua(m_state, key);\
436 lua_rawget(m_state, -2);\
437 lua_reference ref;\
438 ref.set(m_state);\
439 lua_pop(m_state, 1);\
440 return object(m_state, ref, true);\
443 #define LUABIND_PROXY_ARRAY_AT_BODY\
445 pushvalue();\
446 detail::convert_to_lua(m_state, key);\
447 lua_gettable(m_state, -2);\
448 lua_reference ref;\
449 ref.set(m_state);\
450 lua_pop(m_state, 1);\
451 return object(m_state, ref, true);\
454 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
455 template<class T>
456 inline object at(const T& key)
457 LUABIND_PROXY_ARRAY_AT_BODY
458 #else
459 template<class T>
460 inline object at(const T& key);
461 #endif
464 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
465 template<class T>
466 inline object raw_at(const T& key)
467 LUABIND_PROXY_ARRAY_RAW_AT_BODY
468 #else
469 template<class T>
470 inline object raw_at(const T& key);
471 #endif
473 inline bool is_valid() const { return true; }
474 lua_State* lua_state() const;
475 void pushvalue() const;
476 void set() const;
478 // this is a safe substitute for an implicit converter to bool
479 typedef void (proxy_array_object::*member_ptr)() const;
480 operator member_ptr() const
482 if (is_valid()) return &proxy_array_object::dummy;
483 return 0;
486 private:
488 void dummy() const {}
490 proxy_array_object(luabind::object* o, int key)
491 : m_obj(o)
492 , m_key(key)
494 luabind::object* m_obj;
495 int m_key;
498 template<class T>
499 struct primitive_converter;
501 struct tuple_object_ref;
503 } // detail
505 class LUABIND_API object
508 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
510 template<class T>
511 friend T object_cast(const object& obj);
512 template<class T>
513 friend struct detail::primitive_converter;
515 #endif
517 friend object get_globals(lua_State*);
518 friend object get_registry(lua_State*);
519 friend object newtable(lua_State*);
520 friend class detail::proxy_object;
521 friend class detail::proxy_array_object;
522 friend class detail::proxy_raw_object;
524 public:
526 class array_iterator
528 friend class object;
529 public:
531 typedef std::forward_iterator_tag iterator_category;
532 typedef luabind::object value_type;
533 typedef value_type& reference;
534 typedef value_type* pointer;
535 typedef void difference_type;
537 array_iterator()
538 : m_obj(0)
539 , m_key(0)
543 array_iterator(const array_iterator& iter)
544 : m_obj(iter.m_obj)
545 , m_key(iter.m_key)
549 ~array_iterator() {}
551 array_iterator& operator=(const array_iterator& rhs)
553 m_obj = rhs.m_obj;
554 m_key = rhs.m_key;
555 return *this;
558 detail::proxy_array_object operator*()
560 return m_obj->make_array_proxy(m_key);
563 detail::proxy_array_object operator->()
565 return m_obj->make_array_proxy(m_key);
568 inline array_iterator& operator++()
570 LUABIND_CHECK_STACK(m_obj->lua_state());
572 m_key++;
574 // invalidate the iterator if we hit a nil element
575 lua_State* L = m_obj->lua_state();
576 m_obj->pushvalue();
577 lua_rawgeti(L, -1, m_key);
578 if (lua_isnil(L, -1)) m_key = -1;
579 lua_pop(L, 2);
581 return *this;
584 inline array_iterator operator++(int)
586 LUABIND_CHECK_STACK(m_obj->lua_state());
588 int old_key = m_key;
589 m_key++;
591 // invalidate the iterator if we hit a nil element
592 lua_State* L = m_obj->lua_state();
593 m_obj->pushvalue();
594 lua_rawgeti(L, -1, m_key);
595 if (lua_isnil(L, -1)) m_key = -1;
596 lua_pop(L, 2);
598 return array_iterator(m_obj, old_key);
601 bool operator!=(const array_iterator& rhs) const
603 return m_obj != rhs.m_obj || m_key != rhs.m_key;
606 bool operator==(const array_iterator& rhs) const
608 return !(*this != rhs);
611 private:
613 array_iterator(object* obj, int key)
614 : m_obj(obj)
615 , m_key(key)
619 object* m_obj;
620 int m_key;
628 class iterator
630 friend class object;
631 public:
633 typedef std::forward_iterator_tag iterator_category;
634 typedef luabind::object value_type;
635 typedef value_type& reference;
636 typedef value_type* pointer;
637 typedef void difference_type;
639 iterator()
640 : m_obj(0)
644 iterator(const iterator& iter)
645 : m_obj(iter.m_obj)
647 if (m_obj)
649 m_key = iter.m_key;
653 iterator& operator=(const iterator& rhs)
655 m_obj = rhs.m_obj;
656 if (m_obj)
658 m_key = rhs.m_key;
660 else
662 m_key.reset();
664 return *this;
667 detail::proxy_object operator*()
669 return m_obj->make_proxy(m_key);
672 detail::proxy_object operator->()
674 return m_obj->make_proxy(m_key);
677 iterator& operator++()
679 lua_State* L = m_obj->lua_state();
680 LUABIND_CHECK_STACK(L);
682 m_obj->pushvalue();
683 m_key.get(L);
685 if (lua_next(L, -2) != 0)
687 lua_pop(L, 1);
688 m_key.replace(L);
689 lua_pop(L, 1);
691 else
693 lua_pop(L, 1);
694 m_obj = 0;
695 m_key.reset();
698 return *this;
701 bool operator!=(const iterator& rhs) const
703 if (m_obj != rhs.m_obj) return true;
704 if (m_obj == 0) return false;
705 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
706 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
708 // TODO: fix this. add a real equality test of the keys
709 return true;
712 bool operator==(const iterator& rhs) const
714 return !(*this != rhs);
717 object key() const;
719 private:
721 iterator(luabind::object* obj, detail::lua_reference const& key)
722 : m_obj(obj)
723 , m_key(key)
727 object* m_obj;
728 detail::lua_reference m_key;
734 class raw_iterator
736 friend class object;
737 public:
739 typedef std::forward_iterator_tag iterator_category;
740 typedef luabind::object value_type;
741 typedef value_type& reference;
742 typedef value_type* pointer;
743 typedef void difference_type;
745 raw_iterator()
746 : m_obj(0)
750 raw_iterator(const raw_iterator& iter)
751 : m_obj(iter.m_obj)
752 , m_key()
754 if (m_obj)
756 m_key = iter.m_key;
760 raw_iterator& operator=(const raw_iterator& rhs)
762 //std::cout << "===\n";
763 m_obj = rhs.m_obj;
764 if (m_obj)
766 m_key = rhs.m_key;
768 else
770 m_key.reset();
772 return *this;
775 detail::proxy_raw_object operator*()
777 return m_obj->make_raw_proxy(m_key);
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 bool operator==(const raw_iterator& rhs) const
822 return !(*this != rhs);
825 private:
827 raw_iterator(object* obj, detail::lua_reference const& key)
828 : m_obj(obj)
829 , m_key(key)
832 object* m_obj;
833 detail::lua_reference m_key;
841 object()
842 : m_state(0)
846 explicit object(lua_State* L)
847 : m_state(L)
851 template<class T>
852 object(lua_State* L, const T& val)
853 : m_state(L)
855 *this = val;
858 object(const object& o)
859 : m_state(o.m_state)
861 o.m_ref.get(m_state);
862 m_ref.set(m_state);
865 inline ~object()
868 inline bool is_valid() const { return m_ref.is_valid(); }
870 // this is a safe substitute for an implicit converter to bool
871 typedef void (object::*member_ptr)() const;
872 operator member_ptr() const
874 if (is_valid()) return &object::dummy;
875 return 0;
878 int type() const
880 pushvalue();
881 detail::stack_pop p(lua_state(), 1);
882 return lua_type(lua_state(), -1);
885 inline iterator begin() const
887 LUABIND_CHECK_STACK(m_state);
889 m_ref.get(m_state);
890 lua_pushnil(m_state);
891 detail::stack_pop pop(m_state, 1);
892 if (lua_next(m_state, -2) == 0)
893 return end();
894 lua_pop(m_state, 1);
895 detail::lua_reference r;
896 r.set(m_state);
897 iterator i(const_cast<object*>(this), r);
898 return i;
901 inline iterator end() const
903 return iterator(0, detail::lua_reference());
906 inline array_iterator abegin() const
908 return array_iterator(const_cast<object*>(this), 1);
911 inline array_iterator aend() const
913 return array_iterator(const_cast<object*>(this), -1);
916 raw_iterator raw_begin() const
918 m_ref.get(m_state);
919 lua_pushnil(m_state);
920 detail::stack_pop pop(m_state, 1);
921 if (lua_next(m_state, -2) == 0)
922 return raw_end();
923 lua_pop(m_state, 1);
924 detail::lua_reference r;
925 r.set(m_state);
926 raw_iterator i(const_cast<object*>(this), r);
927 return i;
930 raw_iterator raw_end() const
932 return raw_iterator(0, detail::lua_reference());
935 inline void set() const
937 // you are trying to access an invalid object
938 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
940 allocate_slot();
941 m_ref.replace(m_state);
943 inline lua_State* lua_state() const { return m_state; }
944 inline void pushvalue() const
946 // you are trying to dereference an invalid object
947 assert((m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
948 assert((m_state != 0) && "internal error, please report");
949 m_ref.get(m_state);
952 void swap(object& rhs);
954 template<class T>
955 inline object raw_at(const T& key)
957 lua_State* L = lua_state();
958 pushvalue();
959 detail::convert_to_lua(L, key);
960 lua_rawget(L, -2);
961 detail::lua_reference ref;
962 ref.set(L);
963 lua_pop(L, 1);
964 return object(L, ref, true);
967 template<class T>
968 inline object at(const T& key)
970 LUABIND_CHECK_STACK(m_state);
972 lua_State* L = lua_state();
973 pushvalue();
974 detail::convert_to_lua(L, key);
975 lua_gettable(L, -2);
976 detail::lua_reference ref;
977 ref.set(L);
978 lua_pop(L, 1);
979 return object(L, ref, true);
982 template<class T>
983 inline detail::proxy_object operator[](const T& key) const
985 LUABIND_CHECK_STACK(m_state);
987 detail::convert_to_lua(m_state, key);
988 detail::lua_reference ref;
989 ref.set(m_state);
990 return detail::proxy_object(const_cast<object*>(this), ref);
995 // *****************************
996 // OPERATOR =
998 template<class T>
999 object& operator=(const T& val) const
1001 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1002 // you cannot assign a non-lua value to an uninitialized object
1004 detail::convert_to_lua(m_state, val);
1005 set();
1006 return const_cast<luabind::object&>(*this);
1009 object& operator=(const object& o) const;
1010 object& operator=(const detail::proxy_object& o) const;
1011 object& operator=(const detail::proxy_raw_object& o) const;
1012 object& operator=(const detail::proxy_array_object& o) const;
1014 template<class T, class Policies>
1015 void assign(const T& val, const Policies& p) const
1017 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1018 // you cannot assign a non-lua value to an uninitialized object
1020 detail::convert_to_lua_p(m_state, val, p);
1021 set();
1024 // const overload should return a tuple_object..?
1025 inline detail::tuple_object_ref operator,(const object& rhs) const;
1027 // *****************************
1028 // OPERATOR()
1030 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1031 #include BOOST_PP_ITERATE()
1035 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1037 return detail::proxy_object(this, key);
1040 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1042 return detail::proxy_raw_object(this, key);
1045 inline detail::proxy_array_object make_array_proxy(int key)
1047 return detail::proxy_array_object(this, key);
1050 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1051 // it's an inner class), that's why this interface is public
1052 // private:
1054 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1055 : m_state(L)
1056 , m_ref(ref)
1060 private:
1062 void dummy() const {}
1064 void allocate_slot() const
1066 if (!m_ref.is_valid())
1068 lua_pushboolean(m_state, 0);
1069 m_ref.set(m_state);
1073 mutable lua_State* m_state;
1074 mutable detail::lua_reference m_ref;
1078 // *************************************
1079 // OBJECT
1081 inline void object::swap(object& rhs)
1083 // you cannot swap objects from different lua states
1084 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1085 m_ref.swap(rhs.m_ref);
1088 inline object object::iterator::key() const
1090 lua_State* L = m_obj->lua_state();
1091 return object(L, m_key, true);
1094 inline object object::raw_iterator::key() const
1096 lua_State* L = m_obj->lua_state();
1097 return object(L, m_key, true);
1100 namespace detail
1102 // tuple object ----------------------------------------------
1104 struct tuple_object;
1106 struct tuple_object_ref
1108 tuple_object_ref(object* a, object* b)
1109 : n(2)
1110 { refs[0] = a; refs[1] = b; }
1112 tuple_object_ref& operator,(const object& x)
1113 { refs[n++] = const_cast<object*>(&x); return *this; }
1115 struct assign_into
1117 assign_into() {}
1119 template<class T>
1120 assign_into(tuple_object_ref& to, const T& val)
1121 : target(&to)
1122 , n(0)
1124 if (n >= target->n) return;
1125 *target->refs[n++] = val;
1128 template<class T>
1129 assign_into& operator,(const T& val)
1131 if (n >= target->n) return *this;
1132 *target->refs[n++] = val;
1133 return *this;
1136 tuple_object_ref* target;
1137 std::size_t n;
1140 template<class T>
1141 assign_into operator=(const T& val)
1142 { return assign_into(*this, val); }
1144 tuple_object_ref(const tuple_object_ref&);
1145 assign_into operator=(const tuple_object_ref& x)
1147 for (std::size_t i = 0; i < n && i < x.n; ++i)
1148 *refs[i] = *x.refs[i];
1149 return assign_into();
1152 inline assign_into operator=(const tuple_object&);
1154 std::size_t n;
1155 object* refs[10];
1158 struct tuple_object
1160 tuple_object(const object& x)
1161 : n(0)
1162 { objs[n++] = x; }
1164 tuple_object(const tuple_object_ref& x)
1166 for (std::size_t i = 0; i < x.n; ++i)
1167 objs[i] = *x.refs[i];
1170 std::size_t n;
1171 object objs[10];
1174 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1176 for (std::size_t i = 0; i < n && i < x.n; ++i)
1177 *refs[i] = x.objs[i];
1178 return assign_into();
1181 // *************************************
1182 // PROXY CALLER
1184 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1185 template<class Tuple>
1186 template<class Policies>
1187 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1189 m_called = true;
1190 lua_State* L = m_obj->lua_state();
1191 m_obj->pushvalue();
1192 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1193 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1195 #ifndef LUABIND_NO_EXCEPTIONS
1196 throw error(L);
1197 #else
1198 error_callback_fun e = get_error_callback();
1199 if (e) e(L);
1201 assert(0 && "the lua function threw an error and exceptions are disabled."
1202 "if you want to handle this error use luabind::set_error_callback()");
1203 std::terminate();
1204 #endif
1206 detail::lua_reference ref;
1207 ref.set(L);
1208 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1210 #endif
1211 // *************************************
1212 // PROXY OBJECT
1214 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1215 template<class T>
1216 inline object proxy_object::raw_at(const T& key)
1217 LUABIND_PROXY_RAW_AT_BODY
1219 template<class T>
1220 inline object proxy_object::at(const T& key)
1221 LUABIND_PROXY_AT_BODY
1222 #endif
1224 inline lua_State* proxy_object::lua_state() const
1226 return m_obj->lua_state();
1229 inline proxy_object::operator luabind::object()
1231 lua_State* L = m_obj->lua_state();
1232 pushvalue();
1233 detail::lua_reference ref;
1234 ref.set(L);
1235 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1239 // *************************************
1240 // PROXY ARRAY OBJECT
1242 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1243 template<class T>
1244 inline object proxy_array_object::raw_at(const T& key)
1245 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1247 template<class T>
1248 inline object proxy_array_object::at(const T& key)
1249 LUABIND_PROXY_ARRAY_AT_BODY
1250 #endif
1252 #undef LUABIND_PROXY_ARRAY_AT_BODY
1253 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1255 inline lua_State* proxy_array_object::lua_state() const
1257 return m_obj->lua_state();
1260 inline proxy_array_object::operator luabind::object()
1262 lua_State* L = m_obj->lua_state();
1263 pushvalue();
1264 detail::lua_reference ref;
1265 ref.set(L);
1266 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1270 // *************************************
1271 // PROXY RAW OBJECT
1273 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1274 template<class T>
1275 inline object proxy_raw_object::raw_at(const T& key)
1276 LUABIND_PROXY_RAW_AT_BODY
1278 template<class T>
1279 inline object proxy_raw_object::at(const T& key)
1280 LUABIND_PROXY_AT_BODY
1281 #endif
1283 #undef LUABIND_PROXY_RAW_AT_BODY
1284 #undef LUABIND_PROXY_AT_BODY
1286 inline lua_State* proxy_raw_object::lua_state() const
1288 return m_obj->lua_state();
1291 inline proxy_raw_object::operator luabind::object()
1293 lua_State* L = lua_state();
1294 pushvalue();
1295 detail::lua_reference ref;
1296 ref.set(L);
1297 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1301 // *************************************
1302 // PROXY CALLER
1305 template<class Tuple>
1306 proxy_caller<Tuple>::~proxy_caller()
1308 if (m_called) return;
1310 m_called = true;
1311 lua_State* L = m_obj->lua_state();
1312 m_obj->pushvalue();
1314 push_args_from_tuple<1>::apply(L, m_args);
1315 if (pcall(L, boost::tuples::length<Tuple>::value, 0))
1317 #ifndef LUABIND_NO_EXCEPTIONS
1318 throw luabind::error(L);
1319 #else
1320 error_callback_fun e = get_error_callback();
1321 if (e) e(L);
1323 assert(0 && "the lua function threw an error and exceptions are disabled."
1324 "if you want to handle this error use luabind::set_error_callback()");
1325 std::terminate();
1326 #endif
1330 template<class Tuple>
1331 proxy_caller<Tuple>::operator luabind::object()
1333 m_called = true;
1334 lua_State* L = m_obj->lua_state();
1335 m_obj->pushvalue();
1337 push_args_from_tuple<1>::apply(L, m_args);
1338 if (pcall(L, boost::tuples::length<Tuple>::value, 1))
1340 #ifndef LUABIND_NO_EXCEPTIONS
1341 throw luabind::error(L);
1342 #else
1343 error_callback_fun e = get_error_callback();
1344 if (e) e(L);
1346 assert(0 && "the lua function threw an error and exceptions are disabled."
1347 "if you want to handle this error use luabind::set_error_callback()");
1348 std::terminate();
1349 #endif
1351 detail::lua_reference ref;
1352 ref.set(L);
1353 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1358 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1360 return detail::tuple_object_ref(
1361 const_cast<object*>(this), const_cast<object*>(&rhs));
1364 typedef detail::tuple_object function_;
1366 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1367 MACRO(object, object) \
1368 MACRO(object, detail::proxy_object) \
1369 MACRO(object, detail::proxy_array_object) \
1370 MACRO(object, detail::proxy_raw_object) \
1371 MACRO(detail::proxy_object, object) \
1372 MACRO(detail::proxy_object, detail::proxy_object) \
1373 MACRO(detail::proxy_object, detail::proxy_array_object) \
1374 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1375 MACRO(detail::proxy_array_object, object) \
1376 MACRO(detail::proxy_array_object, detail::proxy_object) \
1377 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1378 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1379 MACRO(detail::proxy_raw_object, object) \
1380 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1381 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1382 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1385 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1386 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1387 #undef LUABIND_EQUALITY_OPERATOR
1389 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1390 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1391 #undef LUABIND_LESSTHAN_OPERATOR
1393 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1394 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1395 #undef LUABIND_LESSOREQUAL_OPERATOR
1397 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1398 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1400 return !(rhs == lhs); \
1403 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1405 #undef LUABIND_INEQUALITY_OPERATOR
1407 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1408 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1410 return !(rhs < lhs); \
1413 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1415 #undef LUABIND_GREATEROREQUAL_OPERATOR
1417 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1418 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1420 return !(lhs <= rhs); \
1423 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1424 #undef LUABIND_GREATERTHAN_OPERATOR
1426 #undef LUABIND_DECLARE_OPERATOR
1430 namespace std
1433 #define LUABIND_DEFINE_SWAP(t1,t2)\
1434 inline void swap(t1 lhs, t2 rhs)\
1436 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1437 rhs.pushvalue();\
1438 lhs.pushvalue();\
1439 rhs.set();\
1440 lhs.set();\
1443 inline void swap(luabind::object& lhs, luabind::object& rhs)
1445 lhs.swap(rhs);
1448 // object against all other
1449 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1450 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1451 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1452 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1453 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1454 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1456 // proxy_object against all other
1457 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1458 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1459 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1460 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1461 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1463 // proxy_raw_object against all other
1464 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1465 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1466 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1468 // proxy_array_object against all other
1469 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1471 #undef LUABIND_DEFINE_SWAP
1473 } // std
1475 #endif // LUABIND_OBJECT_HPP_INCLUDED
1477 #elif BOOST_PP_ITERATION_FLAGS() == 1
1479 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1480 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1482 #if BOOST_PP_ITERATION() > 0
1483 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1484 #endif
1485 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1486 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1488 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1489 #if BOOST_PP_ITERATION() == 0
1490 tuple_t args;
1491 #else
1492 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1493 #endif
1494 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1497 #undef LUABIND_OPERATOR_PARAMS
1498 #undef LUABIND_TUPLE_PARAMS
1500 #endif