New inheritance graph code.
[luabind.git] / luabind / operator.hpp
blob144fb0d0b6e984b62f50407f9b3f548606c35c26
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/eval_if.hpp>
27 #include <boost/mpl/identity.hpp>
28 #include <boost/mpl/apply_wrap.hpp>
29 #include <boost/preprocessor/repetition/enum_trailing.hpp>
30 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
31 #include <boost/type_traits/is_same.hpp>
32 #include <luabind/detail/other.hpp>
33 #include <luabind/raw_policy.hpp>
35 #if defined(__GNUC__) && __GNUC__ < 3
36 # define LUABIND_NO_STRINGSTREAM
37 #else
38 # if defined(BOOST_NO_STRINGSTREAM)
39 # define LUABIND_NO_STRINGSTREAM
40 # endif
41 #endif
43 #ifdef LUABIND_NO_STRINGSTREAM
44 #include <strstream>
45 #else
46 #include <sstream>
47 #endif
49 namespace luabind { namespace detail {
51 template<class W, class T> struct unwrap_parameter_type;
52 template<class Derived> struct operator_ {};
54 struct operator_void_return {};
56 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
57 template<class T>
58 inline T const& operator,(T const& x, operator_void_return)
60 return x;
62 #endif
64 }} // namespace luabind
66 namespace luabind { namespace operators {
68 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
69 (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
70 #include BOOST_PP_ITERATE()
72 }} // namespace luabind::operators
74 #include <boost/preprocessor/iteration/local.hpp>
76 namespace luabind {
78 template<class Derived>
79 struct self_base
81 operators::call_operator0<Derived> operator()() const
83 return 0;
86 #define BOOST_PP_LOCAL_MACRO(n) \
87 template<BOOST_PP_ENUM_PARAMS(n, class A)> \
88 BOOST_PP_CAT(operators::call_operator, n)< \
89 Derived \
90 BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \
92 operator()( \
93 BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \
94 ) const \
95 { \
96 return 0; \
99 #define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
100 #include BOOST_PP_LOCAL_ITERATE()
104 struct self_type : self_base<self_type>
108 struct const_self_type : self_base<const_self_type>
112 namespace detail {
114 template<class W, class T>
115 struct unwrap_parameter_type
117 typedef typename boost::mpl::eval_if<
118 boost::is_same<T, self_type>
119 , boost::mpl::identity<W&>
120 , boost::mpl::eval_if<
121 boost::is_same<T, const_self_type>
122 , boost::mpl::identity<W const&>
123 , unwrap_other<T>
125 >::type type;
128 template<class Derived, class A, class B>
129 struct binary_operator
130 : operator_<binary_operator<Derived, A, B> >
132 binary_operator(int) {}
134 template<class T, class Policies>
135 struct apply
137 typedef typename unwrap_parameter_type<T, A>::type arg0;
138 typedef typename unwrap_parameter_type<T, B>::type arg1;
140 static void execute(lua_State* L, arg0 _0, arg1 _1)
142 Derived::template apply<arg0, arg1, Policies>::execute(
143 L, _0, _1);
147 static char const* name()
149 return Derived::name();
153 template<class Derived, class A>
154 struct unary_operator
155 : operator_<unary_operator<Derived, A> >
157 unary_operator(int) {}
159 template<class T, class Policies>
160 struct apply
162 typedef typename unwrap_parameter_type<T, A>::type arg0;
164 static void execute(lua_State* L, arg0 _0)
166 Derived::template apply<arg0, Policies>::execute(L, _0);
170 static char const* name()
172 return Derived::name();
176 template<class Policies>
177 inline void operator_result(lua_State* L, operator_void_return, Policies*)
181 namespace mpl = boost::mpl;
183 template<class T, class Policies>
184 inline void operator_result(lua_State* L, T const& x, Policies*)
186 typedef typename find_conversion_policy<
188 , Policies
189 >::type cv_policy;
191 typename mpl::apply_wrap2<cv_policy,T,cpp_to_lua>::type cv;
193 cv.apply(L, x);
196 }} // namespace detail::luabind
198 namespace luabind {
200 #define LUABIND_BINARY_OPERATOR(name_, op) \
201 namespace operators { \
203 struct name_ \
205 template<class T0, class T1, class Policies> \
206 struct apply \
208 static void execute(lua_State* L, T0 _0, T1 _1) \
210 detail::operator_result(L, _0 op _1, (Policies*)0); \
212 }; \
214 static char const* name() \
216 return "__" # name_; \
218 }; \
222 template<class T, class U> \
223 detail::binary_operator< \
224 operators::name_ \
225 , U \
226 , T \
228 inline operator op(self_base<U>, T const&) \
230 return 0; \
233 template<class T, class U> \
234 detail::binary_operator< \
235 operators::name_ \
236 , T \
237 , U \
239 inline operator op(T const&, self_base<U>) \
241 return 0; \
244 detail::binary_operator< \
245 operators::name_ \
246 , self_type \
247 , self_type \
249 inline operator op(self_type, self_type) \
251 return 0; \
254 detail::binary_operator< \
255 operators::name_ \
256 , self_type \
257 , const_self_type \
259 inline operator op(self_type, const_self_type) \
261 return 0; \
264 detail::binary_operator< \
265 operators::name_ \
266 , const_self_type \
267 , self_type \
269 inline operator op(const_self_type, self_type) \
271 return 0; \
274 detail::binary_operator< \
275 operators::name_ \
276 , const_self_type \
277 , const_self_type \
279 inline operator op(const_self_type, const_self_type) \
281 return 0; \
284 LUABIND_BINARY_OPERATOR(add, +)
285 LUABIND_BINARY_OPERATOR(sub, -)
286 LUABIND_BINARY_OPERATOR(mul, *)
287 LUABIND_BINARY_OPERATOR(div, /)
288 LUABIND_BINARY_OPERATOR(pow, ^)
289 LUABIND_BINARY_OPERATOR(lt, <)
290 LUABIND_BINARY_OPERATOR(le, <=)
291 LUABIND_BINARY_OPERATOR(eq, ==)
293 #undef LUABIND_UNARY_OPERATOR
295 #define LUABIND_UNARY_OPERATOR(name_, op, fn) \
296 namespace operators { \
298 struct name_ \
300 template<class T, class Policies> \
301 struct apply \
303 static void execute(lua_State* L, T x) \
305 detail::operator_result(L, op(x), (Policies*)0); \
307 }; \
309 static char const* name() \
311 return "__" # name_; \
313 }; \
317 template<class T> \
318 detail::unary_operator< \
319 operators::name_ \
320 , T \
322 inline fn(self_base<T>) \
324 return 0; \
327 template<class T>
328 std::string tostring_operator(T const& x)
330 #ifdef LUABIND_NO_STRINGSTREAM
331 std::strstream s;
332 s << x << std::ends;
333 #else
334 std::stringstream s;
335 s << x;
336 #endif
337 return s.str();
340 LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
341 LUABIND_UNARY_OPERATOR(unm, -, operator-)
343 #undef LUABIND_BINARY_OPERATOR
345 namespace {
347 LUABIND_ANONYMOUS_FIX self_type self;
348 LUABIND_ANONYMOUS_FIX const_self_type const_self;
350 } // namespace unnamed
352 } // namespace luabind
354 #endif // OPERATOR_040729_HPP