*** empty log message ***
[luabind.git] / src / object.cpp
blobb99087377df663ea138bcacbdcb2b6e280220123
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;
30 namespace luabind
32 namespace detail
36 // *************************************
37 // PROXY OBJECT
39 #define LUABIND_PROXY_ASSIGNMENT_OPERATOR(rhs)\
40 proxy_object& proxy_object::operator=(const rhs& p) \
41 { \
42 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
43 lua_State* L = lua_state(); \
44 m_obj->pushvalue(); \
45 m_key.get(L);\
46 p.pushvalue(); \
47 lua_settable(L, -3); \
48 lua_pop(L, 1); \
49 return *this; \
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();
64 m_obj->pushvalue();
65 m_key.get(L);
66 lua_gettable(L, -2);
67 // remove the table and leave the value on top of the stack
68 lua_remove(L, -2);
71 void proxy_object::set() const
73 lua_State* L = lua_state();
74 m_obj->pushvalue();
75 m_key.get(L);
76 lua_pushvalue(L, -3);
77 lua_settable(L, -3);
78 // pop table and value
79 lua_pop(L, 2);
84 // *************************************
85 // PROXY ARRAY OBJECT
89 #define LUABIND_ARRAY_PROXY_ASSIGNMENT_OPERATOR(rhs)\
90 proxy_array_object& proxy_array_object::operator=(const rhs& p) \
91 { \
92 assert((lua_state() == p.lua_state()) && "you cannot assign a value from a different lua state"); \
93 lua_State* L = lua_state(); \
94 m_obj->pushvalue(); \
95 p.pushvalue(); \
96 lua_rawseti(L, -2, m_key); \
97 lua_pop(L, 1); \
98 return *this; \
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();
114 m_obj->pushvalue();
115 lua_rawgeti(L, -1, m_key);
116 lua_remove(L, -2);
119 void proxy_array_object::set() const
121 lua_State* L = lua_state();
122 m_obj->pushvalue();
123 lua_pushvalue(L, -2);
124 lua_rawseti(L, -2, m_key);
125 // pop table and value
126 lua_pop(L, 2);
130 // *************************************
131 // PROXY RAW OBJECT
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(); \
140 m_key.get(L);\
141 p.pushvalue(); \
142 lua_rawset(L, -3); \
143 lua_pop(L, 1); \
144 return *this; \
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();
159 m_obj->pushvalue();
160 m_key.get(L);
161 lua_rawget(L, -2);
162 // remove the table and leave the value on top of the stack
163 lua_remove(L, -2);
166 void proxy_raw_object::set() const
168 lua_State* L = lua_state();
169 m_obj->pushvalue();
170 m_key.get(L);
171 lua_pushvalue(L, -3);
172 lua_rawset(L, -3);
173 // pop table and value
174 lua_pop(L, 2);
177 } // detail
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 // *****************************
199 // OPERATOR ==
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(); \
210 lhs.pushvalue(); \
211 rhs.pushvalue(); \
212 bool result = lua_equal(L, -1, -2) != 0; \
213 lua_pop(L, 2); \
214 return result; \
217 LUABIND_DECLARE_OPERATOR(LUABIND_EQUALITY_OPERATOR)
219 #undef LUABIND_EQUALITY_OPERATOR
222 // *****************************
223 // OPERATOR =
225 #define LUABIND_ASSIGNMENT_OPERATOR(rhs)\
226 object& object::operator=(const rhs& o) const \
228 m_state = o.lua_state(); \
229 o.pushvalue(); \
230 set(); \
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 // *****************************
242 // OPERATOR ==
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(); \
253 lhs.pushvalue(); \
254 rhs.pushvalue(); \
255 bool result = lua_lessthan(L, -1, -2) != 0; \
256 lua_pop(L, 2); \
257 return result; \
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(); \
271 lhs.pushvalue(); \
272 rhs.pushvalue(); \
273 bool result1 = lua_lessthan(L, -1, -2) != 0; \
274 bool result2 = lua_equal(L, -1, -2) != 0; \
275 lua_pop(L, 2); \
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