operators.qbk 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. ``
  8. namespace boost { namespace python { namespace self_ns {
  9. {
  10. unspecified-type-declaration self_t;
  11. // inplace operators
  12. template <class T> operator_<unspecified> operator+=(self_t, T);
  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. // comparisons
  23. template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
  24. template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
  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. // non-member operations
  30. template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
  31. template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
  32. template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
  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> pow(L const&, R const&);
  41. // unary operations
  42. operator_<unspecified> operator-(self_t);
  43. operator_<unspecified> operator+(self_t);
  44. operator_<unspecified> operator~(self_t);
  45. operator_<unspecified> operator!(self_t);
  46. // value operations
  47. operator_<unspecified> int_(self_t);
  48. operator_<unspecified> long_(self_t);
  49. operator_<unspecified> float_(self_t);
  50. operator_<unspecified> complex_(self_t);
  51. operator_<unspecified> str(self_t);
  52. operator_<unspecified> repr(self_t);
  53. }}};
  54. ``
  55. 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.
  56. [section `self_t` inplace operators]
  57. In 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`.
  58. [table
  59. [[C++ Expression][Python Method Name][C++ Implementation]]
  60. [[`self += r`][`__iadd__`][`x += y`]]
  61. [[`self -= r`][`__isub__`][`x -= y`]]
  62. [[`self *= r`][`__imul__`][`x *= y`]]
  63. [[`self /= r`][`__idiv__`][`x /= y`]]
  64. [[`self %= r`][`__imod__`][`x %= y`]]
  65. [[`self >>= r`][`__irshift__`][`x >>= y`]]
  66. [[`self <<= r`][`__ilshift__`][`x <<= y`]]
  67. [[`self &= r`][`__iand__`][`x &= y`]]
  68. [[`self ^= r`][`__ixor__`][`x ^= y`]]
  69. [[`self |= r`][`__ior__`][`x |= y`]]
  70. ]
  71. [endsect]
  72. [section `self_t` comparison functions]
  73. 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`;
  74. if `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`;
  75. otherwise, `y` is an object of the same type as `l` or `r`.
  76. `l` is never of type [link high_level_components.boost_python_operators_hpp.class_self_ns_self_t self_t].
  77. 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.
  78. [table
  79. [[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]]
  80. [[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]]
  81. [[`l == self`][`__eq__`][`y == x`][`y == x`, `x == y`]]
  82. [[`self != r`][`__ne__`][`x != y`][`x != y`, `y != x`]]
  83. [[`l != self`][`__ne__`][`y != x`][`y != x`, `x != y`]]
  84. [[`self < r`][`__lt__`][`x < y`][`x < y`, `y > x`]]
  85. [[`l < self`][`__gt__`][`y < x`][`y > x`, `x < y`]]
  86. [[`self > r`][`__gt__`][`x > y`][`x > y`, `y < x`]]
  87. [[`l > self`][`__lt__`][`y > x`][`y < x`, `x > y`]]
  88. [[`self <= r`][`__le__`][`x <= y`][`x <= y`, `y >= x`]]
  89. [[`l <= self`][`__ge__`][`y <= x`][`y >= x`, `x <= y`]]
  90. [[`self >= r`][`__ge__`][`x >= y`][`x >= y`, `y <= x`]]
  91. [[`l <= self`][`__le__`][`y >= x`][`y <= x`, `x >= y`]]
  92. ]
  93. [endsect]
  94. [section `self_t` non-member operations]
  95. 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].
  96. [table
  97. [[C++ Expression][Python Method Name][C++ Implementation]]
  98. [[`self + r`][`__add__`][`x + y`]]
  99. [[`l + self`][`__radd__`][`y + x`]]
  100. [[`self - r`][`__sub__`][`x - y`]]
  101. [[`l - self`][`__rsub__`][`y - x`]]
  102. [[`self * r`][`__mult__`][`x * y`]]
  103. [[`l * self`][`__rmult__`][`y * x`]]
  104. [[`self / r`][`__div__`][`x / y`]]
  105. [[`l / self`][`__rdiv__`][`y / x`]]
  106. [[`self % r`][`__mod__`][`x % y`]]
  107. [[`l % self`][`__rmod__`][`y % x`]]
  108. [[`self >> r`][`__rshift__`][`x >> y`]]
  109. [[`l >> self`][`__rrshift__`][`y >> x`]]
  110. [[`self << r`][`__lshift__`][`x << y`]]
  111. [[`l << self`][`__rlshift__`][`y << x`]]
  112. [[`self & r`][`__and__`][`x & y`]]
  113. [[`l & self`][`__rand__`][`y & x`]]
  114. [[`self ^ r`][`__xor__`][`x ^ y`]]
  115. [[`l ^ self`][`__rxor__`][`y ^ x`]]
  116. [[`self | r`][`__or__`][`x | y`]]
  117. [[`l | self`][`__ror__`][`y | x`]]
  118. [[`pow(self, r)`][`__pow__`][`x ** y`]]
  119. [[`pow(l, self)`][`__rpow__`][`y ** x`]]
  120. ]
  121. [endsect]
  122. [section `self_t` unary operations]
  123. [table
  124. [[C++ Expression][Python Method Name][C++ Implementation]]
  125. [[`-self`][`__neg__`][`-x`]]
  126. [[`+self`][`__pos__`][`+x`]]
  127. [[`~self`][`__invert__`][`~x`]]
  128. [[`not self` or `!self`][`__nonzero__`][`!!x`]]
  129. ]
  130. [endsect]
  131. [section `self_t` value operations]
  132. [table
  133. [[C++ Expression][Python Method Name][C++ Implementation]]
  134. [[`int_(self)`][`__int__`][`long(x)`]]
  135. [[`long_(self)`][`__long__`][`PyLong_FromLong(x)`]]
  136. [[`float_(self)`][`__float__`][`double(x)`]]
  137. [[`complex_(self)`][`__complex__`][`std::complex<double>(x)`]]
  138. [[`str(self)`][`__str__`][`lexical_cast<std::string>(x)`]]
  139. [[`repr(self)`][`__repr__`][`lexical_cast<std::string>(x)`]]
  140. ]
  141. [endsect]
  142. [endsect]
  143. [section Class template `other`]
  144. Instances 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.
  145. ``
  146. namespace boost { namespace python
  147. {
  148. template <class T>
  149. struct other
  150. {
  151. };
  152. }}
  153. ``
  154. [endsect]
  155. [section Class template `detail::operator_`]
  156. 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()`].
  157. ``
  158. namespace boost { namespace python { namespace detail
  159. {
  160. template <unspecified>
  161. struct operator_
  162. {
  163. };
  164. }}}
  165. ``
  166. [endsect]
  167. [section Object `self`]
  168. ``
  169. namespace boost { namespace python
  170. {
  171. using self_ns::self;
  172. }}
  173. ``
  174. [endsect]
  175. [section Example]
  176. ``
  177. #include <boost/python/module.hpp>
  178. #include <boost/python/class.hpp>
  179. #include <boost/python/operators.hpp>
  180. #include <boost/operators.hpp>
  181. struct number
  182. : boost::integer_arithmetic<number>
  183. {
  184. explicit number(long x_) : x(x_) {}
  185. operator long() const { return x; }
  186. template <class T>
  187. number& operator+=(T const& rhs)
  188. { x += rhs; return *this; }
  189. template <class T>
  190. number& operator-=(T const& rhs)
  191. { x -= rhs; return *this; }
  192. template <class T>
  193. number& operator*=(T const& rhs)
  194. { x *= rhs; return *this; }
  195. template <class T>
  196. number& operator/=(T const& rhs)
  197. { x /= rhs; return *this; }
  198. template <class T>
  199. number& operator%=(T const& rhs)
  200. { x %= rhs; return *this; }
  201. long x;
  202. };
  203. using namespace boost::python;
  204. BOOST_PYTHON_MODULE(demo)
  205. {
  206. class_<number>("number", init<long>())
  207. // interoperate with self
  208. .def(self += self)
  209. .def(self + self)
  210. .def(self -= self)
  211. .def(self - self)
  212. .def(self *= self)
  213. .def(self * self)
  214. .def(self /= self)
  215. .def(self / self)
  216. .def(self %= self)
  217. .def(self % self)
  218. // Convert to Python int
  219. .def(int_(self))
  220. // interoperate with long
  221. .def(self += long())
  222. .def(self + long())
  223. .def(long() + self)
  224. .def(self -= long())
  225. .def(self - long())
  226. .def(long() - self)
  227. .def(self *= long())
  228. .def(self * long())
  229. .def(long() * self)
  230. .def(self /= long())
  231. .def(self / long())
  232. .def(long() / self)
  233. .def(self %= long())
  234. .def(self % long())
  235. .def(long() % self)
  236. ;
  237. }
  238. ``
  239. [endsect]
  240. [endsect]