fixed bug with holders and properties
[luabind.git] / luabind / detail / property.hpp
blob547bd7649d16a285cb417a751dcedda5f57e555e
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.
24 #ifndef LUABIND_PROPERTY_HPP_INCLUDED
25 #define LUABIND_PROPERTY_HPP_INCLUDED
27 #include <luabind/config.hpp>
29 namespace luabind { namespace detail
31 class object_rep;
33 template<class R, class T, class Policies>
34 int get(R(T::*f)() const, T* obj, lua_State* L, Policies* policies) { return returns<R>::call(f, obj, L, policies); }
36 template<class R, class T, class Policies>
37 int get(R(*f)(const T*), T* obj, lua_State* L, Policies* policies) { return returns<R>::call(f, obj, L, policies); }
39 template<class R, class T, class Policies>
40 int get(R(*f)(const T&), T* obj, lua_State* L, Policies* policies) { return returns<R>::call(f, obj, L, policies); }
43 template<class R, class T, class Policies>
44 int get(R(T::*f)() const, T* obj, lua_State* L, Policies* policies) { return returns<R>::call(f, obj, L, policies); }
46 template<class R, class T, class U, class Policies>
47 int get(R(*f)(T), U* obj, lua_State* L, Policies* policies) { return returns<R>::call(f, obj, L, policies); }
49 template<class T, class F, class Policies>
50 struct get_caller : Policies
52 get_caller() {}
53 get_caller(const Policies& p): Policies(p) {}
55 int operator()(lua_State* L, int pointer_offset, F f)
57 // parameters on the lua stack:
58 // 1. object_rep
59 // 2. key (property name)
61 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
62 class_rep* crep = obj->crep();
64 void* ptr;
66 if (crep->has_holder())
67 ptr = crep->extractor()(obj->ptr());
68 else
69 ptr = obj->ptr();
71 return get(f, reinterpret_cast<T*>(static_cast<char*>(ptr) + pointer_offset), L, static_cast<Policies*>(this));
75 template<class T, class A1, class Policies>
76 int set(void(T::*f)(A1), T* obj, lua_State* L, Policies* policies) { return returns<void>::call(f, obj, L, policies); }
78 template<class R, class T, class A1, class Policies>
79 int set(void(*f)(T*, A1), T* obj, lua_State* L, Policies* policies) { return returns<void>::call(f, obj, L, policies); }
81 template<class T, class A1, class Policies>
82 int set(void(*f)(T&, A1), T* obj, lua_State* L, Policies* policies) { return returns<void>::call(f, obj, L, policies); }
85 template<class T, class U, class A1, class Policies>
86 int set(void(*f)(T, A1), U* obj, lua_State* L, Policies* policies) { return returns<void>::call(f, obj, L, policies); }
88 template<class T, class F, class Policies>
89 struct set_caller : Policies
91 int operator()(lua_State* L, int pointer_offset, F f)
93 // parameters on the lua stack:
94 // 1. object_rep
95 // 2. key (property name)
96 // 3. value
98 // and since call() expects it's first
99 // parameter on index 2 we need to
100 // remove the key-parameter (parameter 2).
101 object_rep* obj = reinterpret_cast<object_rep*>(lua_touserdata(L, 1));
102 class_rep* crep = obj->crep();
104 void* ptr;
106 if (crep->has_holder())
107 ptr = crep->extractor()(obj->ptr());
108 else
109 ptr = obj->ptr();
111 lua_remove(L, 2);
112 return set(f, reinterpret_cast<T*>(static_cast<char*>(ptr) + pointer_offset), L, static_cast<Policies*>(this));
116 // TODO: add support for policies
117 template<class T, class D, class Policies>
118 struct auto_set : Policies
120 auto_set() {}
121 auto_set(const Policies& p): Policies(p) {}
123 int operator()(lua_State* L, int pointer_offset, D T::*member)
125 int nargs = lua_gettop(L);
127 // parameters on the lua stack:
128 // 1. object_rep
129 // 2. key (property name)
130 // 3. value
131 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
132 class_rep* crep = obj->crep();
134 void* raw_ptr;
136 if (crep->has_holder())
137 raw_ptr = crep->extractor()(obj->ptr());
138 else
139 raw_ptr = obj->ptr();
141 T* ptr = reinterpret_cast<T*>(static_cast<char*>(raw_ptr) + pointer_offset);
143 typedef typename find_conversion_policy<1,Policies>::type converter_policy;
144 typename converter_policy::template generate_converter<D,lua_to_cpp>::type converter;
145 ptr->*member = converter.apply(L, LUABIND_DECORATE_TYPE(D), 3);
147 int nret = lua_gettop(L) - nargs;
149 const int indices[] = { 1, nargs + nret, 3 };
151 policy_list_postcall<Policies>::apply(L, indices);
153 return nret;
157 // TODO: add support for policies
158 template<class T, class D, class Policies>
159 struct auto_get : Policies
161 auto_get() {}
162 auto_get(const Policies& p): Policies(p) {}
164 int operator()(lua_State* L, int pointer_offset, D T::*member)
166 int nargs = lua_gettop(L);
168 // parameters on the lua stack:
169 // 1. object_rep
170 // 2. key (property name)
171 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
172 class_rep* crep = obj->crep();
174 void* raw_ptr;
176 if (crep->has_holder())
177 raw_ptr = crep->extractor()(obj->ptr());
178 else
179 raw_ptr = obj->ptr();
181 T* ptr = reinterpret_cast<T*>(static_cast<char*>(raw_ptr) + pointer_offset);
183 typedef typename find_conversion_policy<0,Policies>::type converter_policy;
184 typename converter_policy::template generate_converter<D,cpp_to_lua>::type converter;
185 converter.apply(L, ptr->*member);
187 int nret = lua_gettop(L) - nargs;
189 const int indices[] = { 1, nargs + nret };
191 policy_list_postcall<Policies>::apply(L, indices);
193 return nret;
199 #endif // LUABIND_PROPERTY_HPP_INCLUDED