###  | # Boost.Python ## Header <boost/python/operators.hpp>

## Contents

Introduction
Classes
  Class `self_ns::self_t`
    Class `self_t` synopsis
    Class `self_t` inplace operators
    Class `self_t` comparison functions
    Class `self_t` non-member operations
    Class `self_t` unary operations
    Class `self_t` value operations
  Class template `other`
    Class `other` synopsis
  Class template `operator_`
    Class `operator_` synopsis
Objects
  self
Examples

## Introduction

`<boost/python/operators.hpp>` provides types and functions for automatically generating Python special methods from the corresponding C++ constructs. Most of these constructs are operator expressions, hence the name. To use the facility, substitute the `self` object for an object of the class type being wrapped in the expression to be exposed, and pass the result to class_<>::def(). Much of what is exposed in this header should be considered part of the implementation, so is not documented in detail here.

## Classes

### Class `self_ns::self_t`

`self_ns::self_t` is the actual type of the `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.

#### Class `self_ns::self_t` synopsis

    namespace boost { namespace python { namespace self_ns {
    {
       unspecified-type-declaration self_t;

       // inplace operators
       template <class T> operator_<unspecified> operator+=(self_t, T);
       template <class T> operator_<unspecified> operator-=(self_t, T);
       template <class T> operator_<unspecified> operator*=(self_t, T);
       template <class T> operator_<unspecified> operator/=(self_t, T);
       template <class T> operator_<unspecified> operator%=(self_t, T);
       template <class T> operator_<unspecified> operator>>=(self_t, T);
       template <class T> operator_<unspecified> operator<<=(self_t, T);
       template <class T> operator_<unspecified> operator&=(self_t, T);
       template <class T> operator_<unspecified> operator^=(self_t, T);
       template <class T> operator_<unspecified> operator|=(self_t, T);

       // comparisons
       template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);

       // non-member operations
       template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
       template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
       template <class L, class R> operator_<unspecified> pow(L const&, R const&);

       // unary operations
       operator_<unspecified> operator-(self_t);
       operator_<unspecified> operator+(self_t);
       operator_<unspecified> operator~(self_t);

       // value operations
       operator_<unspecified> int_(self_t);
       operator_<unspecified> long_(self_t);
       operator_<unspecified> float_(self_t);
       operator_<unspecified> complex_(self_t);
       operator_<unspecified> str(self_t);

    }}};

The tables below describe the methods generated when the results of the expressions described are passed as arguments to class_<>::def(). `x` is an object of the class type being wrapped.

#### Class `self_t` inplace operators

In the table below, If `r` is an object of type `other<T>`, `y` is an object of type `T`; otherwise, `y` is an object of the same type as `r`.

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`

#### Class `self_t` comparison functions

In the tables below, if `r` is of type `self_t`, `y` is an object of the same type as `x`;
if `l` or `r` is an object of type `other<T>`, `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 `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 reflection rules for rich comparison operators, and are only used when the corresponding operation is not defined as a method of the `y` object.

C++ Expression | Python Method Name | C++ Implementation | Python Expressions (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

#### Class `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 here.

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 | __mul__ | x * y
l * self | __rmul__ | 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__ | pow(x, y)
pow(l, self) | __rpow__ | pow(y, x)

#### Class `self_t` unary operations

C++ Expression | Python Method Name | C++ Implementation
--- | --- | ---
-self | __neg__ | -x
+self | __pos__ | +x
~self | __invert__ | ~x

#### Class `self_t` value operations

C++ Expression | Python Method Name | C++ Implementation
--- | --- | ---
int_(self) | __int__ | long(x)
long_ | __long__ | PyLong_FromLong(x)
float_ | __float__ | double(x)
complex_ | __complex__ | std::complex<double>(x)
str | __str__ | lexical_cast<std::string>(x)

### Class Template `other`

Instances of `other<T>` can be used in operator expressions with 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.

#### Class Template other synopsis

    namespace boost { namespace python
    {
      template <class T>
      struct other
      {
      };
    }}

### Class Template `detail::operator_`

Instantiations of `detail::operator_<>` are used as the return type of operator expressions involving `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 class_<>::def().

#### Class Template `detail::operator_` synopsis

    namespace boost { namespace python { namespace detail
    {
      template <unspecified>
      struct operator_
      {
      };
    }}}

## Objects

`self`

    namespace boost { namespace python
    {
      using self_ns::self;
    }}

## Example

    #include <boost/python/module.hpp>
    #include <boost/python/class.hpp>
    #include <boost/python/operators.hpp>
    #include <boost/operators.hpp>

    struct number
       : boost::integer_arithmetic<number>
    {
       number(long x_) : x(x_) {}
       operator long() const { return x; }

       number& operator+=(number const& rhs)
          { x += rhs }
       number& operator-=(number const& rhs);
          { x -= rhs }
       number& operator*=(number const& rhs)
          { x *= rhs }
       number& operator/=(number const& rhs);
          { x /= rhs }
       number& operator%=(number const& rhs);
          { x %= rhs }

       long x;
    };

    using namespace boost::python;
    BOOST_PYTHON_MODULE(demo)
    {
       class_<number>("number")
          // 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)
          ;
    }

Revised 13 November, 2002

© Copyright Dave Abrahams 2002. All Rights Reserved.