*** empty log message ***
[luabind.git] / luabind / object.hpp
blobc37d77a9f9e55fc86c8c72933d0ed6171525c838
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 // below are some considerations that haven't been implemented
45 // object might need to be able to store values temporarily
46 // without knowing about a lua_State.
48 // globals["f"] = function(&f);
50 // Creates the need for this, since function() doesn't know
51 // about the state and thus can't return a fully initialized
52 // object.
54 // Current solution is to allow for objects to store a pointer
55 // to a commiter-object. This object has a virtual method which
56 // converts it's value to the lua_State.
58 // This has some serious issues. For example, how would
59 // two 'pseude-initialized' objects be able to compare?
61 // Perhaps attempting to perform operations on non-intialised
62 // objects could throw?
63 //
64 // Perhaps we could perform some not-so-smart comparisions? like:
66 // template<class T>
67 // struct commiter : base_commiter
68 // {
69 // commiter(const T& v): val(v), base_commiter(typeid(T)) {}
71 // virtual bool compare(void* rhs)
72 // {
73 // T* other = static_cast<T*>(rhs);
74 // return val == *other;
75 // }
77 // T val;
78 // };
80 // This would at least allow for the most intuitive use.. like:
82 // object a = 5;
83 // object b = 5;
85 // return a == b;
87 // However, comparing an initialized object with a non-initialized
88 // would always return false. Is this ok? Better to disallow it?
90 // the current implementation does not have commiters, all objects
91 // knows about the lua_State* or is uninitialized.
93 class object;
95 namespace detail
97 class proxy_object;
98 class proxy_raw_object;
99 class proxy_array_object;
101 template<class T>
102 void convert_to_lua(lua_State*, const T&);
104 template<int Index, class T, class Policies>
105 void convert_to_lua_p(lua_State*, const T&, const Policies&);
107 template<int Index>
108 struct push_args_from_tuple
110 template<class H, class T, class Policies>
111 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
113 convert_to_lua_p<Index>(L, *x.get_head(), p);
114 push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
117 template<class H, class T>
118 inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
120 convert_to_lua(L, *x.get_head());
121 push_args_from_tuple<Index+1>::apply(L, x.get_tail());
124 template<class Policies>
125 inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {};
127 inline static void apply(lua_State*, const boost::tuples::null_type&) {};
131 template<class Tuple>
132 class proxy_caller
134 friend class luabind::object;
135 public:
137 proxy_caller(luabind::object* o, const Tuple args)
138 : m_obj(o)
139 , m_args(args)
140 , m_called(false)
144 proxy_caller(const detail::proxy_caller<Tuple>& rhs)
145 : m_obj(rhs.m_obj)
146 , m_args(rhs.m_args)
147 , m_called(rhs.m_called)
149 rhs.m_called = true;
152 ~proxy_caller();
153 operator luabind::object();
155 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
156 #define LUABIND_SEMICOLON
157 #else
158 #define LUABIND_SEMICOLON ;
159 #endif
161 template<class Policies>
162 luabind::object operator[](const Policies& p) LUABIND_SEMICOLON
163 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
165 m_called = true;
166 lua_State* L = m_obj->lua_state();
167 m_obj->pushvalue();
168 detail::push_args_from_tuple<1>::apply(L, m_args, p);
169 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
171 #ifndef LUABIND_NO_EXCEPTIONS
172 throw error(L);
173 #else
174 error_callback_fun e = detail::error_callback::get().err;
175 if (e) e(L);
177 assert(0 && "the lua function threw an error and exceptions are disabled."
178 "if you want to handle this error use luabind::set_error_callback()");
179 std::terminate();
180 #endif
182 int ref = detail::ref(L);
183 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
185 #endif
188 #undef LUABIND_SEMICOLON
189 private:
191 luabind::object* m_obj;
192 Tuple m_args;
193 mutable bool m_called;
199 struct stack_pop
201 stack_pop(lua_State* L, int n)
202 : m_state(L)
203 , m_n(n)
207 ~stack_pop()
209 lua_pop(m_state, m_n);
212 private:
214 lua_State* m_state;
215 int m_n;
222 class proxy_object
224 friend class luabind::object;
225 friend class luabind::detail::proxy_array_object;
226 friend class luabind::detail::proxy_raw_object;
227 // template<class T> friend T object_cast(const proxy_object& obj);
228 public:
230 template<class T>
231 proxy_object& operator=(const T& val)
233 //std::cout << "proxy assigment\n";
234 lua_State* L = m_obj->m_state;
235 m_obj->pushvalue();
236 detail::getref(L, m_key_ref);
237 detail::convert_to_lua(L, val);
238 lua_settable(L, -3);
239 // pop table
240 lua_pop(L, 1);
241 return *this;
244 proxy_object& operator=(const object& p);
245 proxy_object& operator=(const proxy_object& p);
246 proxy_object& operator=(const proxy_raw_object& p);
247 proxy_object& operator=(const proxy_array_object& p);
249 void swap(const proxy_object& rhs);
251 operator luabind::object();
253 int type() const
255 pushvalue();
256 detail::stack_pop p(lua_state(), 1);
257 return lua_type(lua_state(), -1);
260 #define LUABIND_PROXY_RAW_AT_BODY \
262 lua_State* L = lua_state(); \
263 pushvalue(); \
264 detail::convert_to_lua(L, key); \
265 lua_rawget(L, -2); \
266 int ref = detail::ref(L); \
267 lua_pop(L, 1); \
268 return object(L, ref, true); \
271 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
272 template<class T>
273 inline object raw_at(const T& key)
274 LUABIND_PROXY_RAW_AT_BODY
275 #else
276 template<class T>
277 inline object raw_at(const T& key);
278 #endif
280 #define LUABIND_PROXY_AT_BODY \
282 lua_State* L = lua_state(); \
283 pushvalue(); \
284 detail::convert_to_lua(L, key); \
285 lua_gettable(L, -2); \
286 int ref = detail::ref(L); \
287 lua_pop(L, 1); \
288 return object(L, ref, true); \
291 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
292 template<class T>
293 inline object at(const T& key)
294 LUABIND_PROXY_AT_BODY
295 #else
296 template<class T>
297 inline object at(const T& key);
298 #endif
300 inline bool is_valid() const { return true; }
301 lua_State* lua_state() const;
302 void pushvalue() const;
303 void set() const;
305 // this is a safe substitute for an implicit converter to bool
306 typedef void (proxy_object::*member_ptr)() const;
307 operator member_ptr() const
309 if (is_valid()) return &proxy_object::dummy;
310 return 0;
313 private:
315 void dummy() const {}
317 proxy_object(luabind::object* o, int key)
318 : m_obj(o)
319 , m_key_ref(key)
323 luabind::object* m_obj;
324 int m_key_ref;
329 class proxy_raw_object
331 friend class luabind::object;
332 friend class luabind::detail::proxy_array_object;
333 friend class luabind::detail::proxy_object;
334 // template<class T> friend T luabind::object_cast(const proxy_object& obj);
335 public:
337 template<class T>
338 proxy_raw_object& operator=(const T& val)
340 //std::cout << "proxy assigment\n";
341 lua_State* L = m_obj->m_state;
342 m_obj->pushvalue();
343 detail::getref(L, m_key_ref);
344 detail::convert_to_lua(L, val);
345 lua_rawset(L, -3);
346 // pop table
347 lua_pop(L, 1);
348 return *this;
351 proxy_raw_object& operator=(const object& p);
352 proxy_raw_object& operator=(const proxy_object& p);
353 proxy_raw_object& operator=(const proxy_raw_object& p);
354 proxy_raw_object& operator=(const proxy_array_object& p);
355 void swap(const proxy_raw_object& rhs);
357 operator luabind::object();
359 int type() const
361 pushvalue();
362 detail::stack_pop p(lua_state(), 1);
363 return lua_type(lua_state(), -1);
366 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
367 template<class T>
368 inline object raw_at(const T& key)
369 LUABIND_PROXY_RAW_AT_BODY
370 #else
371 template<class T>
372 inline object raw_at(const T& key);
373 #endif
375 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
376 template<class T>
377 inline object at(const T& key)
378 LUABIND_PROXY_AT_BODY
379 #else
380 template<class T>
381 inline object at(const T& key);
382 #endif
384 inline bool is_valid() const { return true; }
385 lua_State* lua_state() const;
386 void pushvalue() const;
387 void set() const;
389 // this is a safe substitute for an implicit converter to bool
390 typedef void (proxy_raw_object::*member_ptr)() const;
391 operator member_ptr() const
393 if (is_valid()) return &proxy_raw_object::dummy;
394 return 0;
398 private:
400 void dummy() const {}
402 proxy_raw_object(luabind::object* o, int key)
403 : m_obj(o)
404 , m_key_ref(key)
408 luabind::object* m_obj;
409 int m_key_ref;
414 class proxy_array_object
416 friend class luabind::object;
417 friend class luabind::detail::proxy_object;
418 friend class luabind::detail::proxy_raw_object;
419 // template<class T> friend T object_cast(const proxy_array_object& obj);
420 public:
422 template<class T>
423 proxy_array_object& operator=(const T& val)
425 //std::cout << "array proxy assigment\n";
426 lua_State* L = m_obj->m_state;
427 m_obj->pushvalue();
428 detail::convert_to_lua(L, val);
429 lua_rawseti(L, -2, m_key);
431 // pops the table
432 lua_pop(L, 1);
433 return *this;
436 proxy_array_object& operator=(const object& p);
437 proxy_array_object& operator=(const proxy_object& p);
438 proxy_array_object& operator=(const proxy_raw_object& p);
439 proxy_array_object& operator=(const proxy_array_object& p);
440 void swap(const proxy_array_object& rhs);
442 operator luabind::object();
444 int type() const
446 pushvalue();
447 detail::stack_pop p(lua_state(), 1);
448 return lua_type(lua_state(), -1);
451 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
453 pushvalue(); \
454 detail::convert_to_lua(m_state, key); \
455 lua_rawget(m_state, -2); \
456 int ref = detail::ref(m_state); \
457 lua_pop(m_state, 1); \
458 return object(m_state, ref, true); \
461 #define LUABIND_PROXY_ARRAY_AT_BODY \
463 pushvalue(); \
464 detail::convert_to_lua(m_state, key); \
465 lua_gettable(m_state, -2); \
466 int ref = detail::ref(m_state); \
467 lua_pop(m_state, 1); \
468 return object(m_state, ref, true); \
471 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
472 template<class T>
473 inline object at(const T& key)
474 LUABIND_PROXY_ARRAY_AT_BODY
475 #else
476 template<class T>
477 inline object at(const T& key);
478 #endif
481 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
482 template<class T>
483 inline object raw_at(const T& key)
484 LUABIND_PROXY_ARRAY_RAW_AT_BODY
485 #else
486 template<class T>
487 inline object raw_at(const T& key);
488 #endif
490 template<class T>
491 inline detail::proxy_object operator[](const T& key) const
493 detail::convert_to_lua(m_state, key);
494 int ref = detail::ref(m_state);
495 return detail::proxy_object(const_cast<object*>(this), ref);
498 inline bool is_valid() const { return true; }
499 lua_State* lua_state() const;
500 void pushvalue() const;
501 void set() const;
503 // this is a safe substitute for an implicit converter to bool
504 typedef void (proxy_array_object::*member_ptr)() const;
505 operator member_ptr() const
507 if (is_valid()) return &proxy_array_object::dummy;
508 return 0;
511 private:
513 void dummy() const {}
515 proxy_array_object(luabind::object* o, int key)
516 : m_obj(o)
517 , m_key(key)
520 luabind::object* m_obj;
521 int m_key;
524 template<class T>
525 struct primitive_converter;
527 } // detail
532 class object
535 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
537 template<class T>
538 friend T object_cast(const object& obj);
539 template<class T>
540 friend struct detail::primitive_converter;
542 #endif
544 friend object get_globals(lua_State*);
545 friend object get_registry(lua_State*);
546 friend object newtable(lua_State*);
547 friend class detail::proxy_object;
548 friend class detail::proxy_array_object;
549 friend class detail::proxy_raw_object;
551 public:
553 class array_iterator
555 friend class object;
556 public:
558 typedef std::forward_iterator_tag iterator_category;
559 typedef luabind::object value_type;
560 typedef value_type& reference;
561 typedef value_type* pointer;
562 typedef void difference_type;
564 array_iterator()
565 : m_obj(0)
566 , m_key(LUA_NOREF)
570 array_iterator(const array_iterator& iter)
571 : m_obj(iter.m_obj)
572 , m_key(iter.m_key)
576 ~array_iterator() {}
578 array_iterator& operator=(const array_iterator& rhs)
580 //std::cout << "===\n";
581 m_obj = rhs.m_obj;
582 m_key = rhs.m_key;
583 return *this;
586 detail::proxy_array_object operator*()
588 return m_obj->make_array_proxy(m_key);
591 inline array_iterator& operator++()
593 m_key++;
595 // invalidate the iterator if we hit a nil element
596 lua_State* L = m_obj->lua_state();
597 m_obj->pushvalue();
598 lua_rawgeti(L, -1, m_key);
599 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
600 lua_pop(L, 1);
602 return *this;
605 inline array_iterator operator++(int)
607 int old_key = m_key;
608 m_key++;
610 // invalidate the iterator if we hit a nil element
611 lua_State* L = m_obj->lua_state();
612 m_obj->pushvalue();
613 lua_rawgeti(L, -1, m_key);
614 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
615 lua_pop(L, 1);
617 return array_iterator(m_obj, old_key);
620 bool operator!=(const array_iterator& rhs) const
622 return m_obj != rhs.m_obj || m_key != rhs.m_key;
625 private:
627 array_iterator(object* obj, int key)
628 : m_obj(obj)
629 , m_key(key)
633 object* m_obj;
634 int m_key;
642 class iterator
644 friend class object;
645 public:
647 typedef std::forward_iterator_tag iterator_category;
648 typedef luabind::object value_type;
649 typedef value_type& reference;
650 typedef value_type* pointer;
651 typedef void difference_type;
653 iterator()
654 : m_obj(0)
655 , m_key(LUA_NOREF)
659 iterator(const iterator& iter)
660 : m_obj(iter.m_obj)
661 , m_key(LUA_NOREF)
663 if (m_obj)
665 lua_State* L = m_obj->lua_state();
666 detail::getref(L, iter.m_key);
667 m_key = detail::ref(L);
671 ~iterator()
673 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
676 iterator& operator=(const iterator& rhs)
678 //std::cout << "===\n";
679 m_obj = rhs.m_obj;
680 if (m_obj)
682 lua_State* L = m_obj->lua_state();
683 detail::getref(L, rhs.m_key);
684 m_key = detail::ref(L);
686 else
688 m_key = LUA_NOREF;
690 return *this;
693 detail::proxy_object operator*()
695 return m_obj->make_proxy(m_key);
698 iterator& operator++()
700 lua_State* L = m_obj->lua_state();
701 m_obj->pushvalue();
702 detail::getref(L, m_key);
704 if (lua_next(L, -2) != 0)
706 lua_pop(L, 1);
707 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
708 lua_pop(L, 1);
710 else
712 lua_pop(L, 1);
713 detail::unref(L, m_key);
714 m_obj = 0;
715 m_key = LUA_NOREF;
718 return *this;
721 bool operator!=(const iterator& rhs) const
723 return m_obj != rhs.m_obj || m_key != rhs.m_key;
726 object key() const;
728 private:
730 iterator(object* obj, int key)
731 : m_obj(obj)
732 , m_key(key)
736 object* m_obj;
737 int m_key;
743 class raw_iterator
745 friend class object;
746 public:
748 typedef std::forward_iterator_tag iterator_category;
749 typedef luabind::object value_type;
750 typedef value_type& reference;
751 typedef value_type* pointer;
752 typedef void difference_type;
754 raw_iterator()
755 : m_obj(0)
756 , m_key(LUA_NOREF)
760 raw_iterator(const raw_iterator& iter)
761 : m_obj(iter.m_obj)
762 , m_key(LUA_NOREF)
764 if (m_obj)
766 lua_State* L = m_obj->lua_state();
767 detail::getref(L, iter.m_key);
768 m_key = detail::ref(L);
772 ~raw_iterator()
774 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
777 raw_iterator& operator=(const raw_iterator& rhs)
779 //std::cout << "===\n";
780 m_obj = rhs.m_obj;
781 if (m_obj)
783 lua_State* L = m_obj->lua_state();
784 detail::getref(L, rhs.m_key);
785 m_key = detail::ref(L);
787 else
789 m_key = LUA_NOREF;
791 return *this;
794 detail::proxy_raw_object operator*()
796 return m_obj->make_raw_proxy(m_key);
799 raw_iterator& operator++()
801 lua_State* L = m_obj->lua_state();
802 m_obj->pushvalue();
803 detail::getref(L, m_key);
805 if (lua_next(L, -2) != 0)
807 lua_pop(L, 1);
808 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
809 lua_pop(L, 1);
811 else
813 lua_pop(L, 1);
814 detail::unref(L, m_key);
815 m_obj = 0;
816 m_key = LUA_NOREF;
819 return *this;
822 bool operator!=(const raw_iterator& rhs) const
824 return m_obj != rhs.m_obj || m_key != rhs.m_key;
827 private:
829 raw_iterator(object* obj, int key)
830 : m_obj(obj)
831 , m_key(key)
835 object* m_obj;
836 int m_key;
844 object()
845 : m_state(0)
846 , m_ref(LUA_NOREF)
850 object(lua_State* L)
851 : m_state(L)
852 , m_ref(LUA_NOREF)
856 template<class T>
857 object(lua_State* L, const T& val)
858 : m_state(L)
859 , m_ref(LUA_NOREF)
861 *this = val;
864 object(const object& o)
865 : m_state(o.m_state)
866 , m_ref(LUA_NOREF)
868 lua_getref(m_state, o.m_ref);
869 m_ref = detail::ref(m_state);
872 inline ~object()
874 // If you crash in the detail::unref() call you have probably
875 // closed the lua_State before destructing all object instances.
876 if (m_ref != LUA_NOREF) detail::unref(m_state, m_ref);
879 inline bool is_valid() const { return m_ref != LUA_NOREF; }
881 // this is a safe substitute for an implicit converter to bool
882 typedef void (object::*member_ptr)() const;
883 operator member_ptr() const
885 if (is_valid()) return &object::dummy;
886 return 0;
889 int type() const
891 pushvalue();
892 detail::stack_pop p(lua_state(), 1);
893 return lua_type(lua_state(), -1);
896 inline iterator begin() const
898 lua_getref(m_state, m_ref);
899 lua_pushnil(m_state);
900 lua_next(m_state, -2);
901 lua_pop(m_state, 1);
902 iterator i(const_cast<object*>(this), detail::ref(m_state));
903 lua_pop(m_state, 1);
904 return i;
907 inline iterator end() const
909 return iterator(0, LUA_NOREF);
912 inline array_iterator abegin() const
914 return array_iterator(const_cast<object*>(this), 1);
917 inline array_iterator aend() const
919 return array_iterator(const_cast<object*>(this), LUA_NOREF);
922 raw_iterator raw_begin() const
924 lua_getref(m_state, m_ref);
925 lua_pushnil(m_state);
926 lua_next(m_state, -2);
927 lua_pop(m_state, 1);
928 raw_iterator i(const_cast<object*>(this), detail::ref(m_state));
929 lua_pop(m_state, 1);
930 return i;
933 raw_iterator raw_end() const
935 return raw_iterator(0, LUA_NOREF);
938 inline void set() const
940 // you are trying to access an invalid object
941 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
943 allocate_slot();
944 lua_rawseti(m_state, LUA_REGISTRYINDEX, m_ref);
946 inline lua_State* lua_state() const { return m_state; }
947 inline void pushvalue() const
949 // you are trying to dereference an invalid object
950 assert((m_ref != LUA_NOREF) && "you are trying to access an invalid (uninitialized) object");
951 assert((m_state != 0) && "internal error, please report");
953 lua_getref(m_state, m_ref);
956 void swap(object& rhs);
958 template<class T>
959 inline object raw_at(const T& key)
961 lua_State* L = lua_state();
962 pushvalue();
963 detail::convert_to_lua(L, key);
964 lua_rawget(L, -2);
965 int ref = detail::ref(L);
966 lua_pop(L, 1);
967 return object(L, ref, true);
970 template<class T>
971 inline object at(const T& key)
973 lua_State* L = lua_state();
974 pushvalue();
975 detail::convert_to_lua(L, key);
976 lua_gettable(L, -2);
977 int ref = detail::ref(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 detail::convert_to_lua(m_state, key);
986 int ref = detail::ref(m_state);
987 return detail::proxy_object(const_cast<object*>(this), ref);
992 // *****************************
993 // OPERATOR =
995 object& operator=(const object& o) const;
996 object& operator=(const detail::proxy_object& o) const;
997 object& operator=(const detail::proxy_raw_object& o) const;
998 object& operator=(const detail::proxy_array_object& o) const;
1000 template<class T>
1001 object& operator=(const T& val) const
1003 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1004 // you cannot assign a non-lua value to an uninitialized object
1006 detail::convert_to_lua(m_state, val);
1007 set();
1008 return const_cast<luabind::object&>(*this);
1012 // *****************************
1013 // OPERATOR()
1015 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1016 #include BOOST_PP_ITERATE()
1020 inline detail::proxy_object make_proxy(int key)
1022 return detail::proxy_object(this, key);
1025 inline detail::proxy_raw_object make_raw_proxy(int key)
1027 return detail::proxy_raw_object(this, key);
1030 inline detail::proxy_array_object make_array_proxy(int key)
1032 return detail::proxy_array_object(this, key);
1035 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1036 // it's an inner class), that's why this interface is public
1037 // private:
1039 object(lua_State* L, int ref, bool/*, reference*/)
1040 : m_state(L)
1041 , m_ref(ref)
1045 private:
1047 void dummy() const {}
1049 void allocate_slot() const
1051 if (m_ref == LUA_NOREF)
1053 lua_pushboolean(m_state, 0);
1054 m_ref = detail::ref(m_state);
1058 mutable lua_State* m_state;
1059 mutable int m_ref;
1063 // *************************************
1064 // OBJECT
1066 inline void object::swap(object& rhs)
1068 // you cannot swap objects from different lua states
1069 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1070 std::swap(m_ref, rhs.m_ref);
1073 inline object object::iterator::key() const
1075 lua_State* L = m_obj->lua_state();
1076 detail::getref(L, m_key);
1077 return object(L, detail::ref(L), true);
1080 namespace detail
1083 // *************************************
1084 // PROXY CALLER
1086 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1087 template<class Tuple>
1088 template<class Policies>
1089 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1091 m_called = true;
1092 lua_State* L = m_obj->lua_state();
1093 m_obj->pushvalue();
1094 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1095 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1097 #ifndef LUABIND_NO_EXCEPTIONS
1098 throw error(L);
1099 #else
1100 error_callback_fun e = detail::error_callback::get().err;
1101 if (e) e(L);
1103 assert(0 && "the lua function threw an error and exceptions are disabled."
1104 "if you want to handle this error use luabind::set_error_callback()");
1105 std::terminate();
1106 #endif
1108 int ref = detail::ref(L);
1109 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1111 #endif
1112 // *************************************
1113 // PROXY OBJECT
1115 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1116 template<class T>
1117 inline object proxy_object::raw_at(const T& key)
1118 LUABIND_PROXY_RAW_AT_BODY
1120 template<class T>
1121 inline object proxy_object::at(const T& key)
1122 LUABIND_PROXY_AT_BODY
1123 #endif
1125 inline lua_State* proxy_object::lua_state() const
1127 return m_obj->lua_state();
1130 inline proxy_object::operator luabind::object()
1132 lua_State* L = m_obj->lua_state();
1133 pushvalue();
1134 int ref = detail::ref(L);
1135 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1139 // *************************************
1140 // PROXY ARRAY OBJECT
1142 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1143 template<class T>
1144 inline object proxy_array_object::raw_at(const T& key)
1145 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1147 template<class T>
1148 inline object proxy_array_object::at(const T& key)
1149 LUABIND_PROXY_ARRAY_AT_BODY
1150 #endif
1152 #undef LUABIND_PROXY_ARRAY_AT_BODY
1153 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1155 inline lua_State* proxy_array_object::lua_state() const
1157 return m_obj->lua_state();
1160 inline proxy_array_object::operator luabind::object()
1162 lua_State* L = m_obj->lua_state();
1163 pushvalue();
1164 int ref = detail::ref(L);
1165 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1169 // *************************************
1170 // PROXY RAW OBJECT
1172 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1173 template<class T>
1174 inline object proxy_raw_object::raw_at(const T& key)
1175 LUABIND_PROXY_RAW_AT_BODY
1177 template<class T>
1178 inline object proxy_raw_object::at(const T& key)
1179 LUABIND_PROXY_AT_BODY
1180 #endif
1182 #undef LUABIND_PROXY_RAW_AT_BODY
1183 #undef LUABIND_PROXY_AT_BODY
1185 inline lua_State* proxy_raw_object::lua_state() const
1187 return m_obj->lua_state();
1190 inline proxy_raw_object::operator luabind::object()
1192 lua_State* L = lua_state();
1193 pushvalue();
1194 int ref = detail::ref(L);
1195 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1199 // *************************************
1200 // PROXY CALLER
1203 template<class Tuple>
1204 proxy_caller<Tuple>::~proxy_caller()
1206 if (m_called) return;
1208 m_called = true;
1209 lua_State* L = m_obj->lua_state();
1210 m_obj->pushvalue();
1212 push_args_from_tuple<1>::apply(L, m_args);
1213 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1215 #ifndef LUABIND_NO_EXCEPTIONS
1216 throw luabind::error(L);
1217 #else
1218 error_callback_fun e = detail::error_callback::get().err;
1219 if (e) e(L);
1221 assert(0 && "the lua function threw an error and exceptions are disabled."
1222 "if you want to handle this error use luabind::set_error_callback()");
1223 std::terminate();
1224 #endif
1228 template<class Tuple>
1229 proxy_caller<Tuple>::operator luabind::object()
1231 m_called = true;
1232 lua_State* L = m_obj->lua_state();
1233 m_obj->pushvalue();
1235 push_args_from_tuple<1>::apply(L, m_args);
1236 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1238 #ifndef LUABIND_NO_EXCEPTIONS
1239 throw luabind::error(L);
1240 #else
1241 error_callback_fun e = detail::error_callback::get().err;
1242 if (e) e(L);
1244 assert(0 && "the lua function threw an error and exceptions are disabled."
1245 "if you want to handle this error use luabind::set_error_callback()");
1246 std::terminate();
1247 #endif
1249 int ref = detail::ref(L);
1250 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1255 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1256 MACRO(object, object) \
1257 MACRO(object, detail::proxy_object) \
1258 MACRO(object, detail::proxy_array_object) \
1259 MACRO(object, detail::proxy_raw_object) \
1260 MACRO(detail::proxy_object, object) \
1261 MACRO(detail::proxy_object, detail::proxy_object) \
1262 MACRO(detail::proxy_object, detail::proxy_array_object) \
1263 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1264 MACRO(detail::proxy_array_object, object) \
1265 MACRO(detail::proxy_array_object, detail::proxy_object) \
1266 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1267 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1268 MACRO(detail::proxy_raw_object, object) \
1269 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1270 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1271 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1274 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) bool operator==(const lhs&, const rhs&);
1275 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1276 #undef LUABIND_EQUALITY_OPERATOR
1278 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) bool operator<(const lhs&, const rhs&);
1279 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1280 #undef LUABIND_LESSTHAN_OPERATOR
1282 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) bool operator<=(const lhs_t&, const rhs_t&);
1283 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1284 #undef LUABIND_LESSOREQUAL_OPERATOR
1286 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1287 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1289 return !(rhs == lhs); \
1292 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1294 #undef LUABIND_INEQUALITY_OPERATOR
1296 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1297 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1299 return !(rhs < lhs); \
1302 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1304 #undef LUABIND_GREATEROREQUAL_OPERATOR
1306 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1307 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1309 return !(lhs <= rhs); \
1312 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1313 #undef LUABIND_GREATERTHAN_OPERATOR
1315 #undef LUABIND_DECLARE_OPERATOR
1319 namespace std
1322 #define LUABIND_DEFINE_SWAP(t1,t2)\
1323 inline void swap(t1 lhs, t2 rhs)\
1325 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1326 rhs.pushvalue();\
1327 lhs.pushvalue();\
1328 rhs.set();\
1329 lhs.set();\
1332 inline void swap(luabind::object& lhs, luabind::object& rhs)
1334 lhs.swap(rhs);
1337 // object against all other
1338 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1339 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1340 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1341 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1342 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1343 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1345 // proxy_object against all other
1346 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1347 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1348 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1349 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1350 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1352 // proxy_raw_object against all other
1353 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1354 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1355 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1357 // proxy_array_object against all other
1358 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1360 #undef LUABIND_DEFINE_SWAP
1362 } // std
1364 #endif // LUABIND_OBJECT_HPP_INCLUDED
1366 #elif BOOST_PP_ITERATION_FLAGS() == 1
1368 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1369 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1371 #if BOOST_PP_ITERATION() > 0
1372 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1373 #endif
1374 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1375 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1377 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1378 #if BOOST_PP_ITERATION() == 0
1379 tuple_t args;
1380 #else
1381 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1382 #endif
1383 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1386 #undef LUABIND_OPERATOR_PARAMS
1387 #undef LUABIND_TUPLE_PARAMS
1389 #endif