os/ossrv/ossrv_pub/boost_apis/boost/python/operators.hpp
changeset 0 bde4ae8d615e
     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