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.
28 #include <luabind/luabind.hpp>
29 #include <luabind/detail/implicit_cast.hpp>
31 using namespace luabind::detail
;
39 // *************************************
42 #define LUABIND_PROXY_ASSIGNMENT_OPERATOR(rhs)\
43 proxy_object& proxy_object::operator=(const rhs& p) \
45 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
46 lua_State* L = lua_state(); \
48 detail::getref(L, m_key_ref); \
50 lua_settable(L, -3); \
55 LUABIND_PROXY_ASSIGNMENT_OPERATOR(object
)
56 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
57 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
58 LUABIND_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
60 #undef LUABIND_PROXY_ASSIGNMENT_OPERATOR
62 void proxy_object::pushvalue() const
64 assert((m_key_ref
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitialized object");
66 lua_State
* L
= m_obj
->lua_state();
68 detail::getref(L
, m_key_ref
);
70 // remove the table and leave the value on top of the stack
74 void proxy_object::set() const
76 lua_State
* L
= lua_state();
78 detail::getref(L
, m_key_ref
);
81 // pop table and value
87 // *************************************
92 #define LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(rhs)\
93 proxy_array_object& proxy_array_object::operator=(const rhs& p) \
95 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
96 lua_State* L = lua_state(); \
99 lua_rawseti(L, -2, m_key); \
104 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(object
)
105 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
106 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
107 LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
109 #undef LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR
111 void proxy_array_object::pushvalue() const
113 // you are trying to dereference an invalid object
114 assert((m_key
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitialized object");
116 lua_State
* L
= m_obj
->lua_state();
118 lua_rawgeti(L
, -1, m_key
);
122 void proxy_array_object::set() const
124 lua_State
* L
= lua_state();
126 lua_pushvalue(L
, -2);
127 lua_rawseti(L
, -2, m_key
);
128 // pop table and value
133 // *************************************
137 #define LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(rhs)\
138 proxy_raw_object& proxy_raw_object::operator=(const rhs& p) \
140 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
141 lua_State* L = lua_state(); \
142 m_obj->pushvalue(); \
143 detail::getref(L, m_key_ref); \
150 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(object
)
151 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_object
)
152 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_raw_object
)
153 LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR(proxy_array_object
)
155 #undef LUABIND_RAW_PROXY_ASSIGNMENT_OPERATOR
157 void proxy_raw_object::pushvalue() const
159 assert((m_key_ref
!= LUA_NOREF
) && "you cannot call pushvalue() on an uninitiallized object");
161 lua_State
* L
= lua_state();
163 detail::getref(L
, m_key_ref
);
165 // remove the table and leave the value on top of the stack
169 void proxy_raw_object::set() const
171 lua_State
* L
= lua_state();
173 detail::getref(L
, m_key_ref
);
174 lua_pushvalue(L
, -3);
176 // pop table and value
182 #define LUABIND_DECLARE_OPERATOR(MACRO)\
183 MACRO(object, object) \
184 MACRO(object, detail::proxy_object) \
185 MACRO(object, detail::proxy_array_object) \
186 MACRO(object, detail::proxy_raw_object) \
187 MACRO(detail::proxy_object, object) \
188 MACRO(detail::proxy_object, detail::proxy_object) \
189 MACRO(detail::proxy_object, detail::proxy_array_object) \
190 MACRO(detail::proxy_object, detail::proxy_raw_object) \
191 MACRO(detail::proxy_array_object, object) \
192 MACRO(detail::proxy_array_object, detail::proxy_object) \
193 MACRO(detail::proxy_array_object, detail::proxy_array_object) \
194 MACRO(detail::proxy_array_object, detail::proxy_raw_object) \
195 MACRO(detail::proxy_raw_object, object) \
196 MACRO(detail::proxy_raw_object, detail::proxy_object) \
197 MACRO(detail::proxy_raw_object, detail::proxy_array_object) \
198 MACRO(detail::proxy_raw_object, detail::proxy_raw_object)
201 // *****************************
206 #define LUABIND_EQUALITY_OPERATOR(lhs_t, rhs_t)\
207 bool operator==(const lhs_t& lhs, const rhs_t& rhs) \
209 if (!lhs.is_valid()) return false; \
210 if (!rhs.is_valid()) return false; \
211 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
212 lua_State* L = lhs.lua_state(); \
215 bool result = lua_equal(L, -1, -2) != 0; \
220 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR
)
222 #undef LUABIND_EQUALITY_OPERATOR
225 // *****************************
228 #define LUABIND_ASSIGNMENT_OPERATOR(rhs)\
229 object& object::operator=(const rhs& o) const \
231 m_state = o.lua_state(); \
234 return const_cast<luabind::object&>(*this); \
237 LUABIND_ASSIGNMENT_OPERATOR(object
)
238 LUABIND_ASSIGNMENT_OPERATOR(proxy_object
)
239 LUABIND_ASSIGNMENT_OPERATOR(proxy_array_object
)
240 LUABIND_ASSIGNMENT_OPERATOR(proxy_raw_object
)
244 // *****************************
249 #define LUABIND_LESSTHAN_OPERATOR(lhs_t, rhs_t)\
250 bool operator<(const lhs_t& lhs, const rhs_t& rhs) \
252 if (!lhs.is_valid()) return false; \
253 if (!rhs.is_valid()) return false; \
254 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
255 lua_State* L = lhs.lua_state(); \
258 bool result = lua_lessthan(L, -1, -2) != 0; \
263 LUABIND_DECLARE_OPERATOR(LUABIND_LESSTHAN_OPERATOR
)
265 #undef LUABIND_LESSTHAN_OPERATOR
267 #define LUABIND_LESSOREQUAL_OPERATOR(lhs_t, rhs_t)\
268 bool operator<=(const lhs_t& lhs, const rhs_t& rhs) \
270 if (!lhs.is_valid()) return false; \
271 if (!rhs.is_valid()) return false; \
272 assert((lhs.lua_state() == rhs.lua_state()) && "you cannot compare objects from different lua states"); \
273 lua_State* L = lhs.lua_state(); \
276 bool result1 = lua_lessthan(L, -1, -2) != 0; \
277 bool result2 = lua_equal(L, -1, -2) != 0; \
279 return result1 || result2; \
282 LUABIND_DECLARE_OPERATOR(LUABIND_LESSOREQUAL_OPERATOR
)
284 #undef LUABIND_LESSOREQUAL_OPERATOR
286 #undef LUABIND_GREATERTHAN_OPERATOR
289 #undef LUABIND_DECLARE_OPERATOR