Warning, file /include/boost/python/operators.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #ifndef OPERATORS_DWA2002530_HPP
0006 # define OPERATORS_DWA2002530_HPP
0007
0008 # include <boost/python/detail/prefix.hpp>
0009
0010 # include <boost/python/def_visitor.hpp>
0011 # include <boost/python/converter/arg_to_python.hpp>
0012 # include <boost/python/detail/operator_id.hpp>
0013 # include <boost/python/detail/not_specified.hpp>
0014 # include <boost/python/back_reference.hpp>
0015 # include <boost/mpl/if.hpp>
0016 # include <boost/mpl/eval_if.hpp>
0017 # include <boost/python/self.hpp>
0018 # include <boost/python/other.hpp>
0019 # include <boost/lexical_cast.hpp>
0020 # include <boost/python/refcount.hpp>
0021 # include <boost/python/detail/unwrap_wrapper.hpp>
0022 # include <string>
0023 # include <complex>
0024
0025 namespace boost { namespace python {
0026
0027 namespace detail
0028 {
0029
0030
0031 template <class T>
0032 PyObject* convert_result(T const& x)
0033 {
0034 return converter::arg_to_python<T>(x).release();
0035 }
0036
0037
0038
0039 template <operator_id> struct operator_l
0040 {
0041 template <class L, class R> struct apply;
0042 };
0043
0044 template <operator_id> struct operator_r
0045 {
0046 template <class L, class R> struct apply;
0047 };
0048
0049 template <operator_id> struct operator_1
0050 {
0051 template <class T> struct apply;
0052 };
0053
0054
0055
0056
0057 template <operator_id id, class L, class R>
0058 struct operator_l_inner
0059 : operator_l<id>::template apply<L,R>
0060 {};
0061
0062 template <operator_id id, class L, class R>
0063 struct operator_r_inner
0064 : operator_r<id>::template apply<L,R>
0065 {};
0066
0067 template <operator_id id, class T>
0068 struct operator_1_inner
0069 : operator_1<id>::template apply<T>
0070 {};
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 template <operator_id id>
0085 struct binary_op : operator_l<id>
0086 {
0087 template <class T>
0088 struct apply : operator_l_inner<id,T,T>
0089 {
0090 };
0091 };
0092
0093
0094 template <operator_id id, class R>
0095 struct binary_op_l : operator_l<id>
0096 {
0097 template <class T>
0098 struct apply : operator_l_inner<id,T,R>
0099 {
0100 };
0101 };
0102
0103
0104 template <operator_id id, class L>
0105 struct binary_op_r : operator_r<id>
0106 {
0107 template <class T>
0108 struct apply : operator_r_inner<id,L,T>
0109 {
0110 };
0111 };
0112
0113 template <operator_id id>
0114 struct unary_op : operator_1<id>
0115 {
0116 template <class T>
0117 struct apply : operator_1_inner<id,T>
0118 {
0119 };
0120 };
0121
0122
0123
0124 template <operator_id id, class L = not_specified, class R = not_specified>
0125 struct operator_
0126 : def_visitor<operator_<id,L,R> >
0127 {
0128 private:
0129 template <class ClassT>
0130 void visit(ClassT& cl) const
0131 {
0132 typedef typename mpl::eval_if<
0133 is_same<L,self_t>
0134 , mpl::if_<
0135 is_same<R,self_t>
0136 , binary_op<id>
0137 , binary_op_l<
0138 id
0139 , BOOST_DEDUCED_TYPENAME unwrap_other<R>::type
0140 >
0141 >
0142 , mpl::if_<
0143 is_same<L,not_specified>
0144 , unary_op<id>
0145 , binary_op_r<
0146 id
0147 , BOOST_DEDUCED_TYPENAME unwrap_other<L>::type
0148 >
0149 >
0150 >::type generator;
0151
0152 cl.def(
0153 generator::name()
0154 , &generator::template apply<
0155 BOOST_DEDUCED_TYPENAME ClassT::wrapped_type
0156 >::execute
0157 );
0158 }
0159
0160 friend class python::def_visitor_access;
0161 };
0162 }
0163
0164 # define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \
0165 namespace detail \
0166 { \
0167 template <> \
0168 struct operator_l<op_##id> \
0169 { \
0170 template <class L, class R> \
0171 struct apply \
0172 { \
0173 typedef typename unwrap_wrapper_<L>::type lhs; \
0174 typedef typename unwrap_wrapper_<R>::type rhs; \
0175 static PyObject* execute(lhs& l, rhs const& r) \
0176 { \
0177 return detail::convert_result(expr); \
0178 } \
0179 }; \
0180 static char const* name() { return "__" #id "__"; } \
0181 }; \
0182 \
0183 template <> \
0184 struct operator_r<op_##id> \
0185 { \
0186 template <class L, class R> \
0187 struct apply \
0188 { \
0189 typedef typename unwrap_wrapper_<L>::type lhs; \
0190 typedef typename unwrap_wrapper_<R>::type rhs; \
0191 static PyObject* execute(rhs& r, lhs const& l) \
0192 { \
0193 return detail::convert_result(expr); \
0194 } \
0195 }; \
0196 static char const* name() { return "__" #rid "__"; } \
0197 }; \
0198 }
0199
0200 # define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \
0201 BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \
0202 namespace self_ns \
0203 { \
0204 template <class L, class R> \
0205 inline detail::operator_<detail::op_##id,L,R> \
0206 operator op(L const&, R const&) \
0207 { \
0208 return detail::operator_<detail::op_##id,L,R>(); \
0209 } \
0210 }
0211
0212 BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
0213 BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
0214 BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
0215 #if PY_VERSION_HEX >= 0x03000000
0216 BOOST_PYTHON_BINARY_OPERATOR(truediv, rtruediv, /)
0217 #else
0218 BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
0219 #endif
0220 BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
0221 BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
0222 BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)
0223 BOOST_PYTHON_BINARY_OPERATOR(and, rand, &)
0224 BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^)
0225 BOOST_PYTHON_BINARY_OPERATOR(or, ror, |)
0226 BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >)
0227 BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=)
0228 BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <)
0229 BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=)
0230 BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==)
0231 BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=)
0232 # undef BOOST_PYTHON_BINARY_OPERATOR
0233
0234
0235 BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r))
0236 # undef BOOST_PYTHON_BINARY_OPERATION
0237
0238 namespace self_ns
0239 {
0240 # ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0241 template <class L, class R>
0242 inline detail::operator_<detail::op_pow,L,R>
0243 pow(L const&, R const&)
0244 {
0245 return detail::operator_<detail::op_pow,L,R>();
0246 }
0247 # else
0248
0249
0250
0251
0252
0253 inline detail::operator_<detail::op_pow,self_t,self_t>
0254 pow(self_t, self_t)
0255 {
0256 return detail::operator_<detail::op_pow,self_t,self_t>();
0257 }
0258 template <class R>
0259 inline detail::operator_<detail::op_pow,self_t,R>
0260 pow(self_t const&, R const&)
0261 {
0262 return detail::operator_<detail::op_pow,self_t,R>();
0263 }
0264 template <class L>
0265 inline detail::operator_<detail::op_pow,L,self_t>
0266 pow(L const&, self_t const&)
0267 {
0268 return detail::operator_<detail::op_pow,L,self_t>();
0269 }
0270 # endif
0271 }
0272
0273
0274 # define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \
0275 namespace detail \
0276 { \
0277 template <> \
0278 struct operator_l<op_##id> \
0279 { \
0280 template <class L, class R> \
0281 struct apply \
0282 { \
0283 typedef typename unwrap_wrapper_<L>::type lhs; \
0284 typedef typename unwrap_wrapper_<R>::type rhs; \
0285 static PyObject* \
0286 execute(back_reference<lhs&> l, rhs const& r) \
0287 { \
0288 l.get() op r; \
0289 return python::incref(l.source().ptr()); \
0290 } \
0291 }; \
0292 static char const* name() { return "__" #id "__"; } \
0293 }; \
0294 } \
0295 namespace self_ns \
0296 { \
0297 template <class R> \
0298 inline detail::operator_<detail::op_##id,self_t,R> \
0299 operator op(self_t const&, R const&) \
0300 { \
0301 return detail::operator_<detail::op_##id,self_t,R>(); \
0302 } \
0303 }
0304
0305 BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=)
0306 BOOST_PYTHON_INPLACE_OPERATOR(isub,-=)
0307 BOOST_PYTHON_INPLACE_OPERATOR(imul,*=)
0308 BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=)
0309 BOOST_PYTHON_INPLACE_OPERATOR(imod,%=)
0310 BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=)
0311 BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=)
0312 BOOST_PYTHON_INPLACE_OPERATOR(iand,&=)
0313 BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=)
0314 BOOST_PYTHON_INPLACE_OPERATOR(ior,|=)
0315
0316 # define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \
0317 namespace detail \
0318 { \
0319 template <> \
0320 struct operator_1<op_##id> \
0321 { \
0322 template <class T> \
0323 struct apply \
0324 { \
0325 typedef typename unwrap_wrapper_<T>::type self_t; \
0326 static PyObject* execute(self_t& x) \
0327 { \
0328 return detail::convert_result(op(x)); \
0329 } \
0330 }; \
0331 static char const* name() { return "__" #id "__"; } \
0332 }; \
0333 } \
0334 namespace self_ns \
0335 { \
0336 inline detail::operator_<detail::op_##id> \
0337 func_name(self_t const&) \
0338 { \
0339 return detail::operator_<detail::op_##id>(); \
0340 } \
0341 }
0342 # undef BOOST_PYTHON_INPLACE_OPERATOR
0343
0344 BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-)
0345 BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+)
0346 BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs)
0347 BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~)
0348 #if PY_VERSION_HEX >= 0x03000000
0349 BOOST_PYTHON_UNARY_OPERATOR(bool, !!, operator!)
0350 #else
0351 BOOST_PYTHON_UNARY_OPERATOR(nonzero, !!, operator!)
0352 #endif
0353 BOOST_PYTHON_UNARY_OPERATOR(int, long, int_)
0354 BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_)
0355 BOOST_PYTHON_UNARY_OPERATOR(float, double, float_)
0356 BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex<double>, complex_)
0357 BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast<std::string>, str)
0358 BOOST_PYTHON_UNARY_OPERATOR(repr, lexical_cast<std::string>, repr)
0359 # undef BOOST_PYTHON_UNARY_OPERATOR
0360
0361 }}
0362
0363 # ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0364 using boost::python::self_ns::abs;
0365 using boost::python::self_ns::int_;
0366 using boost::python::self_ns::long_;
0367 using boost::python::self_ns::float_;
0368 using boost::python::self_ns::complex_;
0369 using boost::python::self_ns::str;
0370 using boost::python::self_ns::repr;
0371 using boost::python::self_ns::pow;
0372 # endif
0373
0374 #endif