[section boost/python/operators.hpp] [section Introduction] 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. [endsect] [section Class `self_ns::self_t`] `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. `` namespace boost { namespace python { namespace self_ns { { unspecified-type-declaration self_t; // inplace operators template operator_ operator+=(self_t, T); template operator_ operator-=(self_t, T); template operator_ operator*=(self_t, T); template operator_ operator/=(self_t, T); template operator_ operator%=(self_t, T); template operator_ operator>>=(self_t, T); template operator_ operator<<=(self_t, T); template operator_ operator&=(self_t, T); template operator_ operator^=(self_t, T); template operator_ operator|=(self_t, T); // comparisons template operator_ operator==(L const&, R const&); template operator_ operator!=(L const&, R const&); template operator_ operator<(L const&, R const&); template operator_ operator>(L const&, R const&); template operator_ operator<=(L const&, R const&); template operator_ operator>=(L const&, R const&); // non-member operations template operator_ operator+(L const&, R const&); template operator_ operator-(L const&, R const&); template operator_ operator*(L const&, R const&); template operator_ operator/(L const&, R const&); template operator_ operator%(L const&, R const&); template operator_ operator>>(L const&, R const&); template operator_ operator<<(L const&, R const&); template operator_ operator&(L const&, R const&); template operator_ operator^(L const&, R const&); template operator_ operator|(L const&, R const&); template operator_ pow(L const&, R const&); // unary operations operator_ operator-(self_t); operator_ operator+(self_t); operator_ operator~(self_t); operator_ operator!(self_t); // value operations operator_ int_(self_t); operator_ long_(self_t); operator_ float_(self_t); operator_ complex_(self_t); operator_ str(self_t); operator_ repr(self_t); }}}; `` The 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. [section `self_t` inplace operators] In the table below, If `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other], `y` is an object of type `T`; otherwise, `y` is an object of the same type as `r`. [table [[C++ Expression][Python Method Name][C++ Implementation]] [[`self += r`][`__iadd__`][`x += y`]] [[`self -= r`][`__isub__`][`x -= y`]] [[`self *= r`][`__imul__`][`x *= y`]] [[`self /= r`][`__idiv__`][`x /= y`]] [[`self %= r`][`__imod__`][`x %= y`]] [[`self >>= r`][`__irshift__`][`x >>= y`]] [[`self <<= r`][`__ilshift__`][`x <<= y`]] [[`self &= r`][`__iand__`][`x &= y`]] [[`self ^= r`][`__ixor__`][`x ^= y`]] [[`self |= r`][`__ior__`][`x |= y`]] ] [endsect] [section `self_t` comparison functions] In 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`; if `l` or `r` is an object of type [link high_level_components.boost_python_operators_hpp.class_template_other other], `y` is an object of type `T`; otherwise, `y` is an object of the same type as `l` or `r`. `l` is never of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t]. The 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. [table [[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]] [[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]] [[`l == self`][`__eq__`][`y == x`][`y == x`, `x == y`]] [[`self != r`][`__ne__`][`x != y`][`x != y`, `y != x`]] [[`l != self`][`__ne__`][`y != x`][`y != x`, `x != y`]] [[`self < r`][`__lt__`][`x < y`][`x < y`, `y > x`]] [[`l < self`][`__gt__`][`y < x`][`y > x`, `x < y`]] [[`self > r`][`__gt__`][`x > y`][`x > y`, `y < x`]] [[`l > self`][`__lt__`][`y > x`][`y < x`, `x > y`]] [[`self <= r`][`__le__`][`x <= y`][`x <= y`, `y >= x`]] [[`l <= self`][`__ge__`][`y <= x`][`y >= x`, `x <= y`]] [[`self >= r`][`__ge__`][`x >= y`][`x >= y`, `y <= x`]] [[`l <= self`][`__le__`][`y >= x`][`y <= x`, `x >= y`]] ] [endsect] [section `self_t` non-member operations] The 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]. [table [[C++ Expression][Python Method Name][C++ Implementation]] [[`self + r`][`__add__`][`x + y`]] [[`l + self`][`__radd__`][`y + x`]] [[`self - r`][`__sub__`][`x - y`]] [[`l - self`][`__rsub__`][`y - x`]] [[`self * r`][`__mult__`][`x * y`]] [[`l * self`][`__rmult__`][`y * x`]] [[`self / r`][`__div__`][`x / y`]] [[`l / self`][`__rdiv__`][`y / x`]] [[`self % r`][`__mod__`][`x % y`]] [[`l % self`][`__rmod__`][`y % x`]] [[`self >> r`][`__rshift__`][`x >> y`]] [[`l >> self`][`__rrshift__`][`y >> x`]] [[`self << r`][`__lshift__`][`x << y`]] [[`l << self`][`__rlshift__`][`y << x`]] [[`self & r`][`__and__`][`x & y`]] [[`l & self`][`__rand__`][`y & x`]] [[`self ^ r`][`__xor__`][`x ^ y`]] [[`l ^ self`][`__rxor__`][`y ^ x`]] [[`self | r`][`__or__`][`x | y`]] [[`l | self`][`__ror__`][`y | x`]] [[`pow(self, r)`][`__pow__`][`x ** y`]] [[`pow(l, self)`][`__rpow__`][`y ** x`]] ] [endsect] [section `self_t` unary operations] [table [[C++ Expression][Python Method Name][C++ Implementation]] [[`-self`][`__neg__`][`-x`]] [[`+self`][`__pos__`][`+x`]] [[`~self`][`__invert__`][`~x`]] [[`not self` or `!self`][`__nonzero__`][`!!x`]] ] [endsect] [section `self_t` value operations] [table [[C++ Expression][Python Method Name][C++ Implementation]] [[`int_(self)`][`__int__`][`long(x)`]] [[`long_(self)`][`__long__`][`PyLong_FromLong(x)`]] [[`float_(self)`][`__float__`][`double(x)`]] [[`complex_(self)`][`__complex__`][`std::complex(x)`]] [[`str(self)`][`__str__`][`lexical_cast(x)`]] [[`repr(self)`][`__repr__`][`lexical_cast(x)`]] ] [endsect] [endsect] [section Class template `other`] Instances of `other` 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`. Use `other` to prevent construction of a `T` object in case it is heavyweight, when no constructor is available, or simply for clarity. `` namespace boost { namespace python { template struct other { }; }} `` [endsect] [section Class template `detail::operator_`] Instantiations 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()`]. `` namespace boost { namespace python { namespace detail { template struct operator_ { }; }}} `` [endsect] [section Object `self`] `` namespace boost { namespace python { using self_ns::self; }} `` [endsect] [section Example] `` #include #include #include #include struct number : boost::integer_arithmetic { explicit number(long x_) : x(x_) {} operator long() const { return x; } template number& operator+=(T const& rhs) { x += rhs; return *this; } template number& operator-=(T const& rhs) { x -= rhs; return *this; } template number& operator*=(T const& rhs) { x *= rhs; return *this; } template number& operator/=(T const& rhs) { x /= rhs; return *this; } template number& operator%=(T const& rhs) { x %= rhs; return *this; } long x; }; using namespace boost::python; BOOST_PYTHON_MODULE(demo) { class_("number", init()) // interoperate with self .def(self += self) .def(self + self) .def(self -= self) .def(self - self) .def(self *= self) .def(self * self) .def(self /= self) .def(self / self) .def(self %= self) .def(self % self) // Convert to Python int .def(int_(self)) // interoperate with long .def(self += long()) .def(self + long()) .def(long() + self) .def(self -= long()) .def(self - long()) .def(long() - self) .def(self *= long()) .def(self * long()) .def(long() * self) .def(self /= long()) .def(self / long()) .def(long() / self) .def(self %= long()) .def(self % long()) .def(long() % self) ; } `` [endsect] [endsect]