1[section boost/python/operators.hpp] 2[section Introduction] 3<boost/python/operators.hpp> provides types and functions for automatically generating Python [@http://www.python.org/doc/ref/specialnames.html special methods] from the corresponding C++ constructs. Most of these constructs are operator expressions, hence the name. To use the facility, substitute the [link high_level_components.boost_python_operators_hpp.object_self self] object for an object of the class type being wrapped in the expression to be exposed, and pass the result to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu class_<>::def()]. Much of what is exposed in this header should be considered part of the implementation, so is not documented in detail here. 4[endsect] 5[section Class `self_ns::self_t`] 6`self_ns::self_t` is the actual type of the [link high_level_components.boost_python_operators_hpp.object_self self] object. The library isolates `self_t` in its own namespace, `self_ns`, in order to prevent the generalized operator templates which operate on it from being found by argument-dependent lookup in other contexts. This should be considered an implementation detail, since users should never have to mention `self_t` directly. 7`` 8namespace boost { namespace python { namespace self_ns { 9{ 10 unspecified-type-declaration self_t; 11 12 // inplace operators 13 template <class T> operator_<unspecified> operator+=(self_t, T); 14 template <class T> operator_<unspecified> operator-=(self_t, T); 15 template <class T> operator_<unspecified> operator*=(self_t, T); 16 template <class T> operator_<unspecified> operator/=(self_t, T); 17 template <class T> operator_<unspecified> operator%=(self_t, T); 18 template <class T> operator_<unspecified> operator>>=(self_t, T); 19 template <class T> operator_<unspecified> operator<<=(self_t, T); 20 template <class T> operator_<unspecified> operator&=(self_t, T); 21 template <class T> operator_<unspecified> operator^=(self_t, T); 22 template <class T> operator_<unspecified> operator|=(self_t, T); 23 24 // comparisons 25 template <class L, class R> operator_<unspecified> operator==(L const&, R const&); 26 template <class L, class R> operator_<unspecified> operator!=(L const&, R const&); 27 template <class L, class R> operator_<unspecified> operator<(L const&, R const&); 28 template <class L, class R> operator_<unspecified> operator>(L const&, R const&); 29 template <class L, class R> operator_<unspecified> operator<=(L const&, R const&); 30 template <class L, class R> operator_<unspecified> operator>=(L const&, R const&); 31 32 // non-member operations 33 template <class L, class R> operator_<unspecified> operator+(L const&, R const&); 34 template <class L, class R> operator_<unspecified> operator-(L const&, R const&); 35 template <class L, class R> operator_<unspecified> operator*(L const&, R const&); 36 template <class L, class R> operator_<unspecified> operator/(L const&, R const&); 37 template <class L, class R> operator_<unspecified> operator%(L const&, R const&); 38 template <class L, class R> operator_<unspecified> operator>>(L const&, R const&); 39 template <class L, class R> operator_<unspecified> operator<<(L const&, R const&); 40 template <class L, class R> operator_<unspecified> operator&(L const&, R const&); 41 template <class L, class R> operator_<unspecified> operator^(L const&, R const&); 42 template <class L, class R> operator_<unspecified> operator|(L const&, R const&); 43 template <class L, class R> operator_<unspecified> pow(L const&, R const&); 44 45 // unary operations 46 operator_<unspecified> operator-(self_t); 47 operator_<unspecified> operator+(self_t); 48 operator_<unspecified> operator~(self_t); 49 operator_<unspecified> operator!(self_t); 50 51 // value operations 52 operator_<unspecified> int_(self_t); 53 operator_<unspecified> long_(self_t); 54 operator_<unspecified> float_(self_t); 55 operator_<unspecified> complex_(self_t); 56 operator_<unspecified> str(self_t); 57 58 operator_<unspecified> repr(self_t); 59}}}; 60`` 61The tables below describe the methods generated when the results of the expressions described are passed as arguments to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu class_<>::def()]. `x` is an object of the class type being wrapped. 62[section `self_t` inplace operators] 63In the table below, If `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other<T>], `y` is an object of type `T`; otherwise, `y` is an object of the same type as `r`. 64[table 65[[C++ Expression][Python Method Name][C++ Implementation]] 66[[`self += r`][`__iadd__`][`x += y`]] 67[[`self -= r`][`__isub__`][`x -= y`]] 68[[`self *= r`][`__imul__`][`x *= y`]] 69[[`self /= r`][`__idiv__`][`x /= y`]] 70[[`self %= r`][`__imod__`][`x %= y`]] 71[[`self >>= r`][`__irshift__`][`x >>= y`]] 72[[`self <<= r`][`__ilshift__`][`x <<= y`]] 73[[`self &= r`][`__iand__`][`x &= y`]] 74[[`self ^= r`][`__ixor__`][`x ^= y`]] 75[[`self |= r`][`__ior__`][`x |= y`]] 76] 77[endsect] 78[section `self_t` comparison functions] 79In the tables below, if `r` is of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t], `y` is an object of the same type as `x`; 80if `l` or `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other<T>], `y` is an object of type `T`; 81otherwise, `y` is an object of the same type as `l` or `r`. 82`l` is never of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t]. 83 84The column of Python Expressions illustrates the expressions that will be supported in Python for objects convertible to the types of x and y. The secondary operation arises due to Python's [@http://www.python.org/doc/ref/customization.html#l2h-89 reflection rules] for rich comparison operators, and are only used when the corresponding operation is not defined as a method of the y object. 85[table 86[[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]] 87[[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]] 88[[`l == self`][`__eq__`][`y == x`][`y == x`, `x == y`]] 89[[`self != r`][`__ne__`][`x != y`][`x != y`, `y != x`]] 90[[`l != self`][`__ne__`][`y != x`][`y != x`, `x != y`]] 91[[`self < r`][`__lt__`][`x < y`][`x < y`, `y > x`]] 92[[`l < self`][`__gt__`][`y < x`][`y > x`, `x < y`]] 93[[`self > r`][`__gt__`][`x > y`][`x > y`, `y < x`]] 94[[`l > self`][`__lt__`][`y > x`][`y < x`, `x > y`]] 95[[`self <= r`][`__le__`][`x <= y`][`x <= y`, `y >= x`]] 96[[`l <= self`][`__ge__`][`y <= x`][`y >= x`, `x <= y`]] 97[[`self >= r`][`__ge__`][`x >= y`][`x >= y`, `y <= x`]] 98[[`l <= self`][`__le__`][`y >= x`][`y <= x`, `x >= y`]] 99] 100[endsect] 101[section `self_t` non-member operations] 102The operations whose names begin with "__r" below will only be called if the left-hand operand does not already support the given operation, as described [@http://www.python.org/doc/current/ref/numeric-types.html#l2h-152 here]. 103[table 104[[C++ Expression][Python Method Name][C++ Implementation]] 105[[`self + r`][`__add__`][`x + y`]] 106[[`l + self`][`__radd__`][`y + x`]] 107[[`self - r`][`__sub__`][`x - y`]] 108[[`l - self`][`__rsub__`][`y - x`]] 109[[`self * r`][`__mult__`][`x * y`]] 110[[`l * self`][`__rmult__`][`y * x`]] 111[[`self / r`][`__div__`][`x / y`]] 112[[`l / self`][`__rdiv__`][`y / x`]] 113[[`self % r`][`__mod__`][`x % y`]] 114[[`l % self`][`__rmod__`][`y % x`]] 115[[`self >> r`][`__rshift__`][`x >> y`]] 116[[`l >> self`][`__rrshift__`][`y >> x`]] 117[[`self << r`][`__lshift__`][`x << y`]] 118[[`l << self`][`__rlshift__`][`y << x`]] 119[[`self & r`][`__and__`][`x & y`]] 120[[`l & self`][`__rand__`][`y & x`]] 121[[`self ^ r`][`__xor__`][`x ^ y`]] 122[[`l ^ self`][`__rxor__`][`y ^ x`]] 123[[`self | r`][`__or__`][`x | y`]] 124[[`l | self`][`__ror__`][`y | x`]] 125[[`pow(self, r)`][`__pow__`][`x ** y`]] 126[[`pow(l, self)`][`__rpow__`][`y ** x`]] 127] 128[endsect] 129[section `self_t` unary operations] 130[table 131[[C++ Expression][Python Method Name][C++ Implementation]] 132[[`-self`][`__neg__`][`-x`]] 133[[`+self`][`__pos__`][`+x`]] 134[[`~self`][`__invert__`][`~x`]] 135[[`not self` or `!self`][`__nonzero__`][`!!x`]] 136] 137[endsect] 138[section `self_t` value operations] 139[table 140[[C++ Expression][Python Method Name][C++ Implementation]] 141[[`int_(self)`][`__int__`][`long(x)`]] 142[[`long_(self)`][`__long__`][`PyLong_FromLong(x)`]] 143[[`float_(self)`][`__float__`][`double(x)`]] 144[[`complex_(self)`][`__complex__`][`std::complex<double>(x)`]] 145[[`str(self)`][`__str__`][`lexical_cast<std::string>(x)`]] 146[[`repr(self)`][`__repr__`][`lexical_cast<std::string>(x)`]] 147] 148[endsect] 149[endsect] 150[section Class template `other`] 151Instances of `other<T>` can be used in operator expressions with [link high_level_components.boost_python_operators_hpp.object_self self]; the result is equivalent to the same expression with a `T` object in place of `other<T>`. Use `other<T>` to prevent construction of a `T` object in case it is heavyweight, when no constructor is available, or simply for clarity. 152`` 153namespace boost { namespace python 154{ 155 template <class T> 156 struct other 157 { 158 }; 159}} 160`` 161[endsect] 162[section Class template `detail::operator_`] 163Instantiations of `detail::operator_<>` are used as the return type of operator expressions involving [link high_level_components.boost_python_operators_hpp.object_self self]. This should be considered an implementation detail and is only documented here as a way of showing how the result of self-expressions match calls to [link high_level_components.boost_python_class_hpp.class_template_class_t_bases_hel.class_template_class_modifier_fu `class_<>::def()`]. 164`` 165namespace boost { namespace python { namespace detail 166{ 167 template <unspecified> 168 struct operator_ 169 { 170 }; 171}}} 172`` 173[endsect] 174[section Object `self`] 175`` 176namespace boost { namespace python 177{ 178 using self_ns::self; 179}} 180`` 181[endsect] 182[section Example] 183`` 184#include <boost/python/module.hpp> 185#include <boost/python/class.hpp> 186#include <boost/python/operators.hpp> 187#include <boost/operators.hpp> 188 189struct number 190 : boost::integer_arithmetic<number> 191{ 192 explicit number(long x_) : x(x_) {} 193 operator long() const { return x; } 194 195 template <class T> 196 number& operator+=(T const& rhs) 197 { x += rhs; return *this; } 198 199 template <class T> 200 number& operator-=(T const& rhs) 201 { x -= rhs; return *this; } 202 203 template <class T> 204 number& operator*=(T const& rhs) 205 { x *= rhs; return *this; } 206 207 template <class T> 208 number& operator/=(T const& rhs) 209 { x /= rhs; return *this; } 210 211 template <class T> 212 number& operator%=(T const& rhs) 213 { x %= rhs; return *this; } 214 215 long x; 216}; 217 218using namespace boost::python; 219BOOST_PYTHON_MODULE(demo) 220{ 221 class_<number>("number", init<long>()) 222 // interoperate with self 223 .def(self += self) 224 .def(self + self) 225 .def(self -= self) 226 .def(self - self) 227 .def(self *= self) 228 .def(self * self) 229 .def(self /= self) 230 .def(self / self) 231 .def(self %= self) 232 .def(self % self) 233 234 // Convert to Python int 235 .def(int_(self)) 236 237 // interoperate with long 238 .def(self += long()) 239 .def(self + long()) 240 .def(long() + self) 241 .def(self -= long()) 242 .def(self - long()) 243 .def(long() - self) 244 .def(self *= long()) 245 .def(self * long()) 246 .def(long() * self) 247 .def(self /= long()) 248 .def(self / long()) 249 .def(long() / self) 250 .def(self %= long()) 251 .def(self % long()) 252 .def(long() % self) 253 ; 254} 255`` 256[endsect] 257[endsect] 258