mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Comments from Dave + Editing + Proof reading and stuff
[SVN r19334]
This commit is contained in:
@@ -1,241 +1,613 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python Indexing Support</title>
|
||||
|
||||
<div> <img src="../../../../c++boost.gif"
|
||||
alt="c++boost.gif (8819 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
<hr>
|
||||
<h1>Boost.Python Indexing Support</h1>
|
||||
<p>Indexing is a Python module for easy exportation of indexable C++ containers
|
||||
to Python. Indexable containers are containers that allow random access through
|
||||
the operator[] (e.g. std::vector).
|
||||
<p>While Boost Python has all the facilities to expose indexable C++ containers
|
||||
such as the ubiquitous std::vector to Python, the procedure is not as straightforward
|
||||
as we'd like it to be. When in Python, do as the Pythonians do. Yet, Python
|
||||
containers do not map easily to C++ containers. Emulating Python containers
|
||||
in C++ (see Python Reference Manual, <a href="http://www.python.org/doc/current/ref/sequence-types.html">Emulating
|
||||
container types</a>) using Boost Python is non trivial. There are a lot of
|
||||
issues to consider before we can map a C++ container to Python which involves
|
||||
implementing wrapper functions for the methods <strong>__len__</strong>, <strong>__getitem__</strong>,
|
||||
<strong>__setitem__</strong>, <strong>__delitem__, </strong><strong>__iter__
|
||||
</strong>and<strong> __contains</strong>.
|
||||
<p>The goals:</div>
|
||||
<ul>
|
||||
<li>
|
||||
<div>Make indexable C++ containers behave exactly as one would expect a Python
|
||||
container to behave.</div>
|
||||
</li>
|
||||
<li>Provide default reference semantics for container element indexing (__getitem__)
|
||||
such that c[i] can be mutable. Require: <tt>c[i].m() == c[i] </tt> where m
|
||||
is a non-const (mutating) member function (method).</li>
|
||||
<li>Return safe references from __getitem__ such that subsequent adds and deletes
|
||||
to and from the container will not result in dangling references (will not
|
||||
crash Python).</li>
|
||||
<li>Support slice indexes.</li>
|
||||
<li>Allow interoperability with Python containers (e.g lists, tuples).</li>
|
||||
<li>Allow for extensibility through redefinable policy classes.</li>
|
||||
<li>Provide predefined support for the most common STL and STL like indexable
|
||||
containers.</li>
|
||||
</ul>
|
||||
<div>
|
||||
<hr>
|
||||
<h2>The Boost.Python Indexing Interface</h2>
|
||||
<h3>indexing_suite</h3>
|
||||
<p>The <tt>indexing_suite</tt> class is the base protocol class for the management
|
||||
of C++ containers intended to be integrated to Python. The objective is make
|
||||
a C++ container look and feel and behave exactly as we'd expect a Python container.
|
||||
The class automatically wraps these special Python methods:</p>
|
||||
</div>
|
||||
<dl>
|
||||
<dt>
|
||||
<div><strong>__len__(self)</strong></div>
|
||||
</dt>
|
||||
<dd>
|
||||
<div>Called to implement the built-in function len() Should return the length
|
||||
of the object, an integer >= 0. Also, an object that doesn't define a
|
||||
__nonzero__() method and whose __len__() method returns zero is considered
|
||||
to be false in a Boolean context.</div>
|
||||
</dd>
|
||||
<dt> </dt>
|
||||
<dd>
|
||||
<div></div>
|
||||
</dd>
|
||||
<dt><strong>__getitem__(self, key)</strong></dt>
|
||||
<dd>Called to implement evaluation of self[key]. For sequence types, the accepted
|
||||
keys should be integers and slice objects. Note that the special interpretation
|
||||
of negative indexes (if the class wishes to emulate a sequence type) is up
|
||||
to the __getitem__() method. If key is of an inappropriate type, TypeError
|
||||
may be raised; if of a value outside the set of indexes for the sequence (after
|
||||
any special interpretation of negative values), IndexError should be raised.
|
||||
Note: for loops expect that an IndexError will be raised for illegal indexes
|
||||
to allow proper detection of the end of the sequence.</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<div><strong>__setitem__(self, key, value)</strong></div>
|
||||
</dt>
|
||||
<dd>
|
||||
<div> Called to implement assignment to self[key]. Same note as for __getitem__().
|
||||
This should only be implemented for mappings if the objects support changes
|
||||
to the values for keys, or if new keys can be added, or for sequences if
|
||||
elements can be replaced. The same exceptions should be raised for improper
|
||||
key values as for the __getitem__() method.<br>
|
||||
</div>
|
||||
</dd>
|
||||
<dt><strong>__delitem__(self, key)</strong></dt>
|
||||
<dd>Called to implement deletion of self[key]. Same note as for __getitem__().
|
||||
This should only be implemented for mappings if the objects support removal
|
||||
of keys, or for sequences if elements can be removed from the sequence. The
|
||||
same exceptions should be raised for improper key values as for the __getitem__()
|
||||
method.</dd>
|
||||
<dt>
|
||||
<div><br>
|
||||
<strong>__iter__(self)</strong></div>
|
||||
</dt>
|
||||
<dd>
|
||||
<div>This method is called when an iterator is required for a container. This
|
||||
method should return a new iterator object that can iterate over all the
|
||||
objects in the container. For mappings, it should iterate over the keys
|
||||
of the container, and should also be made available as the method iterkeys().</div>
|
||||
</dd>
|
||||
<dt> </dt>
|
||||
<dd>
|
||||
<div></div>
|
||||
</dd>
|
||||
<dt>
|
||||
<div><strong>__contains__(self, item)</strong></div>
|
||||
</dt>
|
||||
<dd>
|
||||
<div>Called to implement membership test operators. Should return true if
|
||||
item is in self, false otherwise. For mapping objects, this should consider
|
||||
the keys of the mapping rather than the values or the key-item pairs. </div>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>indexing_suite sub-classes</h3>
|
||||
<p>The <tt>indexing_suite</tt> is not meant to be used as is. A couple of policy
|
||||
functions must be supplied by subclasses of <tt>indexing_suite</tt>. However,
|
||||
a set of <tt>indexing_suite</tt> subclasses for the standard indexable STL containers
|
||||
will be provided, In most cases, we can simply use the available predefined
|
||||
suites. In some cases, if needed, we can refine them to suit our needs.</p>
|
||||
<h3>vector_indexing_suite</h3>
|
||||
<p>The <tt>vector_indexing_suite</tt> class is a predefined <tt>indexing_suite</tt>
|
||||
derived class for wrapping <tt>std::vector</tt> (and <tt>std::vector</tt> like)
|
||||
classes (currently, this is the only predefined suite available). It provides
|
||||
all the policies required by the <tt>indexing_suite</tt>.</p>
|
||||
<p> Example usage:</p>
|
||||
<pre> class X {...};
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st February 2003), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>
|
||||
Indexing Support
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<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>
|
||||
<td valign="top">
|
||||
<h1 align="center">
|
||||
<a href="../index.html">Boost.Python</a>
|
||||
</h1>
|
||||
<h2 align="center">
|
||||
Header <boost/python/indexing/indexing_suite.hpp>
|
||||
</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>
|
||||
Contents
|
||||
</h2>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#introduction">Introduction</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#interface">Interface</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#indexing_suite">indexing_suite</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#indexing_suite_subclasses">indexing_suite
|
||||
sub-classes</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt>
|
||||
<a href="#vector_indexing_suite">vector_indexing_suite</a>
|
||||
</dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<a href="#indexing_suite_class">indexing_suite class</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a href="#vector_indexing_suite_class">vector_indexing_suite
|
||||
class</a>
|
||||
</dt>
|
||||
</dl>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="introduction" id="introduction"></a>Introduction
|
||||
</h2>
|
||||
<p>
|
||||
Indexing is a Boost Python facility for easy exportation of indexable
|
||||
C++ containers to Python. Indexable containers are containers that
|
||||
allow random access through the operator[] (e.g. std::vector).
|
||||
</p>
|
||||
<p>
|
||||
While Boost Python has all the facilities needed to expose indexable
|
||||
C++ containers such as the ubiquitous std::vector to Python, the
|
||||
procedure is not as straightforward as we'd like it to be. Python
|
||||
containers do not map easily to C++ containers. Emulating Python
|
||||
containers in C++ (see Python Reference Manual, <a href=
|
||||
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
|
||||
container types</a>) using Boost Python is non trivial. There are a lot
|
||||
of issues to consider before we can map a C++ container to Python.
|
||||
These involve implementing wrapper functions for the methods
|
||||
<strong>__len__</strong>, <strong>__getitem__</strong>,
|
||||
<strong>__setitem__</strong>, <strong>__delitem__,</strong>
|
||||
<strong>__iter__</strong> and <strong>__contains</strong>.
|
||||
</p>
|
||||
<p>
|
||||
The goals:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<div>
|
||||
Make indexable C++ containers behave exactly as one would expect a
|
||||
Python container to behave.
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
Provide default reference semantics for container element indexing
|
||||
(<tt>__getitem__</tt>) such that <tt>c[i]</tt> can be mutable.
|
||||
Require:
|
||||
<div>
|
||||
<pre>
|
||||
val = c[i]
|
||||
c[i].m()
|
||||
val == c[i]
|
||||
</pre>
|
||||
</div>where <tt>m</tt> is a non-const (mutating) member function
|
||||
(method).
|
||||
</li>
|
||||
<li>
|
||||
Return safe references from <tt>__getitem__</tt> such that subsequent
|
||||
adds and deletes to and from the container will not result in
|
||||
dangling references (will not crash Python).
|
||||
</li>
|
||||
<li>
|
||||
Support slice indexes.
|
||||
</li>
|
||||
<li>
|
||||
Accept Python container arguments (e.g. lists, tuples) wherever
|
||||
appropriate.
|
||||
</li>
|
||||
<li>
|
||||
Allow for extensibility through re-definable policy classes.
|
||||
</li>
|
||||
<li>
|
||||
Provide predefined support for the most common STL and STL like
|
||||
indexable containers.
|
||||
</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="interface"></a>The Boost.Python Indexing Interface
|
||||
</h2>
|
||||
<h3>
|
||||
<a name="indexing_suite"></a>indexing_suite
|
||||
</h3>
|
||||
<p>
|
||||
The <tt>indexing_suite</tt> class is the base protocol class for the
|
||||
management of C++ containers intended to be integrated to Python. The
|
||||
objective is make a C++ container look and feel and behave exactly as
|
||||
we'd expect a Python container. The class automatically wraps these
|
||||
special Python methods (taken from the Python reference: <a href=
|
||||
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
|
||||
container types</a>):
|
||||
</p>
|
||||
<dl>
|
||||
<dd>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-126"><tt class=
|
||||
"method">__len__</tt></a></b>(<var>self</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement the built-in function <tt class=
|
||||
"function">len()</tt><a name="l2h-134"> </a> Should return
|
||||
the length of the object, an integer <code>>=</code> 0. Also,
|
||||
an object that doesn't define a <tt class=
|
||||
"method">__nonzero__()</tt> method and whose <tt class=
|
||||
"method">__len__()</tt> method returns zero is considered to be
|
||||
false in a Boolean context. <a name="l2h-128"> </a>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-129"><tt class=
|
||||
"method">__getitem__</tt></a></b>(<var>self, key</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement evaluation of
|
||||
<code><var>self</var>[<var>key</var>]</code>. For sequence types,
|
||||
the accepted keys should be integers and slice
|
||||
objects.<a name="l2h-135"> </a> Note that the special
|
||||
interpretation of negative indexes (if the class wishes to
|
||||
emulate a sequence type) is up to the <tt class=
|
||||
"method">__getitem__()</tt> method. If <var>key</var> is of
|
||||
an inappropriate type, <tt class="exception">TypeError</tt>
|
||||
may be raised; if of a value outside the set of indexes for
|
||||
the sequence (after any special interpretation of negative
|
||||
values), <tt class="exception">IndexError</tt> should be
|
||||
raised. <span class="note"><b class="label">Note:</b>
|
||||
<tt class="keyword">for</tt> loops expect that an <tt class=
|
||||
"exception">IndexError</tt> will be raised for illegal
|
||||
indexes to allow proper detection of the end of the
|
||||
sequence.</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-130"><tt class=
|
||||
"method">__setitem__</tt></a></b>(<var>self, key, value</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement assignment to
|
||||
<code><var>self</var>[<var>key</var>]</code>. Same note as for
|
||||
<tt class="method">__getitem__()</tt>. This should only be
|
||||
implemented for mappings if the objects support changes to the
|
||||
values for keys, or if new keys can be added, or for sequences if
|
||||
elements can be replaced. The same exceptions should be raised
|
||||
for improper <var>key</var> values as for the <tt class=
|
||||
"method">__getitem__()</tt> method.
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-131"><tt class=
|
||||
"method">__delitem__</tt></a></b>(<var>self, key</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement deletion of
|
||||
<code><var>self</var>[<var>key</var>]</code>. Same note as for
|
||||
<tt class="method">__getitem__()</tt>. This should only be
|
||||
implemented for mappings if the objects support removal of keys,
|
||||
or for sequences if elements can be removed from the sequence.
|
||||
The same exceptions should be raised for improper <var>key</var>
|
||||
values as for the <tt class="method">__getitem__()</tt> method.
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-132"><tt class=
|
||||
"method">__iter__</tt></a></b>(<var>self</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
This method is called when an iterator is required for a
|
||||
container. This method should return a new iterator object that
|
||||
can iterate over all the objects in the container. For mappings,
|
||||
it should iterate over the keys of the container, and should also
|
||||
be made available as the method <tt class=
|
||||
"method">iterkeys()</tt>.
|
||||
<p>
|
||||
Iterator objects also need to implement this method; they are
|
||||
required to return themselves. For more information on iterator
|
||||
objects, see ``<a class="ulink" href=
|
||||
"http://www.python.org/doc/current/lib/typeiter.html">Iterator
|
||||
Types</a>'' in the <em class="citetitle"><a href=
|
||||
"http://www.python.org/doc/current/lib/lib.html" title=
|
||||
"Python Library Reference">Python Library Reference</a></em>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<b><a name="l2h-133"><tt class=
|
||||
"method">__contains__</tt></a></b>(<var>self, item</var>)
|
||||
</dt>
|
||||
<dd>
|
||||
Called to implement membership test operators. Should return true
|
||||
if <var>item</var> is in <var>self</var>, false otherwise. For
|
||||
mapping objects, this should consider the keys of the mapping
|
||||
rather than the values or the key-item pairs.
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>
|
||||
<a name="indexing_suite_subclasses"></a>indexing_suite sub-classes
|
||||
</h3>
|
||||
<p>
|
||||
The <tt>indexing_suite</tt> is not meant to be used as is. A couple of
|
||||
policy functions must be supplied by subclasses of
|
||||
<tt>indexing_suite</tt>. However, a set of <tt>indexing_suite</tt>
|
||||
subclasses for the standard indexable STL containers will be provided,
|
||||
In most cases, we can simply use the available predefined suites. In
|
||||
some cases, we can refine the predefined suites to suit our needs.
|
||||
</p>
|
||||
<h3>
|
||||
<a name="vector_indexing_suite"></a>vector_indexing_suite
|
||||
</h3>
|
||||
<p>
|
||||
The <tt>vector_indexing_suite</tt> class is a predefined
|
||||
<tt>indexing_suite</tt> derived class designed to wrap
|
||||
<tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
|
||||
std::vector interface]) classes (currently, this is the only predefined
|
||||
suite available). It provides all the policies required by the
|
||||
<tt>indexing_suite</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Example usage:
|
||||
</p>
|
||||
<pre>
|
||||
class X {...};
|
||||
...
|
||||
|
||||
class_<std::vector<X> >("XVec")
|
||||
class_<std::vector<X> >("XVec")
|
||||
.def(vector_indexing_suite<std::vector<X> >())
|
||||
;
|
||||
</pre>
|
||||
<p>That's it! <tt>XVec</tt> is now a full-fledged Python container (see the <a href="../../test/vector_indexing_suite.cpp">example
|
||||
in full</a>, along with its <a href="../../test/vector_indexing_suite.py">python
|
||||
test</a>).</p>
|
||||
<hr>
|
||||
<h2>indexing_suite class</h2>
|
||||
<pre> template <<br> class Container<br> , class DerivedPolicies<br> , bool NoProxy = false<br> , class Element = typename Container::value_type<br> , class Key = typename Container::value_type<br> , class Index = typename Container::size_type<br> ><br> class indexing_suite <br> : public def_arg<<br> indexing_suite<<br> Container<br> , DerivedPolicies<br> , NoProxy<br> , Element<br> , Key<br> , Index<br> > ><br> {<br> public:</pre>
|
||||
<pre> template <class Class><br> void visit(Class& cl) const;<br> };</pre>
|
||||
<dl>
|
||||
<dt> <strong><tt>Container</tt></strong></dt>
|
||||
<dd>The contianer type to be wrapped to Python.</dd>
|
||||
<dt> </dt>
|
||||
<dt><strong><tt>DerivedPolicies</tt></strong></dt>
|
||||
<dd>Derived classes provide the hooks needed by the <tt>indexing_suite:</tt></dd>
|
||||
</dl>
|
||||
<pre> static element_type& <br> get_item(Container& container, index_type i);
|
||||
<p>
|
||||
<tt>XVec</tt> is now a full-fledged Python container (see the
|
||||
<a href="../../test/vector_indexing_suite.cpp">example in full</a>,
|
||||
along with its <a href="../../test/vector_indexing_suite.py">python
|
||||
test</a>).
|
||||
</p>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="indexing_suite_class"></a>indexing_suite class
|
||||
</h2>
|
||||
<h3>
|
||||
Class template<br>
|
||||
<tt>indexing_suite<<br>
|
||||
class <font color="#007F00">Container</font><br>
|
||||
, class <font color="#007F00">DerivedPolicies<br></font></tt> <tt>,
|
||||
bool <font color="#007F00">NoProxy</font><br>
|
||||
, bool <font color="#007F00">NoProxy</font>,<br>
|
||||
, class <font color="#007F00">Element</font><br>
|
||||
, class <font color="#007F00">Key</font><br>
|
||||
, class <font color="#007F00">Index</font></tt>
|
||||
</h3>
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Template Parameter</strong><br>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Requirements</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Semantics</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Default</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Container</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A class type
|
||||
</td>
|
||||
<td>
|
||||
The container type to be wrapped to Python.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>DerivedPolicies</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A subclass of indexing_suite
|
||||
</td>
|
||||
<td>
|
||||
Derived classes provide the policy hooks. See <a href=
|
||||
"#DerivedPolicies">DerivedPolicies</a> below.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>NoProxy</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A boolean
|
||||
</td>
|
||||
<td>
|
||||
By default indexed elements have Python reference semantics and are
|
||||
returned by proxy. This can be disabled by supplying
|
||||
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
|
||||
</td>
|
||||
<td>
|
||||
false
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Element</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's element type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::value_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Key</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's key type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::value_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Index</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
The container's index type.
|
||||
</td>
|
||||
<td>
|
||||
<tt>Container::size_type</tt>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>
|
||||
template <<br> class Container
|
||||
, class DerivedPolicies
|
||||
, bool NoProxy = false
|
||||
, class Element = typename Container::value_type
|
||||
, class Key = typename Container::value_type
|
||||
, class Index = typename Container::size_type
|
||||
><br> class indexing_suite
|
||||
: unspecified
|
||||
{
|
||||
public:
|
||||
|
||||
static object <br> get_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static void <br> set_item(Container& container, index_type i, element_type const& v);
|
||||
|
||||
static void <br> set_slice(<br> Container& container, index_type from, <br> index_type to, element_type const& v<br> );
|
||||
|
||||
template <class Iter><br> static void <br> set_slice(Container& container, index_type from, <br> index_type to, Iter first, Iter last<br> );
|
||||
|
||||
static void <br> delete_item(Container& container, index_type i);
|
||||
|
||||
static void <br> delete_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static size_t<br> size(Container& container);
|
||||
|
||||
template <class T><br> static bool<br> contains(Container& container, T const& val);
|
||||
|
||||
static index_type<br> convert_index(Container& container, PyObject* i);
|
||||
|
||||
static index_type<br> adjust_index(index_type current, index_type from, <br> index_type to, size_type len<br> );
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>Most of these policies are self explanatory. <tt><strong>convert_index</strong></tt>
|
||||
and <tt><strong>adjust_index</strong></tt>, however, deserves some explanation.</p>
|
||||
<p><strong><tt>convert_index</tt></strong> converts an Python index into a C++
|
||||
index that the container can handle. For instance, negative indexes in Python,
|
||||
by convention, indexes from the right (e.g. <tt>C[-1]</tt> indexes the rightmost
|
||||
element in <tt>C</tt>). <strong><tt>convert_index</tt></strong> should handle
|
||||
the necessary conversion for the C++ container (e.g. convert <tt>-1</tt> to
|
||||
<tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should also
|
||||
be able to convert the type of the index (A dynamic Python type) to the actual
|
||||
type that the C++ container expects.</p>
|
||||
<p>When a container expands or contracts, held indexes to its elements must
|
||||
be adjusted to follow the movement of data. For instance, if we erase 3 elements,
|
||||
starting from index 0 from a 5 element vector, what used to be at index 4
|
||||
will now be at index 1:</p>
|
||||
<pre>
|
||||
[a][b][c][d][e] ---> [d][e]
|
||||
^ ^
|
||||
4 1</pre>
|
||||
<p> <strong><tt>adjust_index</tt></strong> takes care of the adjustment. Given
|
||||
a current index, the function should return the adjusted index when data in
|
||||
the container at index <tt>from</tt>..<tt>to</tt> is replaced by <tt>len</tt>
|
||||
elements. </p>
|
||||
</blockquote>
|
||||
<dl>
|
||||
<dt><strong><tt>NoProxy</tt></strong></dt>
|
||||
<dd>By default indexed elements have Python reference semantics and are returned
|
||||
by proxy. This can be disabled by supplying <strong>true</strong> in the <tt>NoProxy</tt>
|
||||
template parameter.</dd>
|
||||
<dt><tt><strong><br>
|
||||
Element</strong></tt></dt>
|
||||
<dd><tt><strong></strong></tt>The container's element type. Defaults to <tt>Container::value_type</tt></dd>
|
||||
<dt><tt><strong></strong></tt><tt><strong><br>
|
||||
Key</strong></tt></dt>
|
||||
<dd><tt><strong></strong></tt>The container's key type. Defaults to <tt>Container::value_type</tt></dd>
|
||||
<dt><tt><strong></strong></tt><tt><strong><br>
|
||||
Index</strong></tt></dt>
|
||||
<dd><tt><strong></strong></tt>The container's index type. Defaults to <tt>Container::size_type</tt></dd>
|
||||
</dl>
|
||||
<table width="75%" border="1" align="center">
|
||||
<tr>
|
||||
<td><h2><strong><tt>def_arg</tt></strong></h2>
|
||||
<p>The Boost Python <tt><strong>class_</strong></tt> interface provides
|
||||
a generic visitation interface to avoid cluttering the class interface
|
||||
through the <tt><strong>def_arg</strong></tt> mechanism. indexing_suite
|
||||
derives from the <tt>def_arg</tt> base class and provides the requisite
|
||||
<strong> <tt>visit</tt></strong> member function taking in a const reference
|
||||
to the class. </p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<div>
|
||||
<hr>
|
||||
<h2>vector_indexing_suite class</h2>
|
||||
<pre>
|
||||
template <<br> class Container, <br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite <br> : public indexing_suite<Container, DerivedPolicies, NoProxy><br> {<br> public:<br> <br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type& <br> get_item(Container& container, index_type i);
|
||||
indexing_suite(); // default constructor
|
||||
}
|
||||
</pre>
|
||||
<h2>
|
||||
<tt><a name="DerivedPolicies"></a>DerivedPolicies</tt>
|
||||
</h2>
|
||||
<dl>
|
||||
<dd>
|
||||
Derived classes provide the hooks needed by
|
||||
the<tt>indexing_suite:</tt>
|
||||
</dd>
|
||||
</dl>
|
||||
<pre>
|
||||
static element_type&
|
||||
get_item(Container& container, index_type i);
|
||||
|
||||
static object
|
||||
get_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static void <br> set_item(Container& container, index_type i, element_type const& v);
|
||||
static void
|
||||
set_item(Container& container, index_type i, element_type const& v);
|
||||
|
||||
static void
|
||||
set_slice(
|
||||
Container& container, index_type from,
|
||||
index_type to, element_type const& v
|
||||
);
|
||||
|
||||
template <class Iter>
|
||||
static void<br> set_slice(Container& container, index_type from,
|
||||
index_type to, Iter first, Iter last
|
||||
);
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i);
|
||||
|
||||
static void
|
||||
delete_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static size_t
|
||||
size(Container& container);
|
||||
|
||||
template <class T>
|
||||
static bool
|
||||
contains(Container& container, T const& val);
|
||||
|
||||
static index_type
|
||||
convert_index(Container& container, PyObject* i);
|
||||
|
||||
static index_type
|
||||
adjust_index(index_type current, index_type from,
|
||||
index_type to, size_type len
|
||||
);
|
||||
</pre>
|
||||
<blockquote>
|
||||
<p>
|
||||
Most of these policies are self explanatory. <tt>However,
|
||||
<strong>convert_index</strong></tt> and
|
||||
<tt><strong>adjust_index</strong></tt> deserve some explanation.
|
||||
</p>
|
||||
<p>
|
||||
<strong><tt>convert_index</tt></strong> converts a Python index into
|
||||
a C++ index that the container can handle. For instance, negative
|
||||
indexes in Python, by convention, start counting from the right(e.g.
|
||||
<tt>C[-1]</tt> indexes the rightmost element in <tt>C</tt>).
|
||||
<strong><tt>convert_index</tt></strong> should handle the necessary
|
||||
conversion for the C++ container (e.g. convert <tt>-1</tt> to
|
||||
<tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should
|
||||
also be able to convert the type of the index (A dynamic Python type)
|
||||
to the actual type that the C++ container expects.
|
||||
</p>
|
||||
<p>
|
||||
When a container expands or contracts, held indexes to its elements
|
||||
must be adjusted to follow the movement of data. For instance, if we
|
||||
erase 3 elements, starting from index 0 from a 5 element vector, what
|
||||
used to be at index 4 will now be at index 1:
|
||||
</p>
|
||||
<pre>
|
||||
[a][b][c][d][e] ---> [d][e]
|
||||
^ ^
|
||||
4 1
|
||||
</pre>
|
||||
<p>
|
||||
<strong><tt>adjust_index</tt></strong> takes care of the adjustment.
|
||||
Given a current index, the function should return the adjusted index
|
||||
when data in the container at index <tt>from</tt>..<tt>to</tt> is
|
||||
replaced by <tt>len</tt> elements.
|
||||
</p>
|
||||
</blockquote>
|
||||
<div>
|
||||
<hr>
|
||||
<h2>
|
||||
<a name="vector_indexing_suite_class"></a>vector_indexing_suite class
|
||||
</h2>
|
||||
<h3>
|
||||
Class template <tt><br>
|
||||
vector_indexing_suite<<br>
|
||||
class <font color="#007F00">Container</font><br>
|
||||
, bool <font color="#007F00">NoProxy</font><br>
|
||||
, class <font color="#007F00">DerivedPolicies</font>></tt>
|
||||
</h3>
|
||||
<table width="100%" border="1">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Template Parameter</strong><br>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Requirements</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Semantics</strong>
|
||||
</td>
|
||||
<td>
|
||||
<strong>Default</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>Container</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A class type
|
||||
</td>
|
||||
<td>
|
||||
The container type to be wrapped to Python.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>NoProxy</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A boolean
|
||||
</td>
|
||||
<td>
|
||||
By default indexed elements have Python reference semantics and
|
||||
are returned by proxy. This can be disabled by supplying
|
||||
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
|
||||
</td>
|
||||
<td>
|
||||
false
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<font color="#007F00"><tt>DerivedPolicies</tt></font>
|
||||
</td>
|
||||
<td>
|
||||
A subclass of indexing_suite
|
||||
</td>
|
||||
<td>
|
||||
The <tt>vector_indexing_suite</tt> may still be derived to
|
||||
further tweak any of the predefined policies. Static polymorphism
|
||||
through CRTP (James Coplien. "Curiously Recurring Template
|
||||
Pattern". C++ Report, Feb. 1995) enables the base
|
||||
<tt>indexing_suite</tt> class to call policy function of the most
|
||||
derived class
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<pre>
|
||||
template <<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite<br> : public indexing_suite<Container, DerivedPolicies, NoProxy><br> {<br> public:<br><br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type&<br> get_item(Container& container, index_type i);
|
||||
|
||||
static object
|
||||
get_slice(Container& container, index_type from, index_type to);
|
||||
|
||||
static void<br> set_item(Container& container, index_type i, element_type const& v);
|
||||
|
||||
static void
|
||||
set_slice(Container& container, index_type from,
|
||||
index_type to, element_type const& v);
|
||||
|
||||
template <class Iter><br> static void <br> set_slice(Container& container, index_type from, <br> index_type to, Iter first, Iter last);
|
||||
template <class Iter><br> static void<br> set_slice(Container& container, index_type from,<br> index_type to, Iter first, Iter last);
|
||||
|
||||
static void
|
||||
delete_item(Container& container, index_type i);
|
||||
@@ -254,25 +626,14 @@
|
||||
static index_type
|
||||
adjust_index(index_type current, index_type from,
|
||||
index_type to, size_type len);
|
||||
};</pre>
|
||||
<dl>
|
||||
<dt><strong><tt>Container</tt></strong></dt>
|
||||
<dd>The contianer type to be wrapped to Python.</dd>
|
||||
<dt> </dt>
|
||||
<dt><strong><tt>NoProxy</tt></strong></dt>
|
||||
<dd>By default indexed elements have Python reference semantics and are returned
|
||||
by proxy. This can be disabled by supplying <strong>true</strong> in the
|
||||
<tt>NoProxy</tt> template parameter.</dd>
|
||||
<dt><br>
|
||||
<strong><tt>DerivedPolicies</tt></strong></dt>
|
||||
<dd>The <tt>vector_indexing_suite</tt> may still be derived to further tweak
|
||||
any of the predefined policies. Static polymorphism through CRTP (James
|
||||
Coplien. "Curiously Recurring Template Pattern". C++ Report, Feb.
|
||||
1995) enables the base <tt>indexing_suite</tt> class to call policy function
|
||||
of the most derived class.</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
© Copyright Joel de Guzman 2003. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice appears
|
||||
in all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</div>
|
||||
};
|
||||
</pre>
|
||||
<hr>
|
||||
© Copyright Joel de Guzman 2003. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user