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 #ifndef LUABIND_OBJECT_PROXY_HPP_INCLUDED
24 #define LUABIND_OBJECT_PROXY_HPP_INCLUDED
26 #include <boost/optional.hpp>
28 #include <luabind/config.hpp>
29 #include <luabind/detail/policy.hpp>
30 #include <luabind/error.hpp>
31 #include <luabind/detail/convert_to_lua.hpp>
32 #include <luabind/detail/debug.hpp>
33 #include <luabind/detail/stack_utils.hpp>
35 #include <boost/mpl/apply_wrap.hpp>
43 namespace mpl
= boost::mpl
;
45 template<class T
, class Obj
, class Policies
>
46 inline T
object_cast_impl(const Obj
& obj
, const Policies
&)
48 if (obj
.lua_state() == 0)
50 #ifndef LUABIND_NO_EXCEPTIONS
51 throw cast_failed(0, typeid(T
));
53 lua_State
* L
= obj
.lua_state();
54 cast_failed_callback_fun e
= get_cast_failed_callback();
55 if (e
) e(L
, typeid(T
));
57 assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
62 LUABIND_CHECK_STACK(obj
.lua_state());
64 typedef typename
detail::find_conversion_policy
<0, Policies
>::type converter_policy
;
65 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
69 lua_State
* L
= obj
.lua_state();
70 detail::stack_pop
p(L
, 1);
72 #ifndef LUABIND_NO_ERROR_CHECKING
74 if (converter
.match(L
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
76 #ifndef LUABIND_NO_EXCEPTIONS
77 throw cast_failed(L
, typeid(T
));
79 cast_failed_callback_fun e
= get_cast_failed_callback();
80 if (e
) e(L
, typeid(T
));
82 assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
88 return converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), -1);
91 template<class T
, class Obj
, class Policies
>
92 boost::optional
<T
> object_cast_nothrow_impl(const Obj
& obj
, const Policies
&)
94 typedef typename
detail::find_conversion_policy
<0, Policies
>::type converter_policy
;
95 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
97 if (obj
.lua_state() == 0) return boost::optional
<T
>();
98 LUABIND_CHECK_STACK(obj
.lua_state());
102 lua_State
* L
= obj
.lua_state();
103 detail::stack_pop
p(L
, 1);
105 #ifndef LUABIND_NO_ERROR_CHECKING
107 if (converter
.match(L
, LUABIND_DECORATE_TYPE(T
), -1) < 0)
108 return boost::optional
<T
>();
111 return boost::optional
<T
>(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), -1));
116 T
object_cast(const object
& obj
)
117 { return detail::object_cast_impl
<T
>(obj
, detail::null_type()); }
119 template<class T
, class Policies
>
120 T
object_cast(const object
& obj
, const Policies
& p
)
121 { return detail::object_cast_impl
<T
>(obj
, p
); }
124 boost::optional
<T
> object_cast_nothrow(const object
& obj
)
125 { return detail::object_cast_nothrow_impl
<T
>(obj
, detail::null_type()); }
127 template<class T
, class Policies
>
128 boost::optional
<T
> object_cast_nothrow(const object
& obj
, const Policies
& p
)
129 { return detail::object_cast_nothrow_impl
<T
>(obj
, p
); }
133 T
object_cast(const detail::proxy_object
& obj
)
134 { return detail::object_cast_impl
<T
>(obj
, detail::null_type()); }
136 template<class T
, class Policies
>
137 T
object_cast(const detail::proxy_object
& obj
, const Policies
& p
)
138 { return detail::object_cast_impl
<T
>(obj
, p
); }
141 boost::optional
<T
> object_cast_nothrow(const detail::proxy_object
& obj
)
142 { return detail::object_cast_nothrow_impl
<T
>(obj
, detail::null_type()); }
144 template<class T
, class Policies
>
145 boost::optional
<T
> object_cast_nothrow(const detail::proxy_object
& obj
, const Policies
& p
)
146 { return detail::object_cast_nothrow_impl
<T
>(obj
, p
); }
150 T
object_cast(const detail::proxy_raw_object
& obj
)
151 { return detail::object_cast_impl
<T
>(obj
, detail::null_type()); }
153 template<class T
, class Policies
>
154 T
object_cast(const detail::proxy_raw_object
& obj
, const Policies
& p
)
155 { return detail::object_cast_impl
<T
>(obj
, p
); }
158 boost::optional
<T
> object_cast_nothrow(const detail::proxy_raw_object
& obj
)
159 { return detail::object_cast_nothrow_impl
<T
>(obj
, detail::null_type()); }
161 template<class T
, class Policies
>
162 boost::optional
<T
> object_cast_nothrow(const detail::proxy_raw_object
& obj
, const Policies
& p
)
163 { return detail::object_cast_nothrow_impl
<T
>(obj
, p
); }
167 T
object_cast(const detail::proxy_array_object
& obj
)
168 { return detail::object_cast_impl
<T
>(obj
, detail::null_type()); }
170 template<class T
, class Policies
>
171 T
object_cast(const detail::proxy_array_object
& obj
, const Policies
& p
)
172 { return detail::object_cast_impl
<T
>(obj
, p
); }
175 boost::optional
<T
> object_cast_nothrow(const detail::proxy_array_object
& obj
)
176 { return detail::object_cast_nothrow_impl
<T
>(obj
, detail::null_type()); }
178 template<class T
, class Policies
>
179 boost::optional
<T
> object_cast_nothrow(const detail::proxy_array_object
& obj
, const Policies
& p
)
180 { return detail::object_cast_nothrow_impl
<T
>(obj
, p
); }
185 inline object
get_globals(lua_State
* L
)
187 lua_pushvalue(L
, LUA_GLOBALSINDEX
);
188 detail::lua_reference ref
;
190 return object(L
, ref
, true/*object::reference()*/);
193 inline object
get_registry(lua_State
* L
)
195 lua_pushvalue(L
, LUA_REGISTRYINDEX
);
196 detail::lua_reference ref
;
198 return object(L
, ref
, true/*object::reference()*/);
201 inline object
newtable(lua_State
* L
)
204 detail::lua_reference ref
;
206 return object(L
, ref
, true/*object::reference()*/);
216 object f = class_<A>();
218 A* ptr = object_cast<A*>(f(), adopt(_1));
224 #endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED