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 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);
973 raw_iterator
i(const_cast<object
*>(this), detail::ref(m_state
));
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");
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
);
1004 inline object
raw_at(const T
& key
)
1006 lua_State
* L
= lua_state();
1008 detail::convert_to_lua(L
, key
);
1010 int ref
= detail::ref(L
);
1012 return object(L
, ref
, true);
1016 inline object
at(const T
& key
)
1018 lua_State
* L
= lua_state();
1020 detail::convert_to_lua(L
, key
);
1021 lua_gettable(L
, -2);
1022 int ref
= detail::ref(L
);
1024 return object(L
, ref
, true);
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 // *****************************
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;
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
);
1053 return const_cast<luabind::object
&>(*this);
1057 // *****************************
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
1084 object(lua_State
* L
, int ref
, bool/*, reference*/)
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
;
1108 // *************************************
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
);
1121 // *************************************
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
)
1130 lua_State
* L
= m_obj
->lua_state();
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
1138 error_callback_fun e
= detail::error_callback::get().err
;
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()");
1146 int ref
= detail::ref(L
);
1147 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
1150 // *************************************
1153 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1155 inline object
proxy_object::raw_at(const T
& key
)
1156 LUABIND_PROXY_RAW_AT_BODY
1159 inline object
proxy_object::at(const T
& key
)
1160 LUABIND_PROXY_AT_BODY
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();
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))
1182 inline object
proxy_array_object::raw_at(const T
& key
)
1183 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1186 inline object
proxy_array_object::at(const T
& key
)
1187 LUABIND_PROXY_ARRAY_AT_BODY
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();
1202 int ref
= detail::ref(L
);
1203 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1207 // *************************************
1210 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1212 inline object
proxy_raw_object::raw_at(const T
& key
)
1213 LUABIND_PROXY_RAW_AT_BODY
1216 inline object
proxy_raw_object::at(const T
& key
)
1217 LUABIND_PROXY_AT_BODY
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();
1232 int ref
= detail::ref(L
);
1233 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1237 // *************************************
1241 template<class Tuple
>
1242 proxy_caller
<Tuple
>::~proxy_caller()
1244 if (m_called
) return;
1247 lua_State
* L
= m_obj
->lua_state();
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
);
1256 error_callback_fun e
= detail::error_callback::get().err
;
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()");
1266 template<class Tuple
>
1267 proxy_caller
<Tuple
>::operator luabind::object()
1270 lua_State
* L
= m_obj
->lua_state();
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
);
1279 error_callback_fun e
= detail::error_callback::get().err
;
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()");
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
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");\
1370 inline void swap(luabind::object
& lhs
, luabind::object
& 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
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
)>
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
1419 tuple_t
args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a
));
1421 return detail::proxy_caller
<tuple_t
>(const_cast<luabind::object
*>(this), args
);
1424 #undef LUABIND_OPERATOR_PARAMS
1425 #undef LUABIND_TUPLE_PARAMS