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 #include <luabind/lua_include.hpp>
25 #include <luabind/luabind.hpp>
26 #include <luabind/detail/implicit_cast.hpp>
28 using namespace luabind::detail
;
36 // *************************************
39 #define LUABIND_PROXY_ASSIGNMENT_OPERATOR(rhs)\
40 proxy_object& proxy_object::operator=(const rhs& p) \
42 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
43 lua_State* L = lua_state(); \
47 lua_settable(L, -3); \
52 LUABIND_PROXY_ASSIGNMENT_OPERATOR(object
)
53 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
54 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
55 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
57 #undef LUABIND_PROXY_ASSIGNMENT_OPERATOR
59 void proxy_object::pushvalue() const
61 assert((m_key
.is_valid()) && "you cannot call pushvalue() on an uninitialized object");
63 lua_State
* L
= m_obj
->lua_state();
67 // remove the table and leave the value on top of the stack
71 void proxy_object::set() const
73 lua_State
* L
= lua_state();
78 // pop table and value
84 // *************************************
89 #define LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(rhs)\
90 proxy_array_object& proxy_array_object::operator=(const rhs& p) \
92 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
93 lua_State* L = lua_state(); \
96 lua_rawseti(L, -2, m_key); \
101 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(object
)
102 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
103 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
104 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
106 #undef LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR
108 void proxy_array_object::pushvalue() const
110 // you are trying to dereference an invalid object
111 assert((m_key
!= -1) && "you cannot call pushvalue() on an uninitialized object");
113 lua_State
* L
= m_obj
->lua_state();
115 lua_rawgeti(L
, -1, m_key
);
119 void proxy_array_object::set() const
121 lua_State
* L
= lua_state();
123 lua_pushvalue(L
, -2);
124 lua_rawseti(L
, -2, m_key
);
125 // pop table and value
130 // *************************************
134 #define LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(rhs)\
135 proxy_raw_object& proxy_raw_object::operator=(const rhs& p) \
137 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
138 lua_State* L = lua_state(); \
139 m_obj->pushvalue(); \
147 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(object
)
148 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
149 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
150 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
152 #undef LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR
154 void proxy_raw_object::pushvalue() const
156 assert((m_key
.is_valid()) && "you cannot call pushvalue() on an uninitiallized object");
158 lua_State
* L
= lua_state();
162 // remove the table and leave the value on top of the stack
166 void proxy_raw_object::set() const
168 lua_State
* L
= lua_state();
171 lua_pushvalue(L
, -3);
173 // pop table and value
179 #define LUABIND_DECLARE_OPERATOR(MACRO)\
180 MACRO(object, object) \
181 MACRO(object, detail::proxy_object) \
182 MACRO(object, detail::proxy_array_object) \
183 MACRO(object, detail::proxy_raw_object) \
184 MACRO(detail::proxy_object, object) \
185 MACRO(detail::proxy_object, detail::proxy_object) \
186 MACRO(detail::proxy_object, detail::proxy_array_object) \
187 MACRO(detail::proxy_object, detail::proxy_raw_object) \
188 MACRO(detail::proxy_array_object, object) \
189 MACRO(detail::proxy_array_object, detail::proxy_object) \
190 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
191 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
192 MACRO(detail::proxy_raw_object, object) \
193 MACRO(detail::proxy_raw_object, detail::proxy_object) \
194 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
195 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
198 // *****************************
203 #define LUABIND_EQUALITY_OPERATOR(lhs_t, rhs_t)\
204 bool operator==(const lhs_t& lhs, const rhs_t& rhs) \
206 if (!lhs.is_valid()) return false; \
207 if (!rhs.is_valid()) return false; \
208 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
209 lua_State* L = lhs.lua_state(); \
212 bool result = lua_equal(L, -1, -2) != 0; \
217 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR
)
219 #undef LUABIND_EQUALITY_OPERATOR
222 // *****************************
225 #define LUABIND_ASSIGNMENT_OPERATOR(rhs)\
226 object& object::operator=(const rhs& o) const \
228 m_state = o.lua_state(); \
231 return const_cast<luabind::object&>(*this); \
234 LUABIND_ASSIGNMENT_OPERATOR(object
)
235 LUABIND_ASSIGNMENT_OPERATOR(proxy_object
)
236 LUABIND_ASSIGNMENT_OPERATOR(proxy_array_object
)
237 LUABIND_ASSIGNMENT_OPERATOR(proxy_raw_object
)
241 // *****************************
246 #define LUABIND_LESSTHAN_OPERATOR(lhs_t, rhs_t)\
247 bool operator<(const lhs_t& lhs, const rhs_t& rhs) \
249 if (!lhs.is_valid()) return false; \
250 if (!rhs.is_valid()) return false; \
251 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
252 lua_State* L = lhs.lua_state(); \
255 bool result = lua_lessthan(L, -1, -2) != 0; \
260 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR
)
262 #undef LUABIND_LESSTHAN_OPERATOR
264 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t)\
265 bool operator<=(const lhs_t& lhs, const rhs_t& rhs) \
267 if (!lhs.is_valid()) return false; \
268 if (!rhs.is_valid()) return false; \
269 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
270 lua_State* L = lhs.lua_state(); \
273 bool result1 = lua_lessthan(L, -1, -2) != 0; \
274 bool result2 = lua_equal(L, -1, -2) != 0; \
276 return result1 || result2; \
279 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR
)
281 #undef LUABIND_LESSOREQUAL_OPERATOR
283 #undef LUABIND_GREATERTHAN_OPERATOR
286 #undef LUABIND_DECLARE_OPERATOR