Update contrib.
1 // Copyright David Abrahams 2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef OPERATORS_DWA2002530_HPP
6 # define OPERATORS_DWA2002530_HPP
8 # include <boost/python/detail/prefix.hpp>
10 # include <boost/python/def_visitor.hpp>
11 # include <boost/python/converter/arg_to_python.hpp>
12 # include <boost/python/detail/operator_id.hpp>
13 # include <boost/python/detail/not_specified.hpp>
14 # include <boost/python/back_reference.hpp>
15 # include <boost/mpl/if.hpp>
16 # include <boost/mpl/eval_if.hpp>
17 # include <boost/python/self.hpp>
18 # include <boost/python/other.hpp>
19 # include <boost/lexical_cast.hpp>
20 # include <boost/python/refcount.hpp>
21 # include <boost/python/detail/unwrap_wrapper.hpp>
25 namespace boost { namespace python {
29 // This is essentially the old v1 to_python(). It will be eliminated
30 // once the public interface for to_python is settled on.
32 PyObject* convert_result(T const& x)
34 return converter::arg_to_python<T>(x).release();
37 // Operator implementation template declarations. The nested apply
38 // declaration here keeps MSVC6 happy.
39 template <operator_id> struct operator_l
41 template <class L, class R> struct apply;
44 template <operator_id> struct operator_r
46 template <class L, class R> struct apply;
49 template <operator_id> struct operator_1
51 template <class T> struct apply;
54 // MSVC6 doesn't want us to do this sort of inheritance on a nested
55 // class template, so we use this layer of indirection to avoid
56 // ::template<...> on the nested apply functions below
57 template <operator_id id, class L, class R>
58 struct operator_l_inner
59 : operator_l<id>::template apply<L,R>
62 template <operator_id id, class L, class R>
63 struct operator_r_inner
64 : operator_r<id>::template apply<L,R>
67 template <operator_id id, class T>
68 struct operator_1_inner
69 : operator_1<id>::template apply<T>
72 // Define three different binary_op templates which take care of
78 // The inner apply metafunction is used to adjust the operator to
79 // the class type being defined. Inheritance of the outer class is
80 // simply used to provide convenient access to the operation's
84 template <operator_id id>
85 struct binary_op : operator_l<id>
88 struct apply : operator_l_inner<id,T,T>
94 template <operator_id id, class R>
95 struct binary_op_l : operator_l<id>
98 struct apply : operator_l_inner<id,T,R>
104 template <operator_id id, class L>
105 struct binary_op_r : operator_r<id>
108 struct apply : operator_r_inner<id,L,T>
113 template <operator_id id>
114 struct unary_op : operator_1<id>
117 struct apply : operator_1_inner<id,T>
122 // This type is what actually gets returned from operators used on
124 template <operator_id id, class L = not_specified, class R = not_specified>
126 : def_visitor<operator_<id,L,R> >
129 template <class ClassT>
130 void visit(ClassT& cl) const
132 typedef typename mpl::eval_if<
139 , BOOST_DEDUCED_TYPENAME unwrap_other<R>::type
143 is_same<L,not_specified>
147 , BOOST_DEDUCED_TYPENAME unwrap_other<L>::type
154 , &generator::template apply<
155 BOOST_DEDUCED_TYPENAME ClassT::wrapped_type
160 friend class python::def_visitor_access;
164 # define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
168 struct operator_l<op_##id> \
170 template <class L, class R> \
173 typedef typename unwrap_wrapper_<L>::type lhs; \
174 typedef typename unwrap_wrapper_<R>::type rhs; \
175 static PyObject* execute(lhs& l, rhs const& r) \
177 return detail::convert_result(expr); \
180 static char const* name() { return "__" #id "__"; } \
184 struct operator_r<op_##id> \
186 template <class L, class R> \
189 typedef typename unwrap_wrapper_<L>::type lhs; \
190 typedef typename unwrap_wrapper_<R>::type rhs; \
191 static PyObject* execute(rhs& r, lhs const& l) \
193 return detail::convert_result(expr); \
196 static char const* name() { return "__" #rid "__"; } \
200 # define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
201 BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
204 template <class L, class R> \
205 inline detail::operator_<detail::op_##id,L,R> \
206 operator op(L const&, R const&) \
208 return detail::operator_<detail::op_##id,L,R>(); \
212 BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
213 BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
214 BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
215 BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
216 BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
217 BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
218 BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
219 BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
220 BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
221 BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
222 BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
223 BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
224 BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
225 BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
226 BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
227 BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
228 # undef BOOST_PYTHON_BINARY_OPERATOR
230 // pow isn't an operator in C++; handle it specially.
231 BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
232 # undef BOOST_PYTHON_BINARY_OPERATION
236 # ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
237 template <class L, class R>
238 inline detail::operator_<detail::op_pow,L,R>
239 pow(L const&, R const&)
241 return detail::operator_<detail::op_pow,L,R>();
244 // When there's no argument-dependent lookup, we need these
245 // overloads to handle the case when everything is imported into the
246 // global namespace. Note that the plain overload below does /not/
247 // take const& arguments. This is needed by MSVC6 at least, or it
248 // complains of ambiguities, since there's no partial ordering.
249 inline detail::operator_<detail::op_pow,self_t,self_t>
252 return detail::operator_<detail::op_pow,self_t,self_t>();
255 inline detail::operator_<detail::op_pow,self_t,R>
256 pow(self_t const&, R const&)
258 return detail::operator_<detail::op_pow,self_t,R>();
261 inline detail::operator_<detail::op_pow,L,self_t>
262 pow(L const&, self_t const&)
264 return detail::operator_<detail::op_pow,L,self_t>();
270 # define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
274 struct operator_l<op_##id> \
276 template <class L, class R> \
279 typedef typename unwrap_wrapper_<L>::type lhs; \
280 typedef typename unwrap_wrapper_<R>::type rhs; \
282 execute(back_reference<lhs&> l, rhs const& r) \
285 return python::incref(l.source().ptr()); \
288 static char const* name() { return "__" #id "__"; } \
294 inline detail::operator_<detail::op_##id,self_t,R> \
295 operator op(self_t const&, R const&) \
297 return detail::operator_<detail::op_##id,self_t,R>(); \
301 BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
302 BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
303 BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
304 BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
305 BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
306 BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
307 BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
308 BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
309 BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
310 BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
312 # define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
316 struct operator_1<op_##id> \
321 typedef typename unwrap_wrapper_<T>::type self_t; \
322 static PyObject* execute(self_t& x) \
324 return detail::convert_result(op(x)); \
327 static char const* name() { return "__" #id "__"; } \
332 inline detail::operator_<detail::op_##id> \
333 func_name(self_t const&) \
335 return detail::operator_<detail::op_##id>(); \
338 # undef BOOST_PYTHON_INPLACE_OPERATOR
340 BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
341 BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
342 BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
343 BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
344 BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
345 BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
346 BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
347 BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
348 BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
349 BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
350 # undef BOOST_PYTHON_UNARY_OPERATOR
352 }} // namespace boost::python
354 # ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
355 using boost::python::self_ns::abs;
356 using boost::python::self_ns::int_;
357 using boost::python::self_ns::long_;
358 using boost::python::self_ns::float_;
359 using boost::python::self_ns::complex_;
360 using boost::python::self_ns::str;
361 using boost::python::self_ns::pow;
364 #endif // OPERATORS_DWA2002530_HPP