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
);
384 inline bool is_valid() const { return true; }
385 lua_State
* lua_state() const;
386 void pushvalue() const;
389 // this is a safe substitute for an implicit converter to bool
390 typedef void (proxy_raw_object::*member_ptr
)() const;
391 operator member_ptr() const
393 if (is_valid()) return &proxy_raw_object::dummy
;
400 void dummy() const {}
402 proxy_raw_object(luabind::object
* o
, int key
)
408 luabind::object
* m_obj
;
414 class proxy_array_object
416 friend class luabind::object
;
417 friend class luabind::detail::proxy_object
;
418 friend class luabind::detail::proxy_raw_object
;
419 // template<class T> friend T object_cast(const proxy_array_object& obj);
423 proxy_array_object
& operator=(const T
& val
)
425 //std::cout << "array proxy assigment\n";
426 lua_State
* L
= m_obj
->m_state
;
428 detail::convert_to_lua(L
, val
);
429 lua_rawseti(L
, -2, m_key
);
436 proxy_array_object
& operator=(const object
& p
);
437 proxy_array_object
& operator=(const proxy_object
& p
);
438 proxy_array_object
& operator=(const proxy_raw_object
& p
);
439 proxy_array_object
& operator=(const proxy_array_object
& p
);
440 void swap(const proxy_array_object
& rhs
);
442 operator luabind::object();
447 detail::stack_pop
p(lua_state(), 1);
448 return lua_type(lua_state(), -1);
451 #define LUABIND_PROXY_ARRAY_RAW_AT_BODY \
454 detail::convert_to_lua(m_state, key); \
455 lua_rawget(m_state, -2); \
456 int ref = detail::ref(m_state); \
457 lua_pop(m_state, 1); \
458 return object(m_state, ref, true); \
461 #define LUABIND_PROXY_ARRAY_AT_BODY \
464 detail::convert_to_lua(m_state, key); \
465 lua_gettable(m_state, -2); \
466 int ref = detail::ref(m_state); \
467 lua_pop(m_state, 1); \
468 return object(m_state, ref, true); \
471 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
473 inline object
at(const T
& key
)
474 LUABIND_PROXY_ARRAY_AT_BODY
477 inline object
at(const T
& key
);
481 #if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
483 inline object
raw_at(const T
& key
)
484 LUABIND_PROXY_ARRAY_RAW_AT_BODY
487 inline object
raw_at(const T
& key
);
491 inline detail::proxy_object
operator[](const T
& key
) const
493 detail::convert_to_lua(m_state
, key
);
494 int ref
= detail::ref(m_state
);
495 return detail::proxy_object(const_cast<object
*>(this), ref
);
498 inline bool is_valid() const { return true; }
499 lua_State
* lua_state() const;
500 void pushvalue() const;
503 // this is a safe substitute for an implicit converter to bool
504 typedef void (proxy_array_object::*member_ptr
)() const;
505 operator member_ptr() const
507 if (is_valid()) return &proxy_array_object::dummy
;
513 void dummy() const {}
515 proxy_array_object(luabind::object
* o
, int key
)
520 luabind::object
* m_obj
;
525 struct primitive_converter
;
535 #if !(defined (BOOST_MSVC) && (BOOST_MSVC <= 1200))
538 friend T
object_cast(const object
& obj
);
540 friend struct detail::primitive_converter
;
544 friend object
get_globals(lua_State
*);
545 friend object
get_registry(lua_State
*);
546 friend object
newtable(lua_State
*);
547 friend class detail::proxy_object
;
548 friend class detail::proxy_array_object
;
549 friend class detail::proxy_raw_object
;
558 typedef std::forward_iterator_tag iterator_category
;
559 typedef luabind::object value_type
;
560 typedef value_type
& reference
;
561 typedef value_type
* pointer
;
562 typedef void difference_type
;
570 array_iterator(const array_iterator
& iter
)
578 array_iterator
& operator=(const array_iterator
& rhs
)
580 //std::cout << "===\n";
586 detail::proxy_array_object
operator*()
588 return m_obj
->make_array_proxy(m_key
);
591 inline array_iterator
& operator++()
595 // invalidate the iterator if we hit a nil element
596 lua_State
* L
= m_obj
->lua_state();
598 lua_rawgeti(L
, -1, m_key
);
599 if (lua_isnil(L
, -1)) m_key
= LUA_NOREF
;
605 inline array_iterator
operator++(int)
610 // invalidate the iterator if we hit a nil element
611 lua_State
* L
= m_obj
->lua_state();
613 lua_rawgeti(L
, -1, m_key
);
614 if (lua_isnil(L
, -1)) m_key
= LUA_NOREF
;
617 return array_iterator(m_obj
, old_key
);
620 bool operator!=(const array_iterator
& rhs
) const
622 return m_obj
!= rhs
.m_obj
|| m_key
!= rhs
.m_key
;
627 array_iterator(object
* obj
, int key
)
647 typedef std::forward_iterator_tag iterator_category
;
648 typedef luabind::object value_type
;
649 typedef value_type
& reference
;
650 typedef value_type
* pointer
;
651 typedef void difference_type
;
659 iterator(const iterator
& iter
)
665 lua_State
* L
= m_obj
->lua_state();
666 detail::getref(L
, iter
.m_key
);
667 m_key
= detail::ref(L
);
673 if (m_obj
&& m_key
!= LUA_NOREF
) detail::unref(m_obj
->lua_state(), m_key
);
676 iterator
& operator=(const iterator
& rhs
)
678 //std::cout << "===\n";
682 lua_State
* L
= m_obj
->lua_state();
683 detail::getref(L
, rhs
.m_key
);
684 m_key
= detail::ref(L
);
693 detail::proxy_object
operator*()
695 return m_obj
->make_proxy(m_key
);
698 iterator
& operator++()
700 lua_State
* L
= m_obj
->lua_state();
702 detail::getref(L
, m_key
);
704 if (lua_next(L
, -2) != 0)
707 lua_rawseti(L
, LUA_REGISTRYINDEX
, m_key
);
713 detail::unref(L
, m_key
);
721 bool operator!=(const iterator
& rhs
) const
723 return m_obj
!= rhs
.m_obj
|| m_key
!= rhs
.m_key
;
730 iterator(object
* obj
, int key
)
748 typedef std::forward_iterator_tag iterator_category
;
749 typedef luabind::object value_type
;
750 typedef value_type
& reference
;
751 typedef value_type
* pointer
;
752 typedef void difference_type
;
760 raw_iterator(const raw_iterator
& iter
)
766 lua_State
* L
= m_obj
->lua_state();
767 detail::getref(L
, iter
.m_key
);
768 m_key
= detail::ref(L
);
774 if (m_obj
&& m_key
!= LUA_NOREF
) detail::unref(m_obj
->lua_state(), m_key
);
777 raw_iterator
& operator=(const raw_iterator
& rhs
)
779 //std::cout << "===\n";
783 lua_State
* L
= m_obj
->lua_state();
784 detail::getref(L
, rhs
.m_key
);
785 m_key
= detail::ref(L
);
794 detail::proxy_raw_object
operator*()
796 return m_obj
->make_raw_proxy(m_key
);
799 raw_iterator
& operator++()
801 lua_State
* L
= m_obj
->lua_state();
803 detail::getref(L
, m_key
);
805 if (lua_next(L
, -2) != 0)
808 lua_rawseti(L
, LUA_REGISTRYINDEX
, m_key
);
814 detail::unref(L
, m_key
);
822 bool operator!=(const raw_iterator
& rhs
) const
824 return m_obj
!= rhs
.m_obj
|| m_key
!= rhs
.m_key
;
829 raw_iterator(object
* obj
, int key
)
857 object(lua_State
* L
, const T
& val
)
864 object(const object
& o
)
868 lua_getref(m_state
, o
.m_ref
);
869 m_ref
= detail::ref(m_state
);
874 // If you crash in the detail::unref() call you have probably
875 // closed the lua_State before destructing all object instances.
876 if (m_ref
!= LUA_NOREF
) detail::unref(m_state
, m_ref
);
879 inline bool is_valid() const { return m_ref
!= LUA_NOREF
; }
881 // this is a safe substitute for an implicit converter to bool
882 typedef void (object::*member_ptr
)() const;
883 operator member_ptr() const
885 if (is_valid()) return &object::dummy
;
892 detail::stack_pop
p(lua_state(), 1);
893 return lua_type(lua_state(), -1);
896 inline iterator
begin() const
898 lua_getref(m_state
, m_ref
);
899 lua_pushnil(m_state
);
900 lua_next(m_state
, -2);
902 iterator
i(const_cast<object
*>(this), detail::ref(m_state
));
907 inline iterator
end() const
909 return iterator(0, LUA_NOREF
);
912 inline array_iterator
abegin() const
914 return array_iterator(const_cast<object
*>(this), 1);
917 inline array_iterator
aend() const
919 return array_iterator(const_cast<object
*>(this), LUA_NOREF
);
922 raw_iterator
raw_begin() const
924 lua_getref(m_state
, m_ref
);
925 lua_pushnil(m_state
);
926 lua_next(m_state
, -2);
928 raw_iterator
i(const_cast<object
*>(this), detail::ref(m_state
));
933 raw_iterator
raw_end() const
935 return raw_iterator(0, LUA_NOREF
);
938 inline void set() const
940 // you are trying to access an invalid object
941 assert((m_state
!= 0) && "you are trying to access an invalid (uninitialized) object");
944 lua_rawseti(m_state
, LUA_REGISTRYINDEX
, m_ref
);
946 inline lua_State
* lua_state() const { return m_state
; }
947 inline void pushvalue() const
949 // you are trying to dereference an invalid object
950 assert((m_ref
!= LUA_NOREF
) && "you are trying to access an invalid (uninitialized) object");
951 assert((m_state
!= 0) && "internal error, please report");
953 lua_getref(m_state
, m_ref
);
956 void swap(object
& rhs
);
959 inline object
raw_at(const T
& key
)
961 lua_State
* L
= lua_state();
963 detail::convert_to_lua(L
, key
);
965 int ref
= detail::ref(L
);
967 return object(L
, ref
, true);
971 inline object
at(const T
& key
)
973 lua_State
* L
= lua_state();
975 detail::convert_to_lua(L
, key
);
977 int ref
= detail::ref(L
);
979 return object(L
, ref
, true);
983 inline detail::proxy_object
operator[](const T
& key
) const
985 detail::convert_to_lua(m_state
, key
);
986 int ref
= detail::ref(m_state
);
987 return detail::proxy_object(const_cast<object
*>(this), ref
);
992 // *****************************
995 object
& operator=(const object
& o
) const;
996 object
& operator=(const detail::proxy_object
& o
) const;
997 object
& operator=(const detail::proxy_raw_object
& o
) const;
998 object
& operator=(const detail::proxy_array_object
& o
) const;
1001 object
& operator=(const T
& val
) const
1003 assert((m_state
!= 0) && "you cannot assign a non-lua value to an uninitialized object");
1004 // you cannot assign a non-lua value to an uninitialized object
1006 detail::convert_to_lua(m_state
, val
);
1008 return const_cast<luabind::object
&>(*this);
1012 // *****************************
1015 #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, <luabind/object.hpp>, 1))
1016 #include BOOST_PP_ITERATE()
1020 inline detail::proxy_object
make_proxy(int key
)
1022 return detail::proxy_object(this, key
);
1025 inline detail::proxy_raw_object
make_raw_proxy(int key
)
1027 return detail::proxy_raw_object(this, key
);
1030 inline detail::proxy_array_object
make_array_proxy(int key
)
1032 return detail::proxy_array_object(this, key
);
1035 // TODO: it's not possible to make object friend with wrapped_constructor_helper::apply (since
1036 // it's an inner class), that's why this interface is public
1039 object(lua_State
* L
, int ref
, bool/*, reference*/)
1047 void dummy() const {}
1049 void allocate_slot() const
1051 if (m_ref
== LUA_NOREF
)
1053 lua_pushboolean(m_state
, 0);
1054 m_ref
= detail::ref(m_state
);
1058 mutable lua_State
* m_state
;
1063 // *************************************
1066 inline void object::swap(object
& rhs
)
1068 // you cannot swap objects from different lua states
1069 assert((lua_state() == rhs
.lua_state()) && "you cannot swap objects from different lua states");
1070 std::swap(m_ref
, rhs
.m_ref
);
1073 inline object
object::iterator::key() const
1075 lua_State
* L
= m_obj
->lua_state();
1076 detail::getref(L
, m_key
);
1077 return object(L
, detail::ref(L
), true);
1083 // *************************************
1086 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1087 template<class Tuple
>
1088 template<class Policies
>
1089 luabind::object proxy_caller
<Tuple
>::operator[](const Policies
& p
)
1092 lua_State
* L
= m_obj
->lua_state();
1094 detail::push_args_from_tuple
<1>::apply(L
, m_args
, p
);
1095 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 1, 0))
1097 #ifndef LUABIND_NO_EXCEPTIONS
1100 error_callback_fun e
= detail::error_callback::get().err
;
1103 assert(0 && "the lua function threw an error and exceptions are disabled."
1104 "if you want to handle this error use luabind::set_error_callback()");
1108 int ref
= detail::ref(L
);
1109 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
1112 // *************************************
1115 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1117 inline object
proxy_object::raw_at(const T
& key
)
1118 LUABIND_PROXY_RAW_AT_BODY
1121 inline object
proxy_object::at(const T
& key
)
1122 LUABIND_PROXY_AT_BODY
1125 inline lua_State
* proxy_object::lua_state() const
1127 return m_obj
->lua_state();
1130 inline proxy_object::operator luabind::object()
1132 lua_State
* L
= m_obj
->lua_state();
1134 int ref
= detail::ref(L
);
1135 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1139 // *************************************
1140 // PROXY ARRAY OBJECT
1142 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1144 inline object
proxy_array_object::raw_at(const T
& key
)
1145 LUABIND_PROXY_ARRAY_RAW_AT_BODY
1148 inline object
proxy_array_object::at(const T
& key
)
1149 LUABIND_PROXY_ARRAY_AT_BODY
1152 #undef LUABIND_PROXY_ARRAY_AT_BODY
1153 #undef LUABIND_PROXY_ARRAY_RAW_AT_BODY
1155 inline lua_State
* proxy_array_object::lua_state() const
1157 return m_obj
->lua_state();
1160 inline proxy_array_object::operator luabind::object()
1162 lua_State
* L
= m_obj
->lua_state();
1164 int ref
= detail::ref(L
);
1165 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1169 // *************************************
1172 #if !defined(BOOST_MSVC) || (defined(BOOST_MSVC) && (BOOST_MSVC > 1300))
1174 inline object
proxy_raw_object::raw_at(const T
& key
)
1175 LUABIND_PROXY_RAW_AT_BODY
1178 inline object
proxy_raw_object::at(const T
& key
)
1179 LUABIND_PROXY_AT_BODY
1182 #undef LUABIND_PROXY_RAW_AT_BODY
1183 #undef LUABIND_PROXY_AT_BODY
1185 inline lua_State
* proxy_raw_object::lua_state() const
1187 return m_obj
->lua_state();
1190 inline proxy_raw_object::operator luabind::object()
1192 lua_State
* L
= lua_state();
1194 int ref
= detail::ref(L
);
1195 return luabind::object(L
, ref
, true/*luabind::object::reference()*/);
1199 // *************************************
1203 template<class Tuple
>
1204 proxy_caller
<Tuple
>::~proxy_caller()
1206 if (m_called
) return;
1209 lua_State
* L
= m_obj
->lua_state();
1212 push_args_from_tuple
<1>::apply(L
, m_args
);
1213 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 0, 0))
1215 #ifndef LUABIND_NO_EXCEPTIONS
1216 throw luabind::error(L
);
1218 error_callback_fun e
= detail::error_callback::get().err
;
1221 assert(0 && "the lua function threw an error and exceptions are disabled."
1222 "if you want to handle this error use luabind::set_error_callback()");
1228 template<class Tuple
>
1229 proxy_caller
<Tuple
>::operator luabind::object()
1232 lua_State
* L
= m_obj
->lua_state();
1235 push_args_from_tuple
<1>::apply(L
, m_args
);
1236 if (lua_pcall(L
, boost::tuples::length
<Tuple
>::value
, 1, 0))
1238 #ifndef LUABIND_NO_EXCEPTIONS
1239 throw luabind::error(L
);
1241 error_callback_fun e
= detail::error_callback::get().err
;
1244 assert(0 && "the lua function threw an error and exceptions are disabled."
1245 "if you want to handle this error use luabind::set_error_callback()");
1249 int ref
= detail::ref(L
);
1250 return luabind::object(m_obj
->lua_state(), ref
, true/*luabind::object::reference()*/);
1255 #define LUABIND_DECLARE_OPERATOR(MACRO)\
1256 MACRO(object, object) \
1257 MACRO(object, detail::proxy_object) \
1258 MACRO(object, detail::proxy_array_object) \
1259 MACRO(object, detail::proxy_raw_object) \
1260 MACRO(detail::proxy_object, object) \
1261 MACRO(detail::proxy_object, detail::proxy_object) \
1262 MACRO(detail::proxy_object, detail::proxy_array_object) \
1263 MACRO(detail::proxy_object, detail::proxy_raw_object) \
1264 MACRO(detail::proxy_array_object, object) \
1265 MACRO(detail::proxy_array_object, detail::proxy_object) \
1266 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
1267 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
1268 MACRO(detail::proxy_raw_object, object) \
1269 MACRO(detail::proxy_raw_object, detail::proxy_object) \
1270 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
1271 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
1274 #define LUABIND_EQUALITY_OPERATOR(lhs, rhs) bool operator==(const lhs&, const rhs&);
1275 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR
)
1276 #undef LUABIND_EQUALITY_OPERATOR
1278 #define LUABIND_LESSTHAN_OPERATOR(lhs, rhs) bool operator<(const lhs&, const rhs&);
1279 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR
)
1280 #undef LUABIND_LESSTHAN_OPERATOR
1282 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t) bool operator<=(const lhs_t&, const rhs_t&);
1283 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR
)
1284 #undef LUABIND_LESSOREQUAL_OPERATOR
1286 #define LUABIND_INEQUALITY_OPERATOR(lhs_t, rhs_t)\
1287 inline bool operator!=(const rhs_t& rhs, const lhs_t& lhs) \
1289 return !(rhs == lhs); \
1292 LUABIND_DECLARE_OPERATOR(LUABIND_INEQUALITY_OPERATOR
)
1294 #undef LUABIND_INEQUALITY_OPERATOR
1296 #define LUABIND_GREATEROREQUAL_OPERATOR(lhs_t, rhs_t)\
1297 inline bool operator>=(const rhs_t& rhs, const lhs_t& lhs) \
1299 return !(rhs < lhs); \
1302 LUABIND_DECLARE_OPERATOR(LUABIND_GREATEROREQUAL_OPERATOR
)
1304 #undef LUABIND_GREATEROREQUAL_OPERATOR
1306 #define LUABIND_GREATERTHAN_OPERATOR(lhs_t, rhs_t)\
1307 inline bool operator>(const lhs_t& lhs, const rhs_t& rhs) \
1309 return !(lhs <= rhs); \
1312 LUABIND_DECLARE_OPERATOR(LUABIND_GREATERTHAN_OPERATOR
)
1313 #undef LUABIND_GREATERTHAN_OPERATOR
1315 #undef LUABIND_DECLARE_OPERATOR
1322 #define LUABIND_DEFINE_SWAP(t1,t2)\
1323 inline void swap(t1 lhs, t2 rhs)\
1325 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot swap objects from different lua states");\
1332 inline void swap(luabind::object
& lhs
, luabind::object
& rhs
)
1337 // object against all other
1338 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_object
&)
1339 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_raw_object
&)
1340 LUABIND_DEFINE_SWAP(luabind::object
&, const luabind::detail::proxy_array_object
&)
1341 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, luabind::object
&)
1342 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, luabind::object
&)
1343 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, luabind::object
&)
1345 // proxy_object against all other
1346 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_object
&)
1347 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_raw_object
&)
1348 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_object
&, const luabind::detail::proxy_array_object
&)
1349 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_object
&)
1350 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_object
&)
1352 // proxy_raw_object against all other
1353 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_raw_object
&)
1354 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_raw_object
&, const luabind::detail::proxy_array_object
&)
1355 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_raw_object
&)
1357 // proxy_array_object against all other
1358 LUABIND_DEFINE_SWAP(const luabind::detail::proxy_array_object
&, const luabind::detail::proxy_array_object
&)
1360 #undef LUABIND_DEFINE_SWAP
1364 #endif // LUABIND_OBJECT_HPP_INCLUDED
1366 #elif BOOST_PP_ITERATION_FLAGS() == 1
1368 #define LUABIND_TUPLE_PARAMS(z, n, data) const A##n *
1369 #define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n
1371 #if BOOST_PP_ITERATION() > 0
1372 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), class A
)>
1374 detail::proxy_caller
<boost::tuples::tuple
<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS
, _
)> >
1375 operator()(BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS
, _
)) const
1377 typedef boost::tuples::tuple
<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS
, _
)> tuple_t
;
1378 #if BOOST_PP_ITERATION() == 0
1381 tuple_t
args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a
));
1383 return detail::proxy_caller
<tuple_t
>(const_cast<luabind::object
*>(this), args
);
1386 #undef LUABIND_OPERATOR_PARAMS
1387 #undef LUABIND_TUPLE_PARAMS