Initial commit, includes Lua with broken Luabind as a backup for branching purposes
[terrastrategy.git] / include / luabind / detail / object_funs.hpp
blobbfecf120786bc451e8b042e22d0c63aea0ff8d9e
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>
37 namespace luabind
40 namespace detail
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, LUABIND_TYPEID(T));
52 #else
53 lua_State* L = obj.lua_state();
54 cast_failed_callback_fun e = get_cast_failed_callback();
55 if (e) e(L, LUABIND_TYPEID(T));
57 assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
58 std::terminate();
59 #endif
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;
67 obj.pushvalue();
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, LUABIND_TYPEID(T));
78 #else
79 cast_failed_callback_fun e = get_cast_failed_callback();
80 if (e) e(L, LUABIND_TYPEID(T));
82 assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()");
83 std::terminate();
84 #endif
86 #endif
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());
100 obj.pushvalue();
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>();
109 #endif
111 return boost::optional<T>(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1));
115 template<class T>
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); }
123 template<class T>
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); }
132 template<class T>
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); }
140 template<class T>
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); }
149 template<class T>
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); }
157 template<class T>
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); }
166 template<class T>
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); }
174 template<class T>
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;
189 ref.set(L);
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;
197 ref.set(L);
198 return object(L, ref, true/*object::reference()*/);
201 inline object newtable(lua_State* L)
203 lua_newtable(L);
204 detail::lua_reference ref;
205 ref.set(L);
206 return object(L, ref, true/*object::reference()*/);
212 struct A
216 object f = class_<A>();
218 A* ptr = object_cast<A*>(f(), adopt(_1));
220 delete ptr;
224 #endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED