2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 05:02:17 +00:00
Files
python/doc/v2/operators.html
Dave Abrahams 241a5bf4e5 operators documentation
[SVN r14076]
2002-06-04 03:30:34 +00:00

532 lines
19 KiB
HTML
Executable File

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/operators.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Header &lt;boost/python/operators.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#self_t-spec">Class <code>self_ns::self_t</code></a>
<dd>
<dl class="page-index">
<dt><a href="#self_t-spec-synopsis">Class <code>self_t</code> synopsis</a>
<dt><a href="#self_t-spec-inplace">Class <code>self_t</code> inplace operators</a>
<dt><a href="#self_t-spec-comparisons">Class <code>self_t</code> comparison functions</a>
<dt><a href="#self_t-spec-ops">Class <code>self_t</code> non-member operations</a>
<dt><a href="#self_t-spec-value-unary-ops">Class <code>self_t</code> unary operations</a>
<dt><a href="#self_t-spec-value-value-ops">Class <code>self_t</code> value operations</a>
</dl>
<dt><a href="#other-spec">Class template <code>other</code></a>
<dd>
<dl class="page-index">
<dt><a href="#other-spec-synopsis">Class <code>other</code> synopsis</a>
</dl>
<dt><a href="#operator_-spec">Class template <code>operator_</code></a>
<dd>
<dl class="page-index">
<dt><a href="#operator_-spec-synopsis">Class <code>operator_</code> synopsis</a>
</dl>
</dl>
<dt><a href="#objects">Objects</a>
<dd>
<dl class="page-index">
<dt><a href="#self-spec">self</a>
</dl>
<dt><a href="#examples">Examples</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/operators.hpp&gt;</code> provides types
and functions for automatically generating Python <a
href="http://www.python.org/doc/ref/specialnames.html">special
methods</a> from the corresponding C++ constructs. Most of these
constructs are operator expressions, hence the name. To use the
facility, substitute the <code><a
href="#self-spec">self</a></code> object for an object of the
class type being wrapped in the expression to be exposed, and pass
the result to <a
href="class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>. Much
of what is exposed in this header should be considered part of the
implementation, so is not documented in detail here.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="self_t-spec"></a>Class <code>self_ns::self_t</code></h3>
<p><code>self_ns::self_t</code> is the actual type of the <a
href="#self-spec"><code>self</code></a> object. The library
isolates <code>self_t</code> in its own namespace,
<code>self_ns</code>, 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 <code>self_t</code> directly.
<h4><a name="self_t-spec-synopsis"></a>Class <code>self_ns::self_t</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace self_ns {
{
class self_t {};
// inplace operators
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator*=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator/=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator%=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;&gt;=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;&lt;=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&amp;=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator^=(self_t, T);
template &lt;class T&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator|=(self_t, T);
// comparisons
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator==(L const&amp;, R const&amp;);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator!=(L const&amp;, R const&amp;);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;(L const&amp;, R const&amp;);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;(L const&amp;, R const&amp;);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;=(L const&amp;, R const&amp;);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;=(L const&amp;, R const&amp;);
// non-member operations
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator*(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator/(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator%(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&gt;&gt;(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&lt;&lt;(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator&amp;(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator^(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator|(L const&amp;, R const&amp);
template &lt;class L, class R&gt; <a
href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; pow(L const&amp;, R const&amp);
// unary operations
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator-(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator+(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; operator~(self_t);
// value operations
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; int_(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; long_(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; float_(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; complex_(self_t);
<a href="#operator_-spec">operator_</a>&lt;<i>unspecified</i>&gt; str(self_t);
}}};
</pre>
The tables below describe the methods generated when the results of
the expressions described are passed as arguments to <a
href="class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>.
<code><b>x</b></code> is an object of the class type being wrapped.
<h4><a name="self_t-spec-inplace"></a>Class <code>self_t</code> inplace operators</h4>
In the table below, If <code><b>r</b></code> is an object of type
<code><a href="#other-spec">other</a>&lt;T&gt;</code>,
<code><b>y</b></code> is an object of type <code>T</code>; otherwise,
<code><b>y</b></code> is an object of the same type as
<code><b>r</b></code>.
<table border="1">
<tr>
<th>C++ Expression
<th>Python Method Name
<th>C++ Implementation
<tr><td><code>self&nbsp;+=&nbsp;r</code>
<td><code>__iadd__</code>
<td><code>x&nbsp;+=&nbsp;y</code>
<tr><td><code>self&nbsp;-=&nbsp;r</code>
<td><code>__isub__</code>
<td><code>x&nbsp;-=&nbsp;y</code>
<tr><td><code>self&nbsp;*=&nbsp;r</code>
<td><code>__imul__</code>
<td><code>x&nbsp;*=&nbsp;y</code>
<tr><td><code>self&nbsp;/=&nbsp;r</code>
<td><code>__idiv__</code>
<td><code>x&nbsp;/=&nbsp;y</code>
<tr><td><code>self&nbsp;%=&nbsp;r</code>
<td><code>__imod__</code>
<td><code>x&nbsp;%=&nbsp;y</code>
<tr><td><code>self&nbsp;&gt;&gt;=&nbsp;r</code>
<td><code>__irshift__</code>
<td><code>x&nbsp;&gt;&gt;=&nbsp;y</code>
<tr><td><code>self&nbsp;&lt;&lt;=&nbsp;r</code>
<td><code>__ilshift__</code>
<td><code>x&nbsp;&lt;&lt;=&nbsp;y</code>
<tr><td><code>self&nbsp;&amp;=&nbsp;r</code>
<td><code>__iand__</code>
<td><code>x&nbsp;&amp;=&nbsp;y</code>
<tr><td><code>self&nbsp;^=&nbsp;r</code>
<td><code>__ixor__</code>
<td><code>x&nbsp;^=&nbsp;y</code>
<tr><td><code>self&nbsp;|=&nbsp;r</code>
<td><code>__ior__</code>
<td><code>x&nbsp;|=&nbsp;y</code>
</table>
<h4><a name="self_t-spec-comparisons"></a>Class <code>self_t</code> comparison
functions</h4>
In the tables below, if <code><b>r</b></code> is of type <code><a
href="#self_t-spec">self_t</a></code>, <code><b>y</b></code> is an object
of the same type as <code>x</code>;
<br>
if <code><b>l</b></code> or <code><b>r</b></code> is an object of type <code><a
href="#other-spec">other</a>&lt;T&gt;</code>,
<code><b>y</b></code> is an object of type <code>T</code>;
<br>
otherwise, <code><b>y</b></code> is an object of the same type as
<code><b>l</b></code> or <code><b>r</b></code>.<br>
<code><b>l</b></code>
is never of type <code><a href="#self_t-spec">self_t</a></code>.
<p>
The column of <b>Python Expressions</b> illustrates the expressions
that will be supported in Python for objects convertible to the types
of <code>x</code> and <code>y</code>. The secondary operation arises
due to Python's <a
href="http://www.python.org/doc/ref/customization.html#l2h-89">reflection
rules</a> for rich comparison operators, and are only used when the
corresponding operation is not defined as a method of the
<code>y</code> object.
<table border="1">
<tr><th>C++ Expression <th>Python Method Name <th>C++ Implementation
<th>Python Expressions<br>(primary, secondary)
<code>
<tr><td>self&nbsp;==&nbsp;r <td>__eq__ <td>x&nbsp;==&nbsp;y
<td>x&nbsp;==&nbsp;y, y&nbsp;==&nbsp;x
<tr><td>l&nbsp;==&nbsp;self <td>__eq__ <td>y&nbsp;==&nbsp;x
<td>y&nbsp;==&nbsp;x, x&nbsp;==&nbsp;y
<tr><td>self&nbsp;!=&nbsp;r <td>__ne__ <td>x&nbsp;!=&nbsp;y
<td>x&nbsp;!=&nbsp;y, y&nbsp;!=&nbsp;x
<tr><td>l&nbsp;!=&nbsp;self <td>__ne__ <td>y&nbsp;!=&nbsp;x
<td>y&nbsp;!=&nbsp;x, x&nbsp;!=&nbsp;y
<tr><td>self&nbsp;&lt;&nbsp;r <td>__lt__ <td>x&nbsp;&lt;&nbsp;y
<td>x&nbsp;&lt;&nbsp;y, y&nbsp;&gt;&nbsp;x
<tr><td>l&nbsp;&lt;&nbsp;self <td>__gt__ <td>y&nbsp;&lt;&nbsp;x
<td>y&nbsp;&gt;&nbsp;x, x&nbsp;&lt;&nbsp;y
<tr><td>self&nbsp;&gt;&nbsp;r <td>__gt__ <td>x&nbsp;&gt;&nbsp;y
<td>x&nbsp;&gt;&nbsp;y, y&nbsp;&lt;&nbsp;x
<tr><td>l&nbsp;&gt;&nbsp;self <td>__lt__ <td>y&nbsp;&gt;&nbsp;x
<td>y&nbsp;&lt;&nbsp;x, x&nbsp;&gt;&nbsp;y
<tr><td>self&nbsp;&lt;=&nbsp;r <td>__le__ <td>x&nbsp;&lt;=&nbsp;y
<td>x&nbsp;&lt;=&nbsp;y, y&nbsp;&gt;=&nbsp;x
<tr><td>l&nbsp;&lt;=&nbsp;self <td>__ge__ <td>y&nbsp;&lt;=&nbsp;x
<td>y&nbsp;&gt;=&nbsp;x, x&nbsp;&lt;=&nbsp;y
<tr><td>self&nbsp;&gt;=&nbsp;r <td>__ge__ <td>x&nbsp;&gt;=&nbsp;y
<td>x&nbsp;&gt;=&nbsp;y, y&nbsp;&lt;=&nbsp;x
<tr><td>l&nbsp;&gt;=&nbsp;self <td>__le__ <td>y&nbsp;&gt;=&nbsp;x
<td>y&nbsp;&lt;=&nbsp;x, x&nbsp;&gt;=&nbsp;y
</code>
</table>
<h4><a name="self_t-spec-ops"></a>Class
<code>self_t</code> non-member operations</h4>
The operations whose names begin with &quot;<code>__r</code>&quot;
below will only be called if the left-hand operand does not already
support the given operation, as described <a
href="http://www.python.org/doc/current/ref/numeric-types.html#l2h-152">here</a>.
<table border="1">
<tr><th>C++ Expression <th>Python Method Name <th>C++ Implementation
<code>
<tr><td>self&nbsp;+&nbsp;r <td>__add__ <td>x&nbsp;+&nbsp;y
<tr><td>l&nbsp;+&nbsp;self <td>__radd__ <td>y&nbsp;+&nbsp;x
<tr><td>self&nbsp;-&nbsp;r <td>__sub__ <td>x&nbsp;-&nbsp;y
<tr><td>l&nbsp;-&nbsp;self <td>__rsub__ <td>y&nbsp;-&nbsp;x
<tr><td>self&nbsp;*&nbsp;r <td>__mul__ <td>x&nbsp;*&nbsp;y
<tr><td>l&nbsp;*&nbsp;self <td>__rmul__ <td>y&nbsp;*&nbsp;x
<tr><td>self&nbsp;/&nbsp;r <td>__div__ <td>x&nbsp;/&nbsp;y
<tr><td>l&nbsp;/&nbsp;self <td>__rdiv__ <td>y&nbsp;/&nbsp;x
<tr><td>self&nbsp;%&nbsp;r <td>__mod__ <td>x&nbsp;%&nbsp;y
<tr><td>l&nbsp;%&nbsp;self <td>__rmod__ <td>y&nbsp;%&nbsp;x
<tr><td>self&nbsp;&gt;&gt;&nbsp;r <td>__rshift__ <td>x&nbsp;&gt;&gt;&nbsp;y
<tr><td>l&nbsp;&gt;&gt;&nbsp;self <td>__rrshift__ <td>y&nbsp;&gt;&gt;&nbsp;x
<tr><td>self&nbsp;&lt;&lt;&nbsp;r <td>__lshift__ <td>x&nbsp;&lt;&lt;&nbsp;y
<tr><td>l&nbsp;&lt;&lt;&nbsp;self <td>__rlshift__ <td>y&nbsp;&lt;&lt;&nbsp;x
<tr><td>self&nbsp;&amp;&nbsp;r <td>__and__ <td>x&nbsp;&amp;&nbsp;y
<tr><td>l&nbsp;&amp;&nbsp;self <td>__rand__ <td>y&nbsp;&amp;&nbsp;x
<tr><td>self&nbsp;^&nbsp;r <td>__xor__ <td>x&nbsp;^&nbsp;y
<tr><td>l&nbsp;^&nbsp;self <td>__rxor__ <td>y&nbsp;^&nbsp;x
<tr><td>self&nbsp;|&nbsp;r <td>__or__ <td>x&nbsp;|&nbsp;y
<tr><td>l&nbsp;|&nbsp;self <td>__ror__ <td>y&nbsp;|&nbsp;x
<tr><td>pow(self,&nbsp;r) <td>__pow__ <td>pow(x,&nbsp;y)
<tr><td>pow(l,&nbsp;self) <td>__rpow__ <td>pow(y,&nbsp;x)
</code>
</table>
<h4><a name="self_t-spec-unary-ops"></a>Class
<code>self_t</code> unary operations</h4>
<table border="1">
<tr><th>C++ Expression <th>Python Method Name <th>C++ Implementation
<code>
<tr><td>-self <td>__neg__ <td>-x
<tr><td>+self<td>__pos__ <td>+x
<tr><td>~self<td>__invert__ <td>~x
</code>
</table>
<h4><a name="self_t-spec-value-ops"></a>Class
<code>self_t</code> value operations</h4>
<table border="1">
<tr><th>C++ Expression <th>Python Method Name <th>C++ Implementation
<code>
<tr><td>int_(self)<td>__int__ <td>long(x)
<tr><td>long_<td>__long__ <td>PyLong_FromLong(x)
<tr><td>float_<td>__float__ <td>double(x)
<tr><td>complex_<td>__complex__ <td>std::complex&lt;double&gt;(x)
<tr><td>str<td>__str__ <td><a href="../../../conversion/lexical_cast.htm#lexical_cast">lexical_cast</a>&lt;std::string&gt;(x)
</code>
</table>
<h3><a name="other-spec"></a>Class Template <code>other</code></h3>
<p>Instances of <code>other&lt;T&gt;</code> can be used in
operator expressions with <a href="#self-spec">self</a>; the
result is equivalent to the same expression with a <code>T</code>
object in place of <code>other&lt;T&gt;</code>. Use
<code>other&lt;T&gt;</code> to prevent construction of a
<code>T</code> object in case it is heavyweight, when no
constructor is available, or simply for clarity.
<h4><a name="other-spec-synopsis"></a>Class Template other synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T&gt;
struct other
{
};
}}
</pre>
<!-- -->
<h3><a name="operator_-spec"></a>Class Template <code>detail::operator_</code></h3>
<p>Instantiations of <code>detail::operator_&lt;&gt;</code> are
used as the return type of operator expressions involving <code><a
href="#self-spec">self</a></code>. This should be considered an
implementation detail and is only documented here as a way of
showing how the result of <code>self</code>-expressions match
calls to <a
href="class.html#class_-spec-modifiers">class_&lt;&gt;::def()</a>.
<h4><a name="operator_-spec-synopsis"></a>Class Template
<code>detail::operator_</code> synopsis</h4>
<pre>
namespace boost { namespace python { namespace detail
{
template &lt;<i>unspecified</i>&gt;
struct operator_
{
};
}}}
</pre>
<h2><a name="objects"></a>Objects</h2>
<p><a name="self-spec"><code>self</code></a>
<pre>
namespace boost { namespace python
{
extern self_ns self;
}}
</pre>
<h2><a name="examples"></a>Example</h2>
<pre>
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/class.hpp&gt;
#include &lt;boost/python/operators.hpp&gt;
#include &lt;boost/operators.hpp&gt;
struct number
: boost::<a href="../../../utility/operators.htm#grpd_oprs">integer_arithmetic</a>&lt;number&gt;
{
number(long x_) : x(x_) {}
operator long() const { return x; }
number&amp; operator+=(number const&amp; rhs)
{ x += rhs }
number&amp; operator-=(number const&amp; rhs);
{ x -= rhs }
number&amp; operator*=(number const&amp; rhs)
{ x *= rhs }
number&amp; operator/=(number const&amp; rhs);
{ x /= rhs }
number&amp; operator%=(number const&amp; rhs);
{ x %= rhs }
long x;
};
using namespace boost::python;
BOOST_PYTHON_MODULE_INIT(demo)
{
module(&quot;demo&quot;)
.add(
class_&lt;number&gt;(&quot;number&quot;)
// 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)
)
;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
3 June, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>