*** empty log message ***
[luabind.git] / luabind / object.hpp
bloba2eabcb46e0fb6783616fb80313ed212c0cd313b
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
23 #if !BOOST_PP_IS_ITERATING
25 #ifndef LUABIND_OBJECT_HPP_INCLUDED
26 #define LUABIND_OBJECT_HPP_INCLUDED
28 #include <iterator>
30 #include <luabind/config.hpp>
31 #include <luabind/detail/error.hpp>
33 #include <boost/preprocessor/repeat.hpp>
34 #include <boost/preprocessor/iteration/iterate.hpp>
35 #include <boost/preprocessor/repetition/enum.hpp>
36 #include <boost/preprocessor/repetition/enum_params.hpp>
37 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
38 #include <boost/tuple/tuple.hpp>
40 namespace luabind
42 class object;
44 namespace detail
46 class proxy_object;
47 class proxy_raw_object;
48 class proxy_array_object;
50 template<class T>
51 void convert_to_lua(lua_State*, const T&);
53 template<int Index, class T, class Policies>
54 void convert_to_lua_p(lua_State*, const T&, const Policies&);
56 template<int Index>
57 struct push_args_from_tuple
59 template<class H, class T, class Policies>
60 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
62 convert_to_lua_p<Index>(L, *x.get_head(), p);
63 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
66 template<class H, class T>
67 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
69 convert_to_lua(L, *x.get_head());
70 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
73 template<class Policies>
74 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
76 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
80 template<class Tuple>
81 class proxy_caller
83 friend class luabind::object;
84 public:
86 proxy_caller(luabind::object* o, const Tuple args)
87 : m_obj(o)
88 , m_args(args)
89 , m_called(false)
93 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
94 : m_obj(rhs.m_obj)
95 , m_args(rhs.m_args)
96 , m_called(rhs.m_called)
98 rhs.m_called = true;
101 ~proxy_caller();
102 operator luabind::object();
104 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
105 #define LUABIND_SEMICOLON
106 #else
107 #define LUABIND_SEMICOLON ;
108 #endif
110 template<class Policies>
111 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
112 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
114 m_called = true;
115 lua_State* L = m_obj->lua_state();
116 m_obj->pushvalue();
117 detail::push_args_from_tuple<1>::apply(L, m_args, p);
118 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
120 #ifndef LUABIND_NO_EXCEPTIONS
121 throw error(L);
122 #else
123 error_callback_fun e = detail::error_callback::get().err;
124 if (e) e(L);
126 assert(0 && "the lua function threw an error and exceptions are disabled."
127 "if you want to handle this error use luabind::set_error_callback()");
128 std::terminate();
129 #endif
131 detail::lua_reference ref;
132 ref.set(L);
133 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
135 #endif
138 #undef LUABIND_SEMICOLON
139 private:
141 luabind::object* m_obj;
142 Tuple m_args;
143 mutable bool m_called;
149 struct stack_pop
151 stack_pop(lua_State* L, int n)
152 : m_state(L)
153 , m_n(n)
157 ~stack_pop()
159 lua_pop(m_state, m_n);
162 private:
164 lua_State* m_state;
165 int m_n;
172 class LUABIND_API proxy_object
174 friend class luabind::object;
175 friend class luabind::detail::proxy_array_object;
176 friend class luabind::detail::proxy_raw_object;
177 // template<class T> friend T object_cast(const proxy_object& obj);
178 public:
180 template<class T>
181 proxy_object& operator=(const T& val)
183 //std::cout << "proxy assigment\n";
184 lua_State* L = m_obj->m_state;
185 m_obj->pushvalue();
186 m_key.get(L);
187 detail::convert_to_lua(L, val);
188 lua_settable(L, -3);
189 // pop table
190 lua_pop(L, 1);
191 return *this;
194 template<class T, class Policies>
195 void assign(const T& val, const Policies& p)
197 //std::cout << "proxy assigment\n";
198 lua_State* L = m_obj->m_state;
199 m_obj->pushvalue();
200 detail::getref(L, m_key_ref);
201 detail::convert_to_lua_p(L, val, p);
202 lua_settable(L, -3);
203 // pop table
204 lua_pop(L, 1);
205 return *this;
208 proxy_object& operator=(const object& p);
209 proxy_object& operator=(const proxy_object& p);
210 proxy_object& operator=(const proxy_raw_object& p);
211 proxy_object& operator=(const proxy_array_object& p);
213 void swap(const proxy_object& rhs);
215 operator luabind::object();
217 int type() const
219 pushvalue();
220 detail::stack_pop p(lua_state(), 1);
221 return lua_type(lua_state(), -1);
224 #define LUABIND_PROXY_RAW_AT_BODY \
226 lua_State* L = lua_state();\
227 pushvalue();\
228 detail::convert_to_lua(L, key);\
229 lua_rawget(L, -2);\
230 detail::lua_reference ref;\
231 ref.set(L);\
232 lua_pop(L, 1);\
233 return object(L, ref, true);\
236 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
237 template<class T>
238 inline object raw_at(const T& key)
239 LUABIND_PROXY_RAW_AT_BODY
240 #else
241 template<class T>
242 inline object raw_at(const T& key);
243 #endif
245 #define LUABIND_PROXY_AT_BODY \
247 lua_State* L = lua_state();\
248 pushvalue();\
249 detail::convert_to_lua(L, key);\
250 lua_gettable(L, -2);\
251 detail::lua_reference ref;\
252 ref.set(L);\
253 lua_pop(L, 1);\
254 return object(L, ref, true);\
257 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
258 template<class T>
259 inline object at(const T& key)
260 LUABIND_PROXY_AT_BODY
261 #else
262 template<class T>
263 inline object at(const T& key);
264 #endif
266 inline bool is_valid() const { return true; }
267 lua_State* lua_state() const;
268 void pushvalue() const;
269 void set() const;
271 // this is a safe substitute for an implicit converter to bool
272 typedef void (proxy_object::*member_ptr)() const;
273 operator member_ptr() const
275 if (is_valid()) return &proxy_object::dummy;
276 return 0;
279 private:
281 void dummy() const {}
283 proxy_object(luabind::object* o, const lua_reference& key)
284 : m_obj(o)
285 , m_key(key)
289 luabind::object* m_obj;
290 detail::lua_reference m_key;
295 class LUABIND_API proxy_raw_object
297 friend class luabind::object;
298 friend class luabind::detail::proxy_array_object;
299 friend class luabind::detail::proxy_object;
300 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
301 public:
303 template<class T>
304 proxy_raw_object& operator=(const T& val)
306 //std::cout << "proxy assigment\n";
307 lua_State* L = m_obj->m_state;
308 m_obj->pushvalue();
309 detail::getref(L, m_key_ref);
310 detail::convert_to_lua(L, val);
311 lua_rawset(L, -3);
312 // pop table
313 lua_pop(L, 1);
314 return *this;
317 template<class T, class Policies>
318 void assign(const T& val, const Policies& p)
320 //std::cout << "proxy assigment\n";
321 lua_State* L = m_obj->m_state;
322 m_obj->pushvalue();
323 detail::getref(L, m_key_ref);
324 detail::convert_to_lua_p(L, val, p);
325 lua_settable(L, -3);
326 // pop table
327 lua_pop(L, 1);
328 return *this;
331 proxy_raw_object& operator=(const object& p);
332 proxy_raw_object& operator=(const proxy_object& p);
333 proxy_raw_object& operator=(const proxy_raw_object& p);
334 proxy_raw_object& operator=(const proxy_array_object& p);
335 void swap(const proxy_raw_object& rhs);
337 operator luabind::object();
339 int type() const
341 pushvalue();
342 detail::stack_pop p(lua_state(), 1);
343 return lua_type(lua_state(), -1);
346 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
347 template<class T>
348 inline object raw_at(const T& key)
349 LUABIND_PROXY_RAW_AT_BODY
350 #else
351 template<class T>
352 inline object raw_at(const T& key);
353 #endif
355 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
356 template<class T>
357 inline object at(const T& key)
358 LUABIND_PROXY_AT_BODY
359 #else
360 template<class T>
361 inline object at(const T& key);
362 #endif
364 inline bool is_valid() const { return true; }
365 lua_State* lua_state() const;
366 void pushvalue() const;
367 void set() const;
369 // this is a safe substitute for an implicit converter to bool
370 typedef void (proxy_raw_object::*member_ptr)() const;
371 operator member_ptr() const
373 if (is_valid()) return &proxy_raw_object::dummy;
374 return 0;
378 private:
380 void dummy() const {}
382 proxy_raw_object(luabind::object* o, const lua_reference& key)
383 : m_obj(o)
384 , m_key(key)
388 luabind::object* m_obj;
389 detail::lua_reference m_key;
394 class LUABIND_API proxy_array_object
396 friend class luabind::object;
397 friend class luabind::detail::proxy_object;
398 friend class luabind::detail::proxy_raw_object;
399 // template<class T> friend T object_cast(const proxy_array_object& obj);
400 public:
402 template<class T>
403 proxy_array_object& operator=(const T& val)
405 //std::cout << "array proxy assigment\n";
406 lua_State* L = m_obj->m_state;
407 m_obj->pushvalue();
408 detail::convert_to_lua(L, val);
409 lua_rawseti(L, -2, m_key);
411 // pops the table
412 lua_pop(L, 1);
413 return *this;
416 template<class T, class Policies>
417 void assign(const T& val, const Policies& p)
419 //std::cout << "proxy assigment\n";
420 lua_State* L = m_obj->m_state;
421 m_obj->pushvalue();
422 detail::convert_to_lua_p(L, val, p);
423 lua_rawseti(L, -2, m_key);
424 // pop table
425 lua_pop(L, 1);
426 return *this;
429 proxy_array_object& operator=(const object& p);
430 proxy_array_object& operator=(const proxy_object& p);
431 proxy_array_object& operator=(const proxy_raw_object& p);
432 proxy_array_object& operator=(const proxy_array_object& p);
433 void swap(const proxy_array_object& rhs);
435 operator luabind::object();
437 int type() const
439 pushvalue();
440 detail::stack_pop p(lua_state(), 1);
441 return lua_type(lua_state(), -1);
444 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY\
446 pushvalue();\
447 detail::convert_to_lua(m_state, key);\
448 lua_rawget(m_state, -2);\
449 lua_reference ref;\
450 ref.set(m_state);\
451 lua_pop(m_state, 1);\
452 return object(m_state, ref, true);\
455 #define LUABIND_PROXY_ARRAY_AT_BODY\
457 pushvalue();\
458 detail::convert_to_lua(m_state, key);\
459 lua_gettable(m_state, -2);\
460 lua_reference ref;\
461 ref.set(m_state);\
462 lua_pop(m_state, 1);\
463 return object(m_state, ref, true);\
466 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
467 template<class T>
468 inline object at(const T& key)
469 LUABIND_PROXY_ARRAY_AT_BODY
470 #else
471 template<class T>
472 inline object at(const T& key);
473 #endif
476 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
477 template<class T>
478 inline object raw_at(const T& key)
479 LUABIND_PROXY_ARRAY_RAW_AT_BODY
480 #else
481 template<class T>
482 inline object raw_at(const T& key);
483 #endif
485 template<class T>
486 inline detail::proxy_object operator[](const T& key) const
488 detail::convert_to_lua(m_state, key);
489 lua_reference ref;\
490 ref.set(m_state);\
491 return detail::proxy_object(const_cast<object*>(this), ref);
494 inline bool is_valid() const { return true; }
495 lua_State* lua_state() const;
496 void pushvalue() const;
497 void set() const;
499 // this is a safe substitute for an implicit converter to bool
500 typedef void (proxy_array_object::*member_ptr)() const;
501 operator member_ptr() const
503 if (is_valid()) return &proxy_array_object::dummy;
504 return 0;
507 private:
509 void dummy() const {}
511 proxy_array_object(luabind::object* o, int key)
512 : m_obj(o)
513 , m_key(key)
515 luabind::object* m_obj;
516 int m_key;
519 template<class T>
520 struct primitive_converter;
522 struct tuple_object_ref;
524 } // detail
526 class LUABIND_API object
529 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
531 template<class T>
532 friend T object_cast(const object& obj);
533 template<class T>
534 friend struct detail::primitive_converter;
536 #endif
538 friend object get_globals(lua_State*);
539 friend object get_registry(lua_State*);
540 friend object newtable(lua_State*);
541 friend class detail::proxy_object;
542 friend class detail::proxy_array_object;
543 friend class detail::proxy_raw_object;
545 public:
547 class array_iterator
549 friend class object;
550 public:
552 typedef std::forward_iterator_tag iterator_category;
553 typedef luabind::object value_type;
554 typedef value_type& reference;
555 typedef value_type* pointer;
556 typedef void difference_type;
558 array_iterator()
559 : m_obj(0)
560 , m_key(0)
564 array_iterator(const array_iterator& iter)
565 : m_obj(iter.m_obj)
566 , m_key(iter.m_key)
570 ~array_iterator() {}
572 array_iterator& operator=(const array_iterator& rhs)
574 m_obj = rhs.m_obj;
575 m_key = rhs.m_key;
576 return *this;
579 detail::proxy_array_object operator*()
581 return m_obj->make_array_proxy(m_key);
584 inline array_iterator& operator++()
586 m_key++;
588 // invalidate the iterator if we hit a nil element
589 lua_State* L = m_obj->lua_state();
590 m_obj->pushvalue();
591 lua_rawgeti(L, -1, m_key);
592 if (lua_isnil(L, -1)) m_key = -1;
593 lua_pop(L, 1);
595 return *this;
598 inline array_iterator operator++(int)
600 int old_key = m_key;
601 m_key++;
603 // invalidate the iterator if we hit a nil element
604 lua_State* L = m_obj->lua_state();
605 m_obj->pushvalue();
606 lua_rawgeti(L, -1, m_key);
607 if (lua_isnil(L, -1)) m_key = -1;
608 lua_pop(L, 1);
610 return array_iterator(m_obj, old_key);
613 bool operator!=(const array_iterator& rhs) const
615 return m_obj != rhs.m_obj || m_key != rhs.m_key;
618 private:
620 array_iterator(object* obj, int key)
621 : m_obj(obj)
622 , m_key(key)
626 object* m_obj;
627 int m_key;
635 class iterator
637 friend class object;
638 public:
640 typedef std::forward_iterator_tag iterator_category;
641 typedef luabind::object value_type;
642 typedef value_type& reference;
643 typedef value_type* pointer;
644 typedef void difference_type;
646 iterator()
647 : m_obj(0)
651 iterator(const iterator& iter)
652 : m_obj(iter.m_obj)
654 if (m_obj)
656 m_key = iter.m_key;
660 iterator& operator=(const iterator& rhs)
662 m_obj = rhs.m_obj;
663 if (m_obj)
665 m_key = rhs.m_key;
667 else
669 m_key.reset();
671 return *this;
674 detail::proxy_object operator*()
676 return m_obj->make_proxy(m_key);
679 iterator& operator++()
681 lua_State* L = m_obj->lua_state();
683 int n = lua_gettop(L);
685 m_obj->pushvalue();
686 m_key.get(L);
688 if (lua_next(L, -2) != 0)
690 lua_pop(L, 1);
691 m_key.replace(L);
692 lua_pop(L, 1);
694 else
696 lua_pop(L, 1);
697 m_obj = 0;
698 m_key.reset();
701 assert(n == lua_gettop(L));
702 return *this;
705 bool operator!=(const iterator& rhs) const
707 if (m_obj != rhs.m_obj) return true;
708 if (m_obj == 0) return false;
709 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
710 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
712 // TODO: fix this. add a real equality test of the keys
713 return true;
716 object key() const;
718 private:
720 iterator(luabind::object* obj, detail::lua_reference const& key)
721 : m_obj(obj)
722 , m_key(key)
726 object* m_obj;
727 detail::lua_reference m_key;
733 class raw_iterator
735 friend class object;
736 public:
738 typedef std::forward_iterator_tag iterator_category;
739 typedef luabind::object value_type;
740 typedef value_type& reference;
741 typedef value_type* pointer;
742 typedef void difference_type;
744 raw_iterator()
745 : m_obj(0)
749 raw_iterator(const raw_iterator& iter)
750 : m_obj(iter.m_obj)
751 , m_key()
753 if (m_obj)
755 m_key = iter.m_key;
759 raw_iterator& operator=(const raw_iterator& rhs)
761 //std::cout << "===\n";
762 m_obj = rhs.m_obj;
763 if (m_obj)
765 m_key = rhs.m_key;
767 else
769 m_key.reset();
771 return *this;
774 detail::proxy_raw_object operator*()
776 return m_obj->make_raw_proxy(m_key);
779 raw_iterator& operator++()
781 lua_State* L = m_obj->lua_state();
782 m_obj->pushvalue();
783 m_key.get(L);
785 if (lua_next(L, -2) != 0)
787 lua_pop(L, 1);
788 m_key.replace(L);
789 lua_pop(L, 1);
791 else
793 lua_pop(L, 1);
794 m_key.reset();
795 m_obj = 0;
798 return *this;
801 object key() const;
803 bool operator!=(const raw_iterator& rhs) const
805 if (m_obj != rhs.m_obj) return true;
806 if (m_obj == 0) return false;
807 if (m_obj->lua_state() != rhs.m_obj->lua_state()) return true;
808 if (m_key.is_valid() != rhs.m_key.is_valid()) return true;
810 // TODO: fix this. add a real equality test of the keys
811 return true;
814 private:
816 raw_iterator(object* obj, detail::lua_reference const& key)
817 : m_obj(obj)
818 , m_key(key)
821 object* m_obj;
822 detail::lua_reference m_key;
830 object()
831 : m_state(0)
835 explicit object(lua_State* L)
836 : m_state(L)
840 template<class T>
841 object(lua_State* L, const T& val)
842 : m_state(L)
844 *this = val;
847 object(const object& o)
848 : m_state(o.m_state)
850 o.m_ref.get(m_state);
851 m_ref.set(m_state);
854 inline ~object()
857 inline bool is_valid() const { return m_ref.is_valid(); }
859 // this is a safe substitute for an implicit converter to bool
860 typedef void (object::*member_ptr)() const;
861 operator member_ptr() const
863 if (is_valid()) return &object::dummy;
864 return 0;
867 int type() const
869 pushvalue();
870 detail::stack_pop p(lua_state(), 1);
871 return lua_type(lua_state(), -1);
874 inline iterator begin() const
876 m_ref.get(m_state);
877 lua_pushnil(m_state);
878 lua_next(m_state, -2);
879 lua_pop(m_state, 1);
880 detail::lua_reference r;
881 r.set(m_state);
882 iterator i(const_cast<object*>(this), r);
883 lua_pop(m_state, 1);
884 return i;
887 inline iterator end() const
889 return iterator(0, detail::lua_reference());
892 inline array_iterator abegin() const
894 return array_iterator(const_cast<object*>(this), 1);
897 inline array_iterator aend() const
899 return array_iterator(const_cast<object*>(this), -1);
902 raw_iterator raw_begin() const
904 m_ref.get(m_state);
905 lua_pushnil(m_state);
906 lua_next(m_state, -2);
907 lua_pop(m_state, 1);
908 detail::lua_reference r;
909 r.set(m_state);
910 raw_iterator i(const_cast<object*>(this), r);
911 lua_pop(m_state, 1);
912 return i;
915 raw_iterator raw_end() const
917 return raw_iterator(0, detail::lua_reference());
920 inline void set() const
922 // you are trying to access an invalid object
923 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
925 allocate_slot();
926 m_ref.replace(m_state);
928 inline lua_State* lua_state() const { return m_state; }
929 inline void pushvalue() const
931 // you are trying to dereference an invalid object
932 assert((m_ref.is_valid()) && "you are trying to access an invalid (uninitialized) object");
933 assert((m_state != 0) && "internal error, please report");
935 m_ref.get(m_state);
938 void swap(object& rhs);
940 template<class T>
941 inline object raw_at(const T& key)
943 lua_State* L = lua_state();
944 pushvalue();
945 detail::convert_to_lua(L, key);
946 lua_rawget(L, -2);
947 detail::lua_reference ref;
948 ref.set(L);
949 lua_pop(L, 1);
950 return object(L, ref, true);
953 template<class T>
954 inline object at(const T& key)
956 lua_State* L = lua_state();
957 pushvalue();
958 detail::convert_to_lua(L, key);
959 lua_gettable(L, -2);
960 detail::lua_reference ref;
961 ref.set(L);
962 lua_pop(L, 1);
963 return object(L, ref, true);
966 template<class T>
967 inline detail::proxy_object operator[](const T& key) const
969 detail::convert_to_lua(m_state, key);
970 detail::lua_reference ref;
971 ref.set(m_state);
972 return detail::proxy_object(const_cast<object*>(this), ref);
977 // *****************************
978 // OPERATOR =
980 template<class T>
981 object& operator=(const T& val) const
983 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
984 // you cannot assign a non-lua value to an uninitialized object
986 detail::convert_to_lua(m_state, val);
987 set();
988 return const_cast<luabind::object&>(*this);
991 object& operator=(const object& o) const;
992 object& operator=(const detail::proxy_object& o) const;
993 object& operator=(const detail::proxy_raw_object& o) const;
994 object& operator=(const detail::proxy_array_object& o) const;
996 template<class T, class Policies>
997 void assign(const T& val, const Policies& p) const
999 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1000 // you cannot assign a non-lua value to an uninitialized object
1002 detail::convert_to_lua_p(m_state, val, p);
1003 set();
1006 // const overload should return a tuple_object..?
1007 inline detail::tuple_object_ref operator,(const object& rhs) const;
1009 // *****************************
1010 // OPERATOR()
1012 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1013 #include BOOST_PP_ITERATE()
1017 inline detail::proxy_object make_proxy(detail::lua_reference const& key)
1019 return detail::proxy_object(this, key);
1022 inline detail::proxy_raw_object make_raw_proxy(detail::lua_reference const& key)
1024 return detail::proxy_raw_object(this, key);
1027 inline detail::proxy_array_object make_array_proxy(int key)
1029 return detail::proxy_array_object(this, key);
1032 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1033 // it's an inner class), that's why this interface is public
1034 // private:
1036 object(lua_State* L, detail::lua_reference const& ref, bool/*, reference*/)
1037 : m_state(L)
1038 , m_ref(ref)
1042 private:
1044 void dummy() const {}
1046 void allocate_slot() const
1048 if (!m_ref.is_valid())
1050 lua_pushboolean(m_state, 0);
1051 m_ref.set(m_state);
1055 mutable lua_State* m_state;
1056 mutable detail::lua_reference m_ref;
1060 // *************************************
1061 // OBJECT
1063 inline void object::swap(object& rhs)
1065 // you cannot swap objects from different lua states
1066 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1067 m_ref.swap(rhs.m_ref);
1070 inline object object::iterator::key() const
1072 lua_State* L = m_obj->lua_state();
1073 return object(L, m_key, true);
1076 inline object object::raw_iterator::key() const
1078 lua_State* L = m_obj->lua_state();
1079 return object(L, m_key, true);
1082 namespace detail
1084 // tuple object ----------------------------------------------
1086 struct tuple_object;
1088 struct tuple_object_ref
1090 tuple_object_ref(object* a, object* b)
1091 : n(2)
1092 { refs[0] = a; refs[1] = b; }
1094 tuple_object_ref& operator,(const object& x)
1095 { refs[n++] = const_cast<object*>(&x); return *this; }
1097 struct assign_into
1099 assign_into() {}
1101 template<class T>
1102 assign_into(tuple_object_ref& to, const T& val)
1103 : target(&to)
1104 , n(0)
1106 if (n >= target->n) return;
1107 *target->refs[n++] = val;
1110 template<class T>
1111 assign_into& operator,(const T& val)
1113 if (n >= target->n) return *this;
1114 *target->refs[n++] = val;
1115 return *this;
1118 tuple_object_ref* target;
1119 std::size_t n;
1122 template<class T>
1123 assign_into operator=(const T& val)
1124 { return assign_into(*this, val); }
1126 tuple_object_ref(const tuple_object_ref&);
1127 assign_into operator=(const tuple_object_ref& x)
1129 for (std::size_t i = 0; i < n && i < x.n; ++i)
1130 *refs[i] = *x.refs[i];
1131 return assign_into();
1134 inline assign_into operator=(const tuple_object&);
1136 std::size_t n;
1137 object* refs[10];
1140 struct tuple_object
1142 tuple_object(const object& x)
1143 : n(0)
1144 { objs[n++] = x; }
1146 tuple_object(const tuple_object_ref& x)
1148 for (std::size_t i = 0; i < x.n; ++i)
1149 objs[i] = *x.refs[i];
1152 std::size_t n;
1153 object objs[10];
1156 inline tuple_object_ref::assign_into tuple_object_ref::operator=(const tuple_object& x)
1158 for (std::size_t i = 0; i < n && i < x.n; ++i)
1159 *refs[i] = x.objs[i];
1160 return assign_into();
1163 // *************************************
1164 // PROXY CALLER
1166 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1167 template<class Tuple>
1168 template<class Policies>
1169 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1171 m_called = true;
1172 lua_State* L = m_obj->lua_state();
1173 m_obj->pushvalue();
1174 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1175 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1177 #ifndef LUABIND_NO_EXCEPTIONS
1178 throw error(L);
1179 #else
1180 error_callback_fun e = detail::error_callback::get().err;
1181 if (e) e(L);
1183 assert(0 && "the lua function threw an error and exceptions are disabled."
1184 "if you want to handle this error use luabind::set_error_callback()");
1185 std::terminate();
1186 #endif
1188 detail::lua_reference ref;
1189 ref.set(L);
1190 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1192 #endif
1193 // *************************************
1194 // PROXY OBJECT
1196 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1197 template<class T>
1198 inline object proxy_object::raw_at(const T& key)
1199 LUABIND_PROXY_RAW_AT_BODY
1201 template<class T>
1202 inline object proxy_object::at(const T& key)
1203 LUABIND_PROXY_AT_BODY
1204 #endif
1206 inline lua_State* proxy_object::lua_state() const
1208 return m_obj->lua_state();
1211 inline proxy_object::operator luabind::object()
1213 lua_State* L = m_obj->lua_state();
1214 pushvalue();
1215 detail::lua_reference ref;
1216 ref.set(L);
1217 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1221 // *************************************
1222 // PROXY ARRAY OBJECT
1224 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1225 template<class T>
1226 inline object proxy_array_object::raw_at(const T& key)
1227 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1229 template<class T>
1230 inline object proxy_array_object::at(const T& key)
1231 LUABIND_PROXY_ARRAY_AT_BODY
1232 #endif
1234 #undef LUABIND_PROXY_ARRAY_AT_BODY
1235 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1237 inline lua_State* proxy_array_object::lua_state() const
1239 return m_obj->lua_state();
1242 inline proxy_array_object::operator luabind::object()
1244 lua_State* L = m_obj->lua_state();
1245 pushvalue();
1246 detail::lua_reference ref;
1247 ref.set(L);
1248 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1252 // *************************************
1253 // PROXY RAW OBJECT
1255 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1256 template<class T>
1257 inline object proxy_raw_object::raw_at(const T& key)
1258 LUABIND_PROXY_RAW_AT_BODY
1260 template<class T>
1261 inline object proxy_raw_object::at(const T& key)
1262 LUABIND_PROXY_AT_BODY
1263 #endif
1265 #undef LUABIND_PROXY_RAW_AT_BODY
1266 #undef LUABIND_PROXY_AT_BODY
1268 inline lua_State* proxy_raw_object::lua_state() const
1270 return m_obj->lua_state();
1273 inline proxy_raw_object::operator luabind::object()
1275 lua_State* L = lua_state();
1276 pushvalue();
1277 detail::lua_reference ref;
1278 ref.set(L);
1279 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1283 // *************************************
1284 // PROXY CALLER
1287 template<class Tuple>
1288 proxy_caller<Tuple>::~proxy_caller()
1290 if (m_called) return;
1292 m_called = true;
1293 lua_State* L = m_obj->lua_state();
1294 m_obj->pushvalue();
1296 push_args_from_tuple<1>::apply(L, m_args);
1297 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1299 #ifndef LUABIND_NO_EXCEPTIONS
1300 throw luabind::error(L);
1301 #else
1302 error_callback_fun e = detail::error_callback::get().err;
1303 if (e) e(L);
1305 assert(0 && "the lua function threw an error and exceptions are disabled."
1306 "if you want to handle this error use luabind::set_error_callback()");
1307 std::terminate();
1308 #endif
1312 template<class Tuple>
1313 proxy_caller<Tuple>::operator luabind::object()
1315 m_called = true;
1316 lua_State* L = m_obj->lua_state();
1317 m_obj->pushvalue();
1319 push_args_from_tuple<1>::apply(L, m_args);
1320 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1322 #ifndef LUABIND_NO_EXCEPTIONS
1323 throw luabind::error(L);
1324 #else
1325 error_callback_fun e = detail::error_callback::get().err;
1326 if (e) e(L);
1328 assert(0 && "the lua function threw an error and exceptions are disabled."
1329 "if you want to handle this error use luabind::set_error_callback()");
1330 std::terminate();
1331 #endif
1333 detail::lua_reference ref;
1334 ref.set(L);
1335 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1340 inline detail::tuple_object_ref object::operator,(const object& rhs) const
1342 return detail::tuple_object_ref(
1343 const_cast<object*>(this), const_cast<object*>(&rhs));
1346 typedef detail::tuple_object function_;
1348 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1349 MACRO(object, object) \
1350 MACRO(object, detail::proxy_object) \
1351 MACRO(object, detail::proxy_array_object) \
1352 MACRO(object, detail::proxy_raw_object) \
1353 MACRO(detail::proxy_object, object) \
1354 MACRO(detail::proxy_object, detail::proxy_object) \
1355 MACRO(detail::proxy_object, detail::proxy_array_object) \
1356 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1357 MACRO(detail::proxy_array_object, object) \
1358 MACRO(detail::proxy_array_object, detail::proxy_object) \
1359 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1360 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1361 MACRO(detail::proxy_raw_object, object) \
1362 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1363 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1364 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1367 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) LUABIND_API bool operator==(const lhs&, const rhs&);
1368 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1369 #undef LUABIND_EQUALITY_OPERATOR
1371 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) LUABIND_API bool operator<(const lhs&, const rhs&);
1372 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1373 #undef LUABIND_LESSTHAN_OPERATOR
1375 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) LUABIND_API bool operator<=(const lhs_t&, const rhs_t&);
1376 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1377 #undef LUABIND_LESSOREQUAL_OPERATOR
1379 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1380 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1382 return !(rhs == lhs); \
1385 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1387 #undef LUABIND_INEQUALITY_OPERATOR
1389 #define LUABIND_GREATEROREQUAL_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_GREATEROREQUAL_OPERATOR)
1397 #undef LUABIND_GREATEROREQUAL_OPERATOR
1399 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1400 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1402 return !(lhs <= rhs); \
1405 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1406 #undef LUABIND_GREATERTHAN_OPERATOR
1408 #undef LUABIND_DECLARE_OPERATOR
1412 namespace std
1415 #define LUABIND_DEFINE_SWAP(t1,t2)\
1416 inline void swap(t1 lhs, t2 rhs)\
1418 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1419 rhs.pushvalue();\
1420 lhs.pushvalue();\
1421 rhs.set();\
1422 lhs.set();\
1425 inline void swap(luabind::object& lhs, luabind::object& rhs)
1427 lhs.swap(rhs);
1430 // object against all other
1431 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1432 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1433 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1434 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1435 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1436 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1438 // proxy_object against all other
1439 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1440 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1441 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1442 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1443 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1445 // proxy_raw_object against all other
1446 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1447 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1448 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1450 // proxy_array_object against all other
1451 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1453 #undef LUABIND_DEFINE_SWAP
1455 } // std
1457 #endif // LUABIND_OBJECT_HPP_INCLUDED
1459 #elif BOOST_PP_ITERATION_FLAGS() == 1
1461 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1462 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1464 #if BOOST_PP_ITERATION() > 0
1465 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1466 #endif
1467 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1468 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1470 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1471 #if BOOST_PP_ITERATION() == 0
1472 tuple_t args;
1473 #else
1474 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1475 #endif
1476 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1479 #undef LUABIND_OPERATOR_PARAMS
1480 #undef LUABIND_TUPLE_PARAMS
1482 #endif