1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/python/operators.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,364 @@
1.4 +// Copyright David Abrahams 2002.
1.5 +// Distributed under the Boost Software License, Version 1.0. (See
1.6 +// accompanying file LICENSE_1_0.txt or copy at
1.7 +// http://www.boost.org/LICENSE_1_0.txt)
1.8 +#ifndef OPERATORS_DWA2002530_HPP
1.9 +# define OPERATORS_DWA2002530_HPP
1.10 +
1.11 +# include <boost/python/detail/prefix.hpp>
1.12 +
1.13 +# include <boost/python/def_visitor.hpp>
1.14 +# include <boost/python/converter/arg_to_python.hpp>
1.15 +# include <boost/python/detail/operator_id.hpp>
1.16 +# include <boost/python/detail/not_specified.hpp>
1.17 +# include <boost/python/back_reference.hpp>
1.18 +# include <boost/mpl/if.hpp>
1.19 +# include <boost/mpl/eval_if.hpp>
1.20 +# include <boost/python/self.hpp>
1.21 +# include <boost/python/other.hpp>
1.22 +# include <boost/lexical_cast.hpp>
1.23 +# include <boost/python/refcount.hpp>
1.24 +# include <boost/python/detail/unwrap_wrapper.hpp>
1.25 +# include <string>
1.26 +# include <complex>
1.27 +
1.28 +namespace boost { namespace python {
1.29 +
1.30 +namespace detail
1.31 +{
1.32 + // This is essentially the old v1 to_python(). It will be eliminated
1.33 + // once the public interface for to_python is settled on.
1.34 + template <class T>
1.35 + PyObject* convert_result(T const& x)
1.36 + {
1.37 + return converter::arg_to_python<T>(x).release();
1.38 + }
1.39 +
1.40 + // Operator implementation template declarations. The nested apply
1.41 + // declaration here keeps MSVC6 happy.
1.42 + template <operator_id> struct operator_l
1.43 + {
1.44 + template <class L, class R> struct apply;
1.45 + };
1.46 +
1.47 + template <operator_id> struct operator_r
1.48 + {
1.49 + template <class L, class R> struct apply;
1.50 + };
1.51 +
1.52 + template <operator_id> struct operator_1
1.53 + {
1.54 + template <class T> struct apply;
1.55 + };
1.56 +
1.57 + // MSVC6 doesn't want us to do this sort of inheritance on a nested
1.58 + // class template, so we use this layer of indirection to avoid
1.59 + // ::template<...> on the nested apply functions below
1.60 + template <operator_id id, class L, class R>
1.61 + struct operator_l_inner
1.62 + : operator_l<id>::template apply<L,R>
1.63 + {};
1.64 +
1.65 + template <operator_id id, class L, class R>
1.66 + struct operator_r_inner
1.67 + : operator_r<id>::template apply<L,R>
1.68 + {};
1.69 +
1.70 + template <operator_id id, class T>
1.71 + struct operator_1_inner
1.72 + : operator_1<id>::template apply<T>
1.73 + {};
1.74 +
1.75 + // Define three different binary_op templates which take care of
1.76 + // these cases:
1.77 + // self op self
1.78 + // self op R
1.79 + // L op self
1.80 + //
1.81 + // The inner apply metafunction is used to adjust the operator to
1.82 + // the class type being defined. Inheritance of the outer class is
1.83 + // simply used to provide convenient access to the operation's
1.84 + // name().
1.85 +
1.86 + // self op self
1.87 + template <operator_id id>
1.88 + struct binary_op : operator_l<id>
1.89 + {
1.90 + template <class T>
1.91 + struct apply : operator_l_inner<id,T,T>
1.92 + {
1.93 + };
1.94 + };
1.95 +
1.96 + // self op R
1.97 + template <operator_id id, class R>
1.98 + struct binary_op_l : operator_l<id>
1.99 + {
1.100 + template <class T>
1.101 + struct apply : operator_l_inner<id,T,R>
1.102 + {
1.103 + };
1.104 + };
1.105 +
1.106 + // L op self
1.107 + template <operator_id id, class L>
1.108 + struct binary_op_r : operator_r<id>
1.109 + {
1.110 + template <class T>
1.111 + struct apply : operator_r_inner<id,L,T>
1.112 + {
1.113 + };
1.114 + };
1.115 +
1.116 + template <operator_id id>
1.117 + struct unary_op : operator_1<id>
1.118 + {
1.119 + template <class T>
1.120 + struct apply : operator_1_inner<id,T>
1.121 + {
1.122 + };
1.123 + };
1.124 +
1.125 + // This type is what actually gets returned from operators used on
1.126 + // self_t
1.127 + template <operator_id id, class L = not_specified, class R = not_specified>
1.128 + struct operator_
1.129 + : def_visitor<operator_<id,L,R> >
1.130 + {
1.131 + private:
1.132 + template <class ClassT>
1.133 + void visit(ClassT& cl) const
1.134 + {
1.135 + typedef typename mpl::eval_if<
1.136 + is_same<L,self_t>
1.137 + , mpl::if_<
1.138 + is_same<R,self_t>
1.139 + , binary_op<id>
1.140 + , binary_op_l<
1.141 + id
1.142 + , BOOST_DEDUCED_TYPENAME unwrap_other<R>::type
1.143 + >
1.144 + >
1.145 + , mpl::if_<
1.146 + is_same<L,not_specified>
1.147 + , unary_op<id>
1.148 + , binary_op_r<
1.149 + id
1.150 + , BOOST_DEDUCED_TYPENAME unwrap_other<L>::type
1.151 + >
1.152 + >
1.153 + >::type generator;
1.154 +
1.155 + cl.def(
1.156 + generator::name()
1.157 + , &generator::template apply<
1.158 + BOOST_DEDUCED_TYPENAME ClassT::wrapped_type
1.159 + >::execute
1.160 + );
1.161 + }
1.162 +
1.163 + friend class python::def_visitor_access;
1.164 + };
1.165 +}
1.166 +
1.167 +# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
1.168 +namespace detail \
1.169 +{ \
1.170 + template <> \
1.171 + struct operator_l<op_##id> \
1.172 + { \
1.173 + template <class L, class R> \
1.174 + struct apply \
1.175 + { \
1.176 + typedef typename unwrap_wrapper_<L>::type lhs; \
1.177 + typedef typename unwrap_wrapper_<R>::type rhs; \
1.178 + static PyObject* execute(lhs& l, rhs const& r) \
1.179 + { \
1.180 + return detail::convert_result(expr); \
1.181 + } \
1.182 + }; \
1.183 + static char const* name() { return "__" #id "__"; } \
1.184 + }; \
1.185 + \
1.186 + template <> \
1.187 + struct operator_r<op_##id> \
1.188 + { \
1.189 + template <class L, class R> \
1.190 + struct apply \
1.191 + { \
1.192 + typedef typename unwrap_wrapper_<L>::type lhs; \
1.193 + typedef typename unwrap_wrapper_<R>::type rhs; \
1.194 + static PyObject* execute(rhs& r, lhs const& l) \
1.195 + { \
1.196 + return detail::convert_result(expr); \
1.197 + } \
1.198 + }; \
1.199 + static char const* name() { return "__" #rid "__"; } \
1.200 + }; \
1.201 +}
1.202 +
1.203 +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
1.204 +BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
1.205 +namespace self_ns \
1.206 +{ \
1.207 + template <class L, class R> \
1.208 + inline detail::operator_<detail::op_##id,L,R> \
1.209 + operator op(L const&, R const&) \
1.210 + { \
1.211 + return detail::operator_<detail::op_##id,L,R>(); \
1.212 + } \
1.213 +}
1.214 +
1.215 +BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
1.216 +BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
1.217 +BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
1.218 +BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
1.219 +BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
1.220 +BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
1.221 +BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
1.222 +BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
1.223 +BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
1.224 +BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
1.225 +BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
1.226 +BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
1.227 +BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
1.228 +BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
1.229 +BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
1.230 +BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
1.231 +# undef BOOST_PYTHON_BINARY_OPERATOR
1.232 +
1.233 +// pow isn't an operator in C++; handle it specially.
1.234 +BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
1.235 +# undef BOOST_PYTHON_BINARY_OPERATION
1.236 +
1.237 +namespace self_ns
1.238 +{
1.239 +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
1.240 + template <class L, class R>
1.241 + inline detail::operator_<detail::op_pow,L,R>
1.242 + pow(L const&, R const&)
1.243 + {
1.244 + return detail::operator_<detail::op_pow,L,R>();
1.245 + }
1.246 +# else
1.247 + // When there's no argument-dependent lookup, we need these
1.248 + // overloads to handle the case when everything is imported into the
1.249 + // global namespace. Note that the plain overload below does /not/
1.250 + // take const& arguments. This is needed by MSVC6 at least, or it
1.251 + // complains of ambiguities, since there's no partial ordering.
1.252 + inline detail::operator_<detail::op_pow,self_t,self_t>
1.253 + pow(self_t, self_t)
1.254 + {
1.255 + return detail::operator_<detail::op_pow,self_t,self_t>();
1.256 + }
1.257 + template <class R>
1.258 + inline detail::operator_<detail::op_pow,self_t,R>
1.259 + pow(self_t const&, R const&)
1.260 + {
1.261 + return detail::operator_<detail::op_pow,self_t,R>();
1.262 + }
1.263 + template <class L>
1.264 + inline detail::operator_<detail::op_pow,L,self_t>
1.265 + pow(L const&, self_t const&)
1.266 + {
1.267 + return detail::operator_<detail::op_pow,L,self_t>();
1.268 + }
1.269 +# endif
1.270 +}
1.271 +
1.272 +
1.273 +# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
1.274 +namespace detail \
1.275 +{ \
1.276 + template <> \
1.277 + struct operator_l<op_##id> \
1.278 + { \
1.279 + template <class L, class R> \
1.280 + struct apply \
1.281 + { \
1.282 + typedef typename unwrap_wrapper_<L>::type lhs; \
1.283 + typedef typename unwrap_wrapper_<R>::type rhs; \
1.284 + static PyObject* \
1.285 + execute(back_reference<lhs&> l, rhs const& r) \
1.286 + { \
1.287 + l.get() op r; \
1.288 + return python::incref(l.source().ptr()); \
1.289 + } \
1.290 + }; \
1.291 + static char const* name() { return "__" #id "__"; } \
1.292 + }; \
1.293 +} \
1.294 +namespace self_ns \
1.295 +{ \
1.296 + template <class R> \
1.297 + inline detail::operator_<detail::op_##id,self_t,R> \
1.298 + operator op(self_t const&, R const&) \
1.299 + { \
1.300 + return detail::operator_<detail::op_##id,self_t,R>(); \
1.301 + } \
1.302 +}
1.303 +
1.304 +BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
1.305 +BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
1.306 +BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
1.307 +BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
1.308 +BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
1.309 +BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
1.310 +BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
1.311 +BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
1.312 +BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
1.313 +BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
1.314 +
1.315 +# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
1.316 +namespace detail \
1.317 +{ \
1.318 + template <> \
1.319 + struct operator_1<op_##id> \
1.320 + { \
1.321 + template <class T> \
1.322 + struct apply \
1.323 + { \
1.324 + typedef typename unwrap_wrapper_<T>::type self_t; \
1.325 + static PyObject* execute(self_t& x) \
1.326 + { \
1.327 + return detail::convert_result(op(x)); \
1.328 + } \
1.329 + }; \
1.330 + static char const* name() { return "__" #id "__"; } \
1.331 + }; \
1.332 +} \
1.333 +namespace self_ns \
1.334 +{ \
1.335 + inline detail::operator_<detail::op_##id> \
1.336 + func_name(self_t const&) \
1.337 + { \
1.338 + return detail::operator_<detail::op_##id>(); \
1.339 + } \
1.340 +}
1.341 +# undef BOOST_PYTHON_INPLACE_OPERATOR
1.342 +
1.343 +BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
1.344 +BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
1.345 +BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
1.346 +BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
1.347 +BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
1.348 +BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
1.349 +BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
1.350 +BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
1.351 +BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
1.352 +BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
1.353 +# undef BOOST_PYTHON_UNARY_OPERATOR
1.354 +
1.355 +}} // namespace boost::python
1.356 +
1.357 +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
1.358 +using boost::python::self_ns::abs;
1.359 +using boost::python::self_ns::int_;
1.360 +using boost::python::self_ns::long_;
1.361 +using boost::python::self_ns::float_;
1.362 +using boost::python::self_ns::complex_;
1.363 +using boost::python::self_ns::str;
1.364 +using boost::python::self_ns::pow;
1.365 +# endif
1.366 +
1.367 +#endif // OPERATORS_DWA2002530_HPP