all relational operators added to luabind::object
[luabind.git] / luabind / object.hpp
blob914fbda4f6c30bbff3453a476a59e4d539f45775
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
385 template<class T>
386 inline object raw_at(const T& key)
388 lua_State* L = lua_state();
389 pushvalue();
390 detail::convert_to_lua(L, key);
391 lua_rawget(L, -2);
392 int ref = detail::ref(L);
393 lua_pop(L, 1);
394 return object(L, ref, true);
397 template<class T>
398 inline object at(const T& key)
400 lua_State* L = lua_state();
401 pushvalue();
402 detail::convert_to_lua(L, key);
403 lua_gettable(L, -2);
404 int ref = detail::ref(L);
405 lua_pop(L, 1);
406 return object(L, ref, true);
409 inline bool is_valid() const { return true; }
410 lua_State* lua_state() const;
411 void pushvalue() const;
412 void set() const;
414 // this is a safe substitute for an implicit converter to bool
415 typedef void (proxy_raw_object::*member_ptr)() const;
416 operator member_ptr() const
418 if (is_valid()) return &proxy_raw_object::dummy;
419 return 0;
423 private:
425 void dummy() const {}
427 proxy_raw_object(luabind::object* o, int key)
428 : m_obj(o)
429 , m_key_ref(key)
433 luabind::object* m_obj;
434 int m_key_ref;
439 class proxy_array_object
441 friend class luabind::object;
442 friend class luabind::detail::proxy_object;
443 friend class luabind::detail::proxy_raw_object;
444 // template<class T> friend T object_cast(const proxy_array_object& obj);
445 public:
447 template<class T>
448 proxy_array_object& operator=(const T& val)
450 //std::cout << "array proxy assigment\n";
451 lua_State* L = m_obj->m_state;
452 m_obj->pushvalue();
453 detail::convert_to_lua(L, val);
454 lua_rawseti(L, -2, m_key);
456 // pops the table
457 lua_pop(L, 1);
458 return *this;
461 proxy_array_object& operator=(const object& p);
462 proxy_array_object& operator=(const proxy_object& p);
463 proxy_array_object& operator=(const proxy_raw_object& p);
464 proxy_array_object& operator=(const proxy_array_object& p);
465 void swap(const proxy_array_object& rhs);
467 operator luabind::object();
469 int type() const
471 pushvalue();
472 detail::stack_pop p(lua_state(), 1);
473 return lua_type(lua_state(), -1);
476 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
478 pushvalue(); \
479 detail::convert_to_lua(m_state, key); \
480 lua_rawget(m_state, -2); \
481 int ref = detail::ref(m_state); \
482 lua_pop(m_state, 1); \
483 return object(m_state, ref, true); \
486 #define LUABIND_PROXY_ARRAY_AT_BODY \
488 pushvalue(); \
489 detail::convert_to_lua(m_state, key); \
490 lua_gettable(m_state, -2); \
491 int ref = detail::ref(m_state); \
492 lua_pop(m_state, 1); \
493 return object(m_state, ref, true); \
496 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
497 template<class T>
498 inline object at(const T& key)
499 LUABIND_PROXY_ARRAY_AT_BODY
500 #else
501 template<class T>
502 inline object at(const T& key);
503 #endif
506 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
507 template<class T>
508 inline object raw_at(const T& key)
509 LUABIND_PROXY_ARRAY_RAW_AT_BODY
510 #else
511 template<class T>
512 inline object raw_at(const T& key);
513 #endif
515 template<class T>
516 inline object raw_at(const T& key)
518 pushvalue();
519 detail::convert_to_lua(m_state, key);
520 lua_rawget(m_state, -2);
521 int ref = detail::ref(m_state);
522 lua_pop(m_state, 1);
523 return object(m_state, ref, true);
526 template<class T>
527 inline object at(const T& key)
529 pushvalue();
530 detail::convert_to_lua(m_state, key);
531 lua_gettable(m_state, -2);
532 int ref = detail::ref(m_state);
533 lua_pop(m_state, 1);
534 return object(m_state, ref, true);
537 template<class T>
538 inline detail::proxy_object operator[](const T& key) const
540 detail::convert_to_lua(m_state, key);
541 int ref = detail::ref(m_state);
542 return detail::proxy_object(const_cast<object*>(this), ref);
545 inline bool is_valid() const { return true; }
546 lua_State* lua_state() const;
547 void pushvalue() const;
548 void set() const;
550 // this is a safe substitute for an implicit converter to bool
551 typedef void (proxy_array_object::*member_ptr)() const;
552 operator member_ptr() const
554 if (is_valid()) return &proxy_array_object::dummy;
555 return 0;
558 private:
560 void dummy() const {}
562 proxy_array_object(luabind::object* o, int key)
563 : m_obj(o)
564 , m_key(key)
567 luabind::object* m_obj;
568 int m_key;
571 template<class T>
572 struct primitive_converter;
574 } // detail
579 class object
582 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
584 template<class T>
585 friend T object_cast(const object& obj);
586 template<class T>
587 friend struct detail::primitive_converter;
589 #endif
591 friend object get_globals(lua_State*);
592 friend object get_registry(lua_State*);
593 friend object newtable(lua_State*);
594 friend class detail::proxy_object;
595 friend class detail::proxy_array_object;
596 friend class detail::proxy_raw_object;
598 public:
600 class array_iterator
602 friend class object;
603 public:
605 typedef std::forward_iterator_tag iterator_category;
606 typedef luabind::object value_type;
607 typedef value_type& reference;
608 typedef value_type* pointer;
609 typedef void difference_type;
611 array_iterator()
612 : m_obj(0)
613 , m_key(LUA_NOREF)
617 array_iterator(const array_iterator& iter)
618 : m_obj(iter.m_obj)
619 , m_key(iter.m_key)
623 ~array_iterator() {}
625 array_iterator& operator=(const array_iterator& rhs)
627 //std::cout << "===\n";
628 m_obj = rhs.m_obj;
629 m_key = rhs.m_key;
630 return *this;
633 detail::proxy_array_object operator*()
635 return m_obj->make_array_proxy(m_key);
638 inline array_iterator& operator++()
640 m_key++;
642 // invalidate the iterator if we hit a nil element
643 lua_State* L = m_obj->lua_state();
644 m_obj->pushvalue();
645 lua_rawgeti(L, -1, m_key);
646 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
647 lua_pop(L, 1);
649 return *this;
652 inline array_iterator operator++(int)
654 int old_key = m_key;
655 m_key++;
657 // invalidate the iterator if we hit a nil element
658 lua_State* L = m_obj->lua_state();
659 m_obj->pushvalue();
660 lua_rawgeti(L, -1, m_key);
661 if (lua_isnil(L, -1)) m_key = LUA_NOREF;
662 lua_pop(L, 1);
664 return array_iterator(m_obj, old_key);
667 bool operator!=(const array_iterator& rhs) const
669 return m_obj != rhs.m_obj || m_key != rhs.m_key;
672 private:
674 array_iterator(object* obj, int key)
675 : m_obj(obj)
676 , m_key(key)
680 object* m_obj;
681 int m_key;
689 class iterator
691 friend class object;
692 public:
694 typedef std::forward_iterator_tag iterator_category;
695 typedef luabind::object value_type;
696 typedef value_type& reference;
697 typedef value_type* pointer;
698 typedef void difference_type;
700 iterator()
701 : m_obj(0)
702 , m_key(LUA_NOREF)
706 iterator(const iterator& iter)
707 : m_obj(iter.m_obj)
708 , m_key(LUA_NOREF)
710 if (m_obj)
712 lua_State* L = m_obj->lua_state();
713 detail::getref(L, iter.m_key);
714 m_key = detail::ref(L);
718 ~iterator()
720 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
723 iterator& operator=(const iterator& rhs)
725 //std::cout << "===\n";
726 m_obj = rhs.m_obj;
727 if (m_obj)
729 lua_State* L = m_obj->lua_state();
730 detail::getref(L, rhs.m_key);
731 m_key = detail::ref(L);
733 else
735 m_key = LUA_NOREF;
737 return *this;
740 detail::proxy_object operator*()
742 return m_obj->make_proxy(m_key);
745 iterator& operator++()
747 lua_State* L = m_obj->lua_state();
748 m_obj->pushvalue();
749 detail::getref(L, m_key);
751 if (lua_next(L, -2) != 0)
753 lua_pop(L, 1);
754 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
755 lua_pop(L, 1);
757 else
759 lua_pop(L, 1);
760 detail::unref(L, m_key);
761 m_obj = 0;
762 m_key = LUA_NOREF;
765 return *this;
768 bool operator!=(const iterator& rhs) const
770 return m_obj != rhs.m_obj || m_key != rhs.m_key;
773 private:
775 iterator(object* obj, int key)
776 : m_obj(obj)
777 , m_key(key)
781 object* m_obj;
782 int m_key;
788 class raw_iterator
790 friend class object;
791 public:
793 typedef std::forward_iterator_tag iterator_category;
794 typedef luabind::object value_type;
795 typedef value_type& reference;
796 typedef value_type* pointer;
797 typedef void difference_type;
799 raw_iterator()
800 : m_obj(0)
801 , m_key(LUA_NOREF)
805 raw_iterator(const raw_iterator& iter)
806 : m_obj(iter.m_obj)
807 , m_key(LUA_NOREF)
809 if (m_obj)
811 lua_State* L = m_obj->lua_state();
812 detail::getref(L, iter.m_key);
813 m_key = detail::ref(L);
817 ~raw_iterator()
819 if (m_obj && m_key != LUA_NOREF) detail::unref(m_obj->lua_state(), m_key);
822 raw_iterator& operator=(const raw_iterator& rhs)
824 //std::cout << "===\n";
825 m_obj = rhs.m_obj;
826 if (m_obj)
828 lua_State* L = m_obj->lua_state();
829 detail::getref(L, rhs.m_key);
830 m_key = detail::ref(L);
832 else
834 m_key = LUA_NOREF;
836 return *this;
839 detail::proxy_raw_object operator*()
841 return m_obj->make_raw_proxy(m_key);
844 raw_iterator& operator++()
846 lua_State* L = m_obj->lua_state();
847 m_obj->pushvalue();
848 detail::getref(L, m_key);
850 if (lua_next(L, -2) != 0)
852 lua_pop(L, 1);
853 lua_rawseti(L, LUA_REGISTRYINDEX, m_key);
854 lua_pop(L, 1);
856 else
858 lua_pop(L, 1);
859 detail::unref(L, m_key);
860 m_obj = 0;
861 m_key = LUA_NOREF;
864 return *this;
867 bool operator!=(const raw_iterator& rhs) const
869 return m_obj != rhs.m_obj || m_key != rhs.m_key;
872 private:
874 raw_iterator(object* obj, int key)
875 : m_obj(obj)
876 , m_key(key)
880 object* m_obj;
881 int m_key;
889 object()
890 : m_state(0)
891 , m_ref(LUA_NOREF)
895 object(lua_State* L)
896 : m_state(L)
897 , m_ref(LUA_NOREF)
901 template<class T>
902 object(lua_State* L, const T& val)
903 : m_state(L)
904 , m_ref(LUA_NOREF)
906 *this = val;
909 object(const object& o)
910 : m_state(o.m_state)
911 , m_ref(LUA_NOREF)
913 lua_getref(m_state, o.m_ref);
914 m_ref = detail::ref(m_state);
917 inline ~object()
919 // If you crash in the detail::unref() call you have probably
920 // closed the lua_State before destructing all object instances.
921 if (m_ref != LUA_NOREF) detail::unref(m_state, m_ref);
924 inline bool is_valid() const { return m_ref != LUA_NOREF; }
926 // this is a safe substitute for an implicit converter to bool
927 typedef void (object::*member_ptr)() const;
928 operator member_ptr() const
930 if (is_valid()) return &object::dummy;
931 return 0;
934 int type() const
936 pushvalue();
937 detail::stack_pop p(lua_state(), 1);
938 return lua_type(lua_state(), -1);
941 inline iterator begin() const
943 lua_getref(m_state, m_ref);
944 lua_pushnil(m_state);
945 lua_next(m_state, -2);
946 lua_pop(m_state, 1);
947 iterator i(const_cast<object*>(this), detail::ref(m_state));
948 lua_pop(m_state, 1);
949 return i;
952 inline iterator end() const
954 return iterator(0, LUA_NOREF);
957 inline array_iterator abegin() const
959 return array_iterator(const_cast<object*>(this), 1);
962 inline array_iterator aend() const
964 return array_iterator(const_cast<object*>(this), LUA_NOREF);
967 raw_iterator raw_begin() const
969 lua_getref(m_state, m_ref);
970 lua_pushnil(m_state);
971 lua_next(m_state, -2);
972 lua_pop(m_state, 1);
973 raw_iterator i(const_cast<object*>(this), detail::ref(m_state));
974 lua_pop(m_state, 1);
975 return i;
978 raw_iterator raw_end() const
980 return raw_iterator(0, LUA_NOREF);
983 inline void set() const
985 // you are trying to access an invalid object
986 assert((m_state != 0) && "you are trying to access an invalid (uninitialized) object");
988 allocate_slot();
989 lua_rawseti(m_state, LUA_REGISTRYINDEX, m_ref);
991 inline lua_State* lua_state() const { return m_state; }
992 inline void pushvalue() const
994 // you are trying to dereference an invalid object
995 assert((m_ref != LUA_NOREF) && "you are trying to access an invalid (uninitialized) object");
996 assert((m_state != 0) && "internal error, please report");
998 lua_getref(m_state, m_ref);
1001 void swap(object& rhs);
1003 template<class T>
1004 inline object raw_at(const T& key)
1006 lua_State* L = lua_state();
1007 pushvalue();
1008 detail::convert_to_lua(L, key);
1009 lua_rawget(L, -2);
1010 int ref = detail::ref(L);
1011 lua_pop(L, 1);
1012 return object(L, ref, true);
1015 template<class T>
1016 inline object at(const T& key)
1018 lua_State* L = lua_state();
1019 pushvalue();
1020 detail::convert_to_lua(L, key);
1021 lua_gettable(L, -2);
1022 int ref = detail::ref(L);
1023 lua_pop(L, 1);
1024 return object(L, ref, true);
1027 template<class T>
1028 inline detail::proxy_object operator[](const T& key) const
1030 detail::convert_to_lua(m_state, key);
1031 int ref = detail::ref(m_state);
1032 return detail::proxy_object(const_cast<object*>(this), ref);
1037 // *****************************
1038 // OPERATOR =
1040 object& operator=(const object& o) const;
1041 object& operator=(const detail::proxy_object& o) const;
1042 object& operator=(const detail::proxy_raw_object& o) const;
1043 object& operator=(const detail::proxy_array_object& o) const;
1045 template<class T>
1046 object& operator=(const T& val) const
1048 assert((m_state != 0) && "you cannot assign a non-lua value to an uninitialized object");
1049 // you cannot assign a non-lua value to an uninitialized object
1051 detail::convert_to_lua(m_state, val);
1052 set();
1053 return const_cast<luabind::object&>(*this);
1057 // *****************************
1058 // OPERATOR()
1060 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1061 #include BOOST_PP_ITERATE()
1065 inline detail::proxy_object make_proxy(int key)
1067 return detail::proxy_object(this, key);
1070 inline detail::proxy_raw_object make_raw_proxy(int key)
1072 return detail::proxy_raw_object(this, key);
1075 inline detail::proxy_array_object make_array_proxy(int key)
1077 return detail::proxy_array_object(this, key);
1080 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1081 // it's an inner class), that's why this interface is public
1082 // private:
1084 object(lua_State* L, int ref, bool/*, reference*/)
1085 : m_state(L)
1086 , m_ref(ref)
1090 private:
1092 void dummy() const {}
1094 void allocate_slot() const
1096 if (m_ref == LUA_NOREF)
1098 lua_pushboolean(m_state, 0);
1099 m_ref = detail::ref(m_state);
1103 mutable lua_State* m_state;
1104 mutable int m_ref;
1108 // *************************************
1109 // OBJECT
1111 inline void object::swap(object& rhs)
1113 // you cannot swap objects from different lua states
1114 assert((lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");
1115 std::swap(m_ref, rhs.m_ref);
1118 namespace detail
1121 // *************************************
1122 // PROXY CALLER
1124 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1125 template<class Tuple>
1126 template<class Policies>
1127 luabind::object proxy_caller<Tuple>::operator[](const Policies& p)
1129 m_called = true;
1130 lua_State* L = m_obj->lua_state();
1131 m_obj->pushvalue();
1132 detail::push_args_from_tuple<1>::apply(L, m_args, p);
1133 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1135 #ifndef LUABIND_NO_EXCEPTIONS
1136 throw error(L);
1137 #else
1138 error_callback_fun e = detail::error_callback::get().err;
1139 if (e) e(L);
1141 assert(0 && "the lua function threw an error and exceptions are disabled."
1142 "if you want to handle this error use luabind::set_error_callback()");
1143 std::terminate();
1144 #endif
1146 int ref = detail::ref(L);
1147 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1149 #endif
1150 // *************************************
1151 // PROXY OBJECT
1153 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1154 template<class T>
1155 inline object proxy_object::raw_at(const T& key)
1156 LUABIND_PROXY_RAW_AT_BODY
1158 template<class T>
1159 inline object proxy_object::at(const T& key)
1160 LUABIND_PROXY_AT_BODY
1161 #endif
1163 inline lua_State* proxy_object::lua_state() const
1165 return m_obj->lua_state();
1168 inline proxy_object::operator luabind::object()
1170 lua_State* L = m_obj->lua_state();
1171 pushvalue();
1172 int ref = detail::ref(L);
1173 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1177 // *************************************
1178 // PROXY ARRAY OBJECT
1180 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1181 template<class T>
1182 inline object proxy_array_object::raw_at(const T& key)
1183 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1185 template<class T>
1186 inline object proxy_array_object::at(const T& key)
1187 LUABIND_PROXY_ARRAY_AT_BODY
1188 #endif
1190 #undef LUABIND_PROXY_ARRAY_AT_BODY
1191 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1193 inline lua_State* proxy_array_object::lua_state() const
1195 return m_obj->lua_state();
1198 inline proxy_array_object::operator luabind::object()
1200 lua_State* L = m_obj->lua_state();
1201 pushvalue();
1202 int ref = detail::ref(L);
1203 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1207 // *************************************
1208 // PROXY RAW OBJECT
1210 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1211 template<class T>
1212 inline object proxy_raw_object::raw_at(const T& key)
1213 LUABIND_PROXY_RAW_AT_BODY
1215 template<class T>
1216 inline object proxy_raw_object::at(const T& key)
1217 LUABIND_PROXY_AT_BODY
1218 #endif
1220 #undef LUABIND_PROXY_RAW_AT_BODY
1221 #undef LUABIND_PROXY_AT_BODY
1223 inline lua_State* proxy_raw_object::lua_state() const
1225 return m_obj->lua_state();
1228 inline proxy_raw_object::operator luabind::object()
1230 lua_State* L = lua_state();
1231 pushvalue();
1232 int ref = detail::ref(L);
1233 return luabind::object(L, ref, true/*luabind::object::reference()*/);
1237 // *************************************
1238 // PROXY CALLER
1241 template<class Tuple>
1242 proxy_caller<Tuple>::~proxy_caller()
1244 if (m_called) return;
1246 m_called = true;
1247 lua_State* L = m_obj->lua_state();
1248 m_obj->pushvalue();
1250 push_args_from_tuple<1>::apply(L, m_args);
1251 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 0, 0))
1253 #ifndef LUABIND_NO_EXCEPTIONS
1254 throw luabind::error(L);
1255 #else
1256 error_callback_fun e = detail::error_callback::get().err;
1257 if (e) e(L);
1259 assert(0 && "the lua function threw an error and exceptions are disabled."
1260 "if you want to handle this error use luabind::set_error_callback()");
1261 std::terminate();
1262 #endif
1266 template<class Tuple>
1267 proxy_caller<Tuple>::operator luabind::object()
1269 m_called = true;
1270 lua_State* L = m_obj->lua_state();
1271 m_obj->pushvalue();
1273 push_args_from_tuple<1>::apply(L, m_args);
1274 if (lua_pcall(L, boost::tuples::length<Tuple>::value, 1, 0))
1276 #ifndef LUABIND_NO_EXCEPTIONS
1277 throw luabind::error(L);
1278 #else
1279 error_callback_fun e = detail::error_callback::get().err;
1280 if (e) e(L);
1282 assert(0 && "the lua function threw an error and exceptions are disabled."
1283 "if you want to handle this error use luabind::set_error_callback()");
1284 std::terminate();
1285 #endif
1287 int ref = detail::ref(L);
1288 return luabind::object(m_obj->lua_state(), ref, true/*luabind::object::reference()*/);
1293 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1294 MACRO(object, object) \
1295 MACRO(object, detail::proxy_object) \
1296 MACRO(object, detail::proxy_array_object) \
1297 MACRO(object, detail::proxy_raw_object) \
1298 MACRO(detail::proxy_object, object) \
1299 MACRO(detail::proxy_object, detail::proxy_object) \
1300 MACRO(detail::proxy_object, detail::proxy_array_object) \
1301 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1302 MACRO(detail::proxy_array_object, object) \
1303 MACRO(detail::proxy_array_object, detail::proxy_object) \
1304 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1305 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1306 MACRO(detail::proxy_raw_object, object) \
1307 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1308 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1309 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1312 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) bool operator==(const lhs&, const rhs&);
1313 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
1314 #undef LUABIND_EQUALITY_OPERATOR
1316 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) bool operator<(const lhs&, const rhs&);
1317 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR)
1318 #undef LUABIND_LESSTHAN_OPERATOR
1320 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) bool operator<=(const lhs_t&, const rhs_t&);
1321 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR)
1322 #undef LUABIND_LESSOREQUAL_OPERATOR
1324 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1325 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1327 return !(rhs == lhs); \
1330 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR)
1332 #undef LUABIND_INEQUALITY_OPERATOR
1334 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1335 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1337 return !(rhs < lhs); \
1340 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR)
1342 #undef LUABIND_GREATEROREQUAL_OPERATOR
1344 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1345 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1347 return !(lhs <= rhs); \
1350 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR)
1351 #undef LUABIND_GREATERTHAN_OPERATOR
1353 #undef LUABIND_DECLARE_OPERATOR
1357 namespace std
1360 #define LUABIND_DEFINE_SWAP(t1,t2)\
1361 inline void swap(t1 lhs, t2 rhs)\
1363 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1364 rhs.pushvalue();\
1365 lhs.pushvalue();\
1366 rhs.set();\
1367 lhs.set();\
1370 inline void swap(luabind::object& lhs, luabind::object& rhs)
1372 lhs.swap(rhs);
1375 // object against all other
1376 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_object&)
1377 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_raw_object&)
1378 LUABIND_DEFINE_SWAP(luabind::object&, const luabind::detail::proxy_array_object&)
1379 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, luabind::object&)
1380 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, luabind::object&)
1381 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, luabind::object&)
1383 // proxy_object against all other
1384 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_object&)
1385 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_raw_object&)
1386 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object&, const luabind::detail::proxy_array_object&)
1387 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_object&)
1388 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_object&)
1390 // proxy_raw_object against all other
1391 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_raw_object&)
1392 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object&, const luabind::detail::proxy_array_object&)
1393 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_raw_object&)
1395 // proxy_array_object against all other
1396 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object&, const luabind::detail::proxy_array_object&)
1398 #undef LUABIND_DEFINE_SWAP
1400 } // std
1402 #endif // LUABIND_OBJECT_HPP_INCLUDED
1404 #elif BOOST_PP_ITERATION_FLAGS() == 1
1406 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1407 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1409 #if BOOST_PP_ITERATION() > 0
1410 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A)>
1411 #endif
1412 detail::proxy_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
1413 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) const
1415 typedef boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> tuple_t;
1416 #if BOOST_PP_ITERATION() == 0
1417 tuple_t args;
1418 #else
1419 tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a));
1420 #endif
1421 return detail::proxy_caller<tuple_t>(const_cast<luabind::object*>(this), args);
1424 #undef LUABIND_OPERATOR_PARAMS
1425 #undef LUABIND_TUPLE_PARAMS
1427 #endif