fixed LUABIND_NO_EXCEPTION problem in class_rep.cpp
[luabind.git] / luabind / operator.hpp
blob7b3eaa051f92bafff10baa31e2a94cfa8b7dee53
1 // Copyright (c) 2004 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 OPERATOR_040729_HPP
24 #define OPERATOR_040729_HPP
26 #include <boost/mpl/apply_if.hpp>
27 #include <boost/mpl/identity.hpp>
28 #include <boost/type_traits/is_same.hpp>
29 #include <luabind/detail/other.hpp>
30 #include <luabind/raw_policy.hpp>
32 namespace luabind { namespace detail {
34 template<class W, class T> struct unwrap_parameter_type;
35 template<class Derived> struct operator_ {};
37 struct operator_void_return {};
39 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
40 template<class T>
41 inline T const& operator,(T const& x, operator_void_return)
43 return x;
45 #endif
47 }} // namespace luabind
49 namespace luabind { namespace operators {
51 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
52 (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
53 #include BOOST_PP_ITERATE()
55 }} // namespace luabind::operators
57 #include <boost/preprocessor/iteration/local.hpp>
59 namespace luabind {
61 template<class Derived>
62 struct self_base
64 operators::call_operator0<Derived> operator()() const
66 return 0;
69 #define BOOST_PP_LOCAL_MACRO(n) \
70 template<BOOST_PP_ENUM_PARAMS(n, class A)> \
71 BOOST_PP_CAT(operators::call_operator, n)< \
72 Derived \
73 BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \
75 operator()( \
76 BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \
77 ) const \
78 { \
79 return 0; \
82 #define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
83 #include BOOST_PP_LOCAL_ITERATE()
87 struct self_type : self_base<self_type>
91 struct const_self_type : self_base<const_self_type>
95 namespace detail {
97 template<class W, class T>
98 struct unwrap_parameter_type
100 typedef typename boost::mpl::apply_if<
101 boost::is_same<T, self_type>
102 , boost::mpl::identity<W&>
103 , boost::mpl::apply_if<
104 boost::is_same<T, const_self_type>
105 , boost::mpl::identity<W const&>
106 , unwrap_other<T>
108 >::type type;
111 template<class Derived, class A, class B>
112 struct binary_operator
113 : operator_<binary_operator<Derived, A, B> >
115 binary_operator(int) {}
117 template<class T, class Policies>
118 struct apply
120 typedef typename unwrap_parameter_type<T, A>::type arg0;
121 typedef typename unwrap_parameter_type<T, B>::type arg1;
123 static void execute(lua_State* L, arg0 _0, arg1 _1)
125 Derived::template apply<arg0, arg1, Policies>::execute(
126 L, _0, _1);
130 static char const* name()
132 return Derived::name();
136 template<class Derived, class A>
137 struct unary_operator
138 : operator_<unary_operator<Derived, A> >
140 unary_operator(int) {}
142 template<class T, class Policies>
143 struct apply
145 typedef typename unwrap_parameter_type<T, A>::type arg0;
147 static void execute(lua_State* L, arg0 _0)
149 Derived::template apply<arg0, Policies>::execute(L, _0);
153 static char const* name()
155 return Derived::name();
159 template<class Policies>
160 inline void operator_result(lua_State* L, operator_void_return, Policies*)
164 template<class T, class Policies>
165 inline void operator_result(lua_State* L, T const& x, Policies*)
167 typedef typename find_conversion_policy<
169 , Policies
170 >::type cv_policy;
172 typename cv_policy::template generate_converter<
174 , cpp_to_lua
175 >::type cv;
177 cv.apply(L, x);
180 }} // namespace detail::luabind
182 namespace luabind {
184 #define LUABIND_BINARY_OPERATOR(name_, op) \
185 namespace operators { \
187 struct name_ \
189 template<class T0, class T1, class Policies> \
190 struct apply \
192 static void execute(lua_State* L, T0 _0, T1 _1) \
194 detail::operator_result(L, _0 op _1, (Policies*)0); \
196 }; \
198 static char const* name() \
200 return "__" # name_; \
202 }; \
206 template<class T, class U> \
207 detail::binary_operator< \
208 operators::name_ \
209 , U \
210 , T \
212 inline operator op(self_base<U>, T const&) \
214 return 0; \
217 template<class T, class U> \
218 detail::binary_operator< \
219 operators::name_ \
220 , T \
221 , U \
223 inline operator op(T const&, self_base<U>) \
225 return 0; \
228 detail::binary_operator< \
229 operators::name_ \
230 , self_type \
231 , self_type \
233 inline operator op(self_type, self_type) \
235 return 0; \
238 detail::binary_operator< \
239 operators::name_ \
240 , self_type \
241 , const_self_type \
243 inline operator op(self_type, const_self_type) \
245 return 0; \
248 detail::binary_operator< \
249 operators::name_ \
250 , const_self_type \
251 , self_type \
253 inline operator op(const_self_type, self_type) \
255 return 0; \
258 detail::binary_operator< \
259 operators::name_ \
260 , const_self_type \
261 , const_self_type \
263 inline operator op(const_self_type, const_self_type) \
265 return 0; \
268 LUABIND_BINARY_OPERATOR(add, +)
269 LUABIND_BINARY_OPERATOR(sub, -)
270 LUABIND_BINARY_OPERATOR(mul, *)
271 LUABIND_BINARY_OPERATOR(div, /)
272 LUABIND_BINARY_OPERATOR(pow, ^)
273 LUABIND_BINARY_OPERATOR(lt, <)
274 LUABIND_BINARY_OPERATOR(le, <=)
275 LUABIND_BINARY_OPERATOR(eq, ==)
277 #undef LUABIND_UNARY_OPERATOR
279 #define LUABIND_UNARY_OPERATOR(name_, op, fn) \
280 namespace operators { \
282 struct name_ \
284 template<class T, class Policies> \
285 struct apply \
287 static void execute(lua_State* L, T x) \
289 detail::operator_result(L, op(x), (Policies*)0); \
291 }; \
293 static char const* name() \
295 return "__" # name_; \
297 }; \
301 template<class T> \
302 detail::unary_operator< \
303 operators::name_ \
304 , T \
306 inline fn(self_base<T>) \
308 return 0; \
311 template<class T>
312 T const& tostring_operator(T const& x)
314 return x;
317 LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
318 LUABIND_UNARY_OPERATOR(unm, -, operator-)
320 #undef LUABIND_BINARY_OPERATOR
322 namespace {
324 LUABIND_ANONYMOUS_FIX self_type self;
325 LUABIND_ANONYMOUS_FIX const_self_type const_self;
327 } // namespace unnamed
329 } // namespace luabind
331 #endif // OPERATOR_040729_HPP