Fixes #66. Adds support for __stdcall on MSVC.
[luabind.git] / luabind / operator.hpp
blobe62490a4ba6876f8b8ab81a2cfea5970551c37cd
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/type_traits/is_same.hpp>
30 #include <luabind/detail/other.hpp>
31 #include <luabind/raw_policy.hpp>
33 #if defined(__GNUC__) && __GNUC__ < 3
34 # define LUABIND_NO_STRINGSTREAM
35 #else
36 # if defined(BOOST_NO_STRINGSTREAM)
37 # define LUABIND_NO_STRINGSTREAM
38 # endif
39 #endif
41 #ifdef LUABIND_NO_STRINGSTREAM
42 #include <strstream>
43 #else
44 #include <sstream>
45 #endif
47 namespace luabind { namespace detail {
49 template<class W, class T> struct unwrap_parameter_type;
50 template<class Derived> struct operator_ {};
52 struct operator_void_return {};
54 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
55 template<class T>
56 inline T const& operator,(T const& x, operator_void_return)
58 return x;
60 #endif
62 }} // namespace luabind
64 namespace luabind { namespace operators {
66 #define BOOST_PP_ITERATION_PARAMS_1 (3, \
67 (0, LUABIND_MAX_ARITY, <luabind/detail/call_operator_iterate.hpp>))
68 #include BOOST_PP_ITERATE()
70 }} // namespace luabind::operators
72 #include <boost/preprocessor/iteration/local.hpp>
74 namespace luabind {
76 template<class Derived>
77 struct self_base
79 operators::call_operator0<Derived> operator()() const
81 return 0;
84 #define BOOST_PP_LOCAL_MACRO(n) \
85 template<BOOST_PP_ENUM_PARAMS(n, class A)> \
86 BOOST_PP_CAT(operators::call_operator, n)< \
87 Derived \
88 BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \
90 operator()( \
91 BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \
92 ) const \
93 { \
94 return 0; \
97 #define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY)
98 #include BOOST_PP_LOCAL_ITERATE()
102 struct self_type : self_base<self_type>
106 struct const_self_type : self_base<const_self_type>
110 namespace detail {
112 template<class W, class T>
113 struct unwrap_parameter_type
115 typedef typename boost::mpl::eval_if<
116 boost::is_same<T, self_type>
117 , boost::mpl::identity<W&>
118 , boost::mpl::eval_if<
119 boost::is_same<T, const_self_type>
120 , boost::mpl::identity<W const&>
121 , unwrap_other<T>
123 >::type type;
126 template<class Derived, class A, class B>
127 struct binary_operator
128 : operator_<binary_operator<Derived, A, B> >
130 binary_operator(int) {}
132 template<class T, class Policies>
133 struct apply
135 typedef typename unwrap_parameter_type<T, A>::type arg0;
136 typedef typename unwrap_parameter_type<T, B>::type arg1;
138 static void execute(lua_State* L, arg0 _0, arg1 _1)
140 Derived::template apply<arg0, arg1, Policies>::execute(
141 L, _0, _1);
145 static char const* name()
147 return Derived::name();
151 template<class Derived, class A>
152 struct unary_operator
153 : operator_<unary_operator<Derived, A> >
155 unary_operator(int) {}
157 template<class T, class Policies>
158 struct apply
160 typedef typename unwrap_parameter_type<T, A>::type arg0;
162 static void execute(lua_State* L, arg0 _0)
164 Derived::template apply<arg0, Policies>::execute(L, _0);
168 static char const* name()
170 return Derived::name();
174 template<class Policies>
175 inline void operator_result(lua_State* L, operator_void_return, Policies*)
179 namespace mpl = boost::mpl;
181 template<class T, class Policies>
182 inline void operator_result(lua_State* L, T const& x, Policies*)
184 typedef typename find_conversion_policy<
186 , Policies
187 >::type cv_policy;
189 typename mpl::apply_wrap2<cv_policy,T,cpp_to_lua>::type cv;
191 cv.apply(L, x);
194 }} // namespace detail::luabind
196 namespace luabind {
198 #define LUABIND_BINARY_OPERATOR(name_, op) \
199 namespace operators { \
201 struct name_ \
203 template<class T0, class T1, class Policies> \
204 struct apply \
206 static void execute(lua_State* L, T0 _0, T1 _1) \
208 detail::operator_result(L, _0 op _1, (Policies*)0); \
210 }; \
212 static char const* name() \
214 return "__" # name_; \
216 }; \
220 template<class T, class U> \
221 detail::binary_operator< \
222 operators::name_ \
223 , U \
224 , T \
226 inline operator op(self_base<U>, T const&) \
228 return 0; \
231 template<class T, class U> \
232 detail::binary_operator< \
233 operators::name_ \
234 , T \
235 , U \
237 inline operator op(T const&, self_base<U>) \
239 return 0; \
242 detail::binary_operator< \
243 operators::name_ \
244 , self_type \
245 , self_type \
247 inline operator op(self_type, self_type) \
249 return 0; \
252 detail::binary_operator< \
253 operators::name_ \
254 , self_type \
255 , const_self_type \
257 inline operator op(self_type, const_self_type) \
259 return 0; \
262 detail::binary_operator< \
263 operators::name_ \
264 , const_self_type \
265 , self_type \
267 inline operator op(const_self_type, self_type) \
269 return 0; \
272 detail::binary_operator< \
273 operators::name_ \
274 , const_self_type \
275 , const_self_type \
277 inline operator op(const_self_type, const_self_type) \
279 return 0; \
282 LUABIND_BINARY_OPERATOR(add, +)
283 LUABIND_BINARY_OPERATOR(sub, -)
284 LUABIND_BINARY_OPERATOR(mul, *)
285 LUABIND_BINARY_OPERATOR(div, /)
286 LUABIND_BINARY_OPERATOR(pow, ^)
287 LUABIND_BINARY_OPERATOR(lt, <)
288 LUABIND_BINARY_OPERATOR(le, <=)
289 LUABIND_BINARY_OPERATOR(eq, ==)
291 #undef LUABIND_UNARY_OPERATOR
293 #define LUABIND_UNARY_OPERATOR(name_, op, fn) \
294 namespace operators { \
296 struct name_ \
298 template<class T, class Policies> \
299 struct apply \
301 static void execute(lua_State* L, T x) \
303 detail::operator_result(L, op(x), (Policies*)0); \
305 }; \
307 static char const* name() \
309 return "__" # name_; \
311 }; \
315 template<class T> \
316 detail::unary_operator< \
317 operators::name_ \
318 , T \
320 inline fn(self_base<T>) \
322 return 0; \
325 template<class T>
326 std::string tostring_operator(T const& x)
328 #ifdef LUABIND_NO_STRINGSTREAM
329 std::strstream s;
330 s << x << std::ends;
331 #else
332 std::stringstream s;
333 s << x;
334 #endif
335 return s.str();
338 LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring)
339 LUABIND_UNARY_OPERATOR(unm, -, operator-)
341 #undef LUABIND_BINARY_OPERATOR
343 namespace {
345 LUABIND_ANONYMOUS_FIX self_type self;
346 LUABIND_ANONYMOUS_FIX const_self_type const_self;
348 } // namespace unnamed
350 } // namespace luabind
352 #endif // OPERATOR_040729_HPP