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
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>
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
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?
64 // Perhaps we could perform some not-so-smart comparisions? like:
67 // struct commiter : base_commiter
69 // commiter(const T& v): val(v), base_commiter(typeid(T)) {}
71 // virtual bool compare(void* rhs)
73 // T* other = static_cast<T*>(rhs);
74 // return val == *other;
80 // This would at least allow for the most intuitive use.. like:
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.
98 class proxy_raw_object
;
99 class proxy_array_object
;
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
&);
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
>
134 friend class luabind::object
;
137 proxy_caller(luabind::object
* o
, const Tuple args
)
144 proxy_caller(const detail::proxy_caller
<Tuple
>& rhs
)
147 , m_called(rhs
.m_called
)
153 operator luabind::object();
155 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
156 #define LUABIND_SEMICOLON
158 #define LUABIND_SEMICOLON ;
161 template<class Policies
>
162 luabind::object
operator[](const Policies
& p
) LUABIND_SEMICOLON
163 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
166 lua_State
* L
= m_obj
->lua_state();
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
174 error_callback_fun e
= detail::error_callback::get().err
;
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()");
182 int ref
= detail::ref(L
);
183 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
188 #undef LUABIND_SEMICOLON
191 luabind::object
* m_obj
;
193 mutable bool m_called
;
201 stack_pop(lua_State
* L
, int n
)
209 lua_pop(m_state
, m_n
);
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);
231 proxy_object
& operator=(const T
& val
)
233 //std::cout << "proxy assigment\n";
234 lua_State
* L
= m_obj
->m_state
;
236 detail::getref(L
, m_key_ref
);
237 detail::convert_to_lua(L
, val
);
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();
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(); \
264 detail::convert_to_lua(L, key); \
266 int ref = detail::ref(L); \
268 return object(L, ref, true); \
271 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
273 inline object
raw_at(const T
& key
)
274 LUABIND_PROXY_RAW_AT_BODY
277 inline object
raw_at(const T
& key
);
280 #define LUABIND_PROXY_AT_BODY \
282 lua_State* L = lua_state(); \
284 detail::convert_to_lua(L, key); \
285 lua_gettable(L, -2); \
286 int ref = detail::ref(L); \
288 return object(L, ref, true); \
291 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
293 inline object
at(const T
& key
)
294 LUABIND_PROXY_AT_BODY
297 inline object
at(const T
& key
);
300 inline bool is_valid() const { return true; }
301 lua_State
* lua_state() const;
302 void pushvalue() 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
;
315 void dummy() const {}
317 proxy_object(luabind::object
* o
, int key
)
323 luabind::object
* m_obj
;
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);
338 proxy_raw_object
& operator=(const T
& val
)
340 //std::cout << "proxy assigment\n";
341 lua_State
* L
= m_obj
->m_state
;
343 detail::getref(L
, m_key_ref
);
344 detail::convert_to_lua(L
, val
);
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();
362 detail::stack_pop
p(lua_state(), 1);
363 return lua_type(lua_state(), -1);
366 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
368 inline object
raw_at(const T
& key
)
369 LUABIND_PROXY_RAW_AT_BODY
372 inline object
raw_at(const T
& key
);
375 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
377 inline object
at(const T
& key
)
378 LUABIND_PROXY_AT_BODY
381 inline object
at(const T
& key
);
386 inline object raw_at(const T& key)
388 lua_State* L = lua_state();
390 detail::convert_to_lua(L, key);
392 int ref = detail::ref(L);
394 return object(L, ref, true);
398 inline object at(const T& key)
400 lua_State* L = lua_state();
402 detail::convert_to_lua(L, key);
404 int ref = detail::ref(L);
406 return object(L, ref, true);
409 inline bool is_valid() const { return true; }
410 lua_State
* lua_state() const;
411 void pushvalue() 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
;
425 void dummy() const {}
427 proxy_raw_object(luabind::object
* o
, int key
)
433 luabind::object
* m_obj
;
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);
448 proxy_array_object
& operator=(const T
& val
)
450 //std::cout << "array proxy assigment\n";
451 lua_State
* L
= m_obj
->m_state
;
453 detail::convert_to_lua(L
, val
);
454 lua_rawseti(L
, -2, m_key
);
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();
472 detail::stack_pop
p(lua_state(), 1);
473 return lua_type(lua_state(), -1);
476 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
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 \
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)
498 inline object
at(const T
& key
)
499 LUABIND_PROXY_ARRAY_AT_BODY
502 inline object
at(const T
& key
);
506 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
508 inline object
raw_at(const T
& key
)
509 LUABIND_PROXY_ARRAY_RAW_AT_BODY
512 inline object
raw_at(const T
& key
);
516 inline object raw_at(const T& key)
519 detail::convert_to_lua(m_state, key);
520 lua_rawget(m_state, -2);
521 int ref = detail::ref(m_state);
523 return object(m_state, ref, true);
527 inline object at(const T& key)
530 detail::convert_to_lua(m_state, key);
531 lua_gettable(m_state, -2);
532 int ref = detail::ref(m_state);
534 return object(m_state, ref, true);
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;
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
;
560 void dummy() const {}
562 proxy_array_object(luabind::object
* o
, int key
)
567 luabind::object
* m_obj
;
572 struct primitive_converter
;
582 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
585 friend T
object_cast(const object
& obj
);
587 friend struct detail::primitive_converter
;
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
;
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
;
617 array_iterator(const array_iterator
& iter
)
625 array_iterator
& operator=(const array_iterator
& rhs
)
627 //std::cout << "===\n";
633 detail::proxy_array_object
operator*()
635 return m_obj
->make_array_proxy(m_key
);
638 inline array_iterator
& operator++()
642 // invalidate the iterator if we hit a nil element
643 lua_State
* L
= m_obj
->lua_state();
645 lua_rawgeti(L
, -1, m_key
);
646 if (lua_isnil(L
, -1)) m_key
= LUA_NOREF
;
652 inline array_iterator
operator++(int)
657 // invalidate the iterator if we hit a nil element
658 lua_State
* L
= m_obj
->lua_state();
660 lua_rawgeti(L
, -1, m_key
);
661 if (lua_isnil(L
, -1)) m_key
= LUA_NOREF
;
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
;
674 array_iterator(object
* obj
, int key
)
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
;
706 iterator(const iterator
& iter
)
712 lua_State
* L
= m_obj
->lua_state();
713 detail::getref(L
, iter
.m_key
);
714 m_key
= detail::ref(L
);
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";
729 lua_State
* L
= m_obj
->lua_state();
730 detail::getref(L
, rhs
.m_key
);
731 m_key
= detail::ref(L
);
740 detail::proxy_object
operator*()
742 return m_obj
->make_proxy(m_key
);
745 iterator
& operator++()
747 lua_State
* L
= m_obj
->lua_state();
749 detail::getref(L
, m_key
);
751 if (lua_next(L
, -2) != 0)
754 lua_rawseti(L
, LUA_REGISTRYINDEX
, m_key
);
760 detail::unref(L
, m_key
);
768 bool operator!=(const iterator
& rhs
) const
770 return m_obj
!= rhs
.m_obj
|| m_key
!= rhs
.m_key
;
775 iterator(object
* obj
, int key
)
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
;
805 raw_iterator(const raw_iterator
& iter
)
811 lua_State
* L
= m_obj
->lua_state();
812 detail::getref(L
, iter
.m_key
);
813 m_key
= detail::ref(L
);
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";
828 lua_State
* L
= m_obj
->lua_state();
829 detail::getref(L
, rhs
.m_key
);
830 m_key
= detail::ref(L
);
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();
848 detail::getref(L
, m_key
);
850 if (lua_next(L
, -2) != 0)
853 lua_rawseti(L
, LUA_REGISTRYINDEX
, m_key
);
859 detail::unref(L
, m_key
);
867 bool operator!=(const raw_iterator
& rhs
) const
869 return m_obj
!= rhs
.m_obj
|| m_key
!= rhs
.m_key
;
874 raw_iterator(object
* obj
, int key
)
902 object(lua_State
* L
, const T
& val
)
909 object(const object
& o
)
913 lua_getref(m_state
, o
.m_ref
);
914 m_ref
= detail::ref(m_state
);
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
;
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);
947 iterator
i(const_cast<object
*>(this), detail::ref(m_state
));
952 inline iterator
end() const
954 return iterator(0, LUA_NOREF
);
957 inline array_iterator
abegin() const
959 // TODO: This should start counting at 1, right?
960 return array_iterator(const_cast<object
*>(this), 1);
963 inline array_iterator
aend() const
965 return array_iterator(const_cast<object
*>(this), LUA_NOREF
);
968 raw_iterator
raw_begin() const
970 lua_getref(m_state
, m_ref
);
971 lua_pushnil(m_state
);
972 lua_next(m_state
, -2);
974 raw_iterator
i(const_cast<object
*>(this), detail::ref(m_state
));
979 raw_iterator
raw_end() const
981 return raw_iterator(0, LUA_NOREF
);
984 inline void set() const
986 // you are trying to access an invalid object
987 assert((m_state
!= 0) && "you are trying to access an invalid (uninitialized) object");
990 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
992 inline lua_State
* lua_state() const { return m_state
; }
993 inline void pushvalue() const
995 // you are trying to dereference an invalid object
996 assert((m_ref
!= LUA_NOREF
) && "you are trying to access an invalid (uninitialized) object");
997 assert((m_state
!= 0) && "internal error, please report");
999 lua_getref(m_state
, m_ref
);
1002 void swap(object
& rhs
);
1005 inline object
raw_at(const T
& key
)
1007 lua_State
* L
= lua_state();
1009 detail::convert_to_lua(L
, key
);
1011 int ref
= detail::ref(L
);
1013 return object(L
, ref
, true);
1017 inline object
at(const T
& key
)
1019 lua_State
* L
= lua_state();
1021 detail::convert_to_lua(L
, key
);
1022 lua_gettable(L
, -2);
1023 int ref
= detail::ref(L
);
1025 return object(L
, ref
, true);
1029 inline detail::proxy_object
operator[](const T
& key
) const
1031 detail::convert_to_lua(m_state
, key
);
1032 int ref
= detail::ref(m_state
);
1033 return detail::proxy_object(const_cast<object
*>(this), ref
);
1038 // *****************************
1042 object
& operator=(const object
& o
) const
1044 m_state
= o
.lua_state();
1047 //TODO: move lua_rawseti into a function set_ref() or something
1048 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
1049 return const_cast<luabind::object
&>(*this);
1052 object
& operator=(const detail::proxy_object
& o
) const
1054 m_state
= o
.lua_state();
1057 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
1058 return const_cast<luabind::object
&>(*this);
1061 object
& operator=(const detail::proxy_raw_object
& o
) const
1063 m_state
= o
.lua_state();
1066 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
1067 return const_cast<luabind::object
&>(*this);
1070 object
& operator=(const detail::proxy_array_object
& o
) const
1072 m_state
= o
.lua_state();
1075 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
1076 return const_cast<luabind::object
&>(*this);
1080 object
& operator=(const T
& val
) const
1082 assert((m_state
!= 0) && "you cannot assign a non-lua value to an uninitialized object");
1083 // you cannot assign a non-lua value to an uninitialized object
1086 detail::convert_to_lua(m_state
, val
);
1087 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
1088 return const_cast<luabind::object
&>(*this);
1092 // *****************************
1096 bool operator==(const object
& rhs
) const
1098 if (m_ref
== LUA_NOREF
|| rhs
.m_ref
== LUA_NOREF
) return false;
1099 lua_getref(m_state
, m_ref
);
1101 bool result
= lua_equal(m_state
, -1, -2) != 0;
1102 lua_pop(m_state
, 2);
1106 bool operator==(const detail::proxy_object
& rhs
) const
1108 if (m_ref
== LUA_NOREF
) return false;
1109 lua_getref(m_state
, m_ref
);
1111 bool result
= lua_equal(m_state
, -1, -2) != 0;
1112 lua_pop(m_state
, 2);
1116 bool operator==(const detail::proxy_raw_object
& rhs
) const
1118 if (m_ref
== LUA_NOREF
) return false;
1119 lua_getref(m_state
, m_ref
);
1121 bool result
= lua_equal(m_state
, -1, -2) != 0;
1122 lua_pop(m_state
, 2);
1126 bool operator==(const detail::proxy_array_object
& rhs
) const
1128 if (m_ref
== LUA_NOREF
) return false;
1129 lua_getref(m_state
, m_ref
);
1131 bool result
= lua_equal(m_state
, -1, -2) != 0;
1132 lua_pop(m_state
, 2);
1137 bool operator==(const T
& rhs
) const
1139 if (m_ref
== LUA_NOREF
) return false;
1140 lua_getref(m_state
, m_ref
);
1141 detail::convert_to_lua(m_state
, rhs
);
1143 bool result
= lua_equal(m_state
, -1, -2);
1145 lua_pop(m_state
, 2);
1151 // *****************************
1154 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1155 #include BOOST_PP_ITERATE()
1159 inline detail::proxy_object
make_proxy(int key
)
1161 return detail::proxy_object(this, key
);
1164 inline detail::proxy_raw_object
make_raw_proxy(int key
)
1166 return detail::proxy_raw_object(this, key
);
1169 inline detail::proxy_array_object
make_array_proxy(int key
)
1171 return detail::proxy_array_object(this, key
);
1174 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1175 // it's an inner class), that's why this interface is public
1178 struct stack_index {};
1179 struct reference {};
1182 object(lua_State* L, int index, stack_index)
1185 lua_pushvalue(L, index);
1186 m_ref = detail::ref(L);
1189 object(lua_State
* L
, int ref
, bool/*, reference*/)
1197 void dummy() const {}
1199 void allocate_slot() const
1201 if (m_ref
== LUA_NOREF
)
1203 lua_pushboolean(m_state
, 0);
1204 m_ref
= detail::ref(m_state
);
1208 mutable lua_State
* m_state
;
1213 // *************************************
1216 inline void object::swap(object
& rhs
)
1218 // you cannot swap objects from different lua states
1219 assert((lua_state() == rhs
.lua_state()) && "you cannot swap objects from different lua states");
1220 std::swap(m_ref
, rhs
.m_ref
);
1226 // *************************************
1229 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1230 template<class Tuple
>
1231 template<class Policies
>
1232 luabind::object proxy_caller
<Tuple
>::operator[](const Policies
& p
)
1235 lua_State
* L
= m_obj
->lua_state();
1237 detail::push_args_from_tuple
<1>::apply(L
, m_args
, p
);
1238 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 1, 0))
1240 #ifndef LUABIND_NO_EXCEPTIONS
1243 error_callback_fun e
= detail::error_callback::get().err
;
1246 assert(0 && "the lua function threw an error and exceptions are disabled."
1247 "if you want to handle this error use luabind::set_error_callback()");
1251 int ref
= detail::ref(L
);
1252 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
1255 // *************************************
1258 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1260 inline object
proxy_object::raw_at(const T
& key
)
1261 LUABIND_PROXY_RAW_AT_BODY
1264 inline object
proxy_object::at(const T
& key
)
1265 LUABIND_PROXY_AT_BODY
1268 inline proxy_object
& proxy_object::operator=(const object
& p
)
1270 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1272 lua_State
* L
= lua_state();
1275 detail::getref(L
, m_key_ref
);
1277 // retrive the rhs value
1280 lua_settable(L
, -3);
1285 inline proxy_object
& proxy_object::operator=(const proxy_object
& p
)
1287 // if you hit this assert you are trying to transfer values from one lua state to another
1288 // without first going through C++
1289 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1291 lua_State
* L
= lua_state();
1293 //std::cout << "proxy-proxy assigment\n";
1295 detail::getref(L
, m_key_ref
);
1297 // retrive the rhs value
1300 lua_settable(L
, -3);
1305 inline proxy_object
& proxy_object::operator=(const proxy_raw_object
& p
)
1307 // if you hit this assert you are trying to transfer values from one lua state to another
1308 // without first going through C++
1309 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1311 lua_State
* L
= lua_state();
1313 //std::cout << "proxy-proxy assigment\n";
1315 detail::getref(L
, m_key_ref
);
1317 // retrive the rhs value
1320 lua_settable(L
, -3);
1325 inline proxy_object
& proxy_object::operator=(const proxy_array_object
& p
)
1327 // if you hit this assert you are trying to transfer values from one lua state to another
1328 // without first going through C++
1329 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1331 lua_State
* L
= lua_state();
1333 //std::cout << "proxy-proxy assigment\n";
1335 detail::getref(L
, m_key_ref
);
1337 // retrive the rhs value
1340 lua_settable(L
, -3);
1345 inline void proxy_object::pushvalue() const
1347 assert((m_key_ref
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitialized object");
1349 lua_State
* L
= m_obj
->lua_state();
1351 detail::getref(L
, m_key_ref
);
1352 lua_gettable(L
, -2);
1353 // remove the table and leave the value on top of the stack
1357 inline lua_State
* proxy_object::lua_state() const
1359 return m_obj
->lua_state();
1362 inline void proxy_object::set() const
1364 lua_State
* L
= lua_state();
1366 detail::getref(L
, m_key_ref
);
1367 lua_pushvalue(L
, -3);
1368 lua_settable(L
, -3);
1369 // pop table and value
1373 inline proxy_object::operator luabind::object()
1375 lua_State
* L
= m_obj
->lua_state();
1377 int ref
= detail::ref(L
);
1378 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1382 // *************************************
1383 // PROXY ARRAY OBJECT
1385 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1387 inline object
proxy_array_object::raw_at(const T
& key
)
1388 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1391 inline object
proxy_array_object::at(const T
& key
)
1392 LUABIND_PROXY_ARRAY_AT_BODY
1395 #undef LUABIND_PROXY_ARRAY_AT_BODY
1396 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1398 inline proxy_array_object
& proxy_array_object::operator=(const object
& p
)
1400 // if you hit this assert you are trying to transfer values
1401 // from one lua state to another without first going through C++
1402 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1403 lua_State
* L
= lua_state();
1405 // retrieve the rhs value
1408 lua_rawseti(L
, -2, m_key
);
1413 inline proxy_array_object
& proxy_array_object::operator=(const proxy_object
& p
)
1415 // if you hit this assert you are trying to transfer values from one lua state to another
1416 // without first going through C++
1417 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1419 lua_State
* L
= lua_state();
1421 //std::cout << "proxy-proxy assigment\n";
1424 // retrieve the rhs value
1427 lua_rawseti(L
, -2, m_key
);
1432 inline proxy_array_object
& proxy_array_object::operator=(const proxy_raw_object
& p
)
1434 // if you hit this assert you are trying to transfer values from one lua state to another
1435 // without first going through C++
1436 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1438 lua_State
* L
= lua_state();
1443 lua_rawseti(L
, -2, m_key
);
1448 inline proxy_array_object
& proxy_array_object::operator=(const proxy_array_object
& p
)
1450 // if you hit this assert you are trying to transfer values from one lua state to another
1451 // without first going through C++
1452 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1454 lua_State
* L
= lua_state();
1459 lua_rawseti(L
, -2, m_key
);
1464 inline lua_State
* proxy_array_object::lua_state() const
1466 return m_obj
->lua_state();
1469 inline void proxy_array_object::pushvalue() const
1471 // you are trying to dereference an invalid object
1472 assert((m_key
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitialized object");
1474 lua_State
* L
= m_obj
->lua_state();
1476 lua_rawgeti(L
, -1, m_key
);
1480 inline void proxy_array_object::set() const
1482 lua_State
* L
= lua_state();
1484 lua_pushvalue(L
, -2);
1485 lua_rawseti(L
, -2, m_key
);
1486 // pop table and value
1490 inline proxy_array_object::operator luabind::object()
1492 lua_State
* L
= m_obj
->lua_state();
1494 int ref
= detail::ref(L
);
1495 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1499 // *************************************
1502 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1504 inline object
proxy_raw_object::raw_at(const T
& key
)
1505 LUABIND_PROXY_RAW_AT_BODY
1508 inline object
proxy_raw_object::at(const T
& key
)
1509 LUABIND_PROXY_AT_BODY
1512 #undef LUABIND_PROXY_RAW_AT_BODY
1513 #undef LUABIND_PROXY_AT_BODY
1515 inline proxy_raw_object
& proxy_raw_object::operator=(const object
& p
)
1517 // if you hit this assert you are trying to transfer values from one lua state to another
1518 // without first going through C++
1519 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1520 lua_State
* L
= lua_state();
1523 detail::getref(L
, m_key_ref
);
1525 // retrive the rhs value
1534 inline proxy_raw_object
& proxy_raw_object::operator=(const proxy_object
& p
)
1536 // if you hit this assert you are trying to transfer values from one lua state to another
1537 // without first going through C++
1538 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1540 lua_State
* L
= lua_state();
1542 //std::cout << "proxy-proxy assigment\n";
1544 detail::getref(L
, m_key_ref
);
1546 // retrive the rhs value
1554 inline proxy_raw_object
& proxy_raw_object::operator=(const proxy_raw_object
& p
)
1556 // if you hit this assert you are trying to transfer values from one lua state to another
1557 // without first going through C++
1558 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1560 lua_State
* L
= lua_state();
1562 //std::cout << "proxy-proxy assigment\n";
1564 detail::getref(L
, m_key_ref
);
1566 // retrive the rhs value
1574 inline proxy_raw_object
& proxy_raw_object::operator=(const proxy_array_object
& p
)
1576 // if you hit this assert you are trying to transfer values from one lua state to another
1577 // without first going through C++
1578 assert((lua_state() == p
.lua_state()) && "you cannot assign a value from a different lua state");
1580 lua_State
* L
= lua_state();
1582 //std::cout << "proxy-proxy assigment\n";
1584 detail::getref(L
, m_key_ref
);
1586 // retrive the rhs value
1587 p
.m_obj
->pushvalue();
1588 lua_rawgeti(L
, -1, p
.m_key
);
1595 inline void proxy_raw_object::pushvalue() const
1597 assert((m_key_ref
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitiallized object");
1599 lua_State
* L
= lua_state();
1601 detail::getref(L
, m_key_ref
);
1603 // remove the table and leave the value on top of the stack
1607 inline void proxy_raw_object::set() const
1609 lua_State
* L
= lua_state();
1611 detail::getref(L
, m_key_ref
);
1612 lua_pushvalue(L
, -3);
1614 // pop table and value
1618 inline lua_State
* proxy_raw_object::lua_state() const
1620 return m_obj
->lua_state();
1623 inline proxy_raw_object::operator luabind::object()
1625 lua_State
* L
= lua_state();
1627 int ref
= detail::ref(L
);
1628 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1632 // *************************************
1636 template<class Tuple
>
1637 proxy_caller
<Tuple
>::~proxy_caller()
1639 if (m_called
) return;
1642 lua_State
* L
= m_obj
->lua_state();
1645 push_args_from_tuple
<1>::apply(L
, m_args
);
1646 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 0, 0))
1648 #ifndef LUABIND_NO_EXCEPTIONS
1649 throw luabind::error(L
);
1651 error_callback_fun e
= detail::error_callback::get().err
;
1654 assert(0 && "the lua function threw an error and exceptions are disabled."
1655 "if you want to handle this error use luabind::set_error_callback()");
1661 template<class Tuple
>
1662 proxy_caller
<Tuple
>::operator luabind::object()
1665 lua_State
* L
= m_obj
->lua_state();
1668 push_args_from_tuple
<1>::apply(L
, m_args
);
1669 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 1, 0))
1671 #ifndef LUABIND_NO_EXCEPTIONS
1672 throw luabind::error(L
);
1674 error_callback_fun e
= detail::error_callback::get().err
;
1677 assert(0 && "the lua function threw an error and exceptions are disabled."
1678 "if you want to handle this error use luabind::set_error_callback()");
1682 int ref
= detail::ref(L
);
1683 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
1693 #define LUABIND_DEFINE_SWAP(t1,t2)\
1694 inline void swap(t1 lhs, t2 rhs)\
1696 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1703 inline void swap(luabind::object
& lhs
, luabind::object
& rhs
)
1708 // object against all other
1709 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_object
&)
1710 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_raw_object
&)
1711 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_array_object
&)
1712 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, luabind::object
&)
1713 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, luabind::object
&)
1714 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, luabind::object
&)
1716 // proxy_object against all other
1717 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_object
&)
1718 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_raw_object
&)
1719 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_array_object
&)
1720 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_object
&)
1721 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_object
&)
1723 // proxy_raw_object against all other
1724 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_raw_object
&)
1725 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_array_object
&)
1726 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_raw_object
&)
1728 // proxy_array_object against all other
1729 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_array_object
&)
1731 #undef LUABIND_DEFINE_SWAP
1735 #endif // LUABIND_OBJECT_HPP_INCLUDED
1737 #elif BOOST_PP_ITERATION_FLAGS() == 1
1739 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1740 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1742 #if BOOST_PP_ITERATION() > 0
1743 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)>
1745 detail::proxy_caller
<boost::tuples::tuple
<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS
, _
)> >
1746 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS
, _
)) const
1748 typedef boost::tuples::tuple
<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS
, _
)> tuple_t
;
1749 #if BOOST_PP_ITERATION() == 0
1752 tuple_t
args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a
));
1754 return detail::proxy_caller
<tuple_t
>(const_cast<luabind::object
*>(this), args
);
1757 #undef LUABIND_OPERATOR_PARAMS
1758 #undef LUABIND_TUPLE_PARAMS