...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
<boost/python/iterator.hpp> provides types and functions for creating
Python
iterators from C++ Containers and Iterators. Note that if your
class_
supports random-access
iterators, implementing __getitem__
(also known as the Sequence Protocol) may serve you better than using this
facility: Python will automatically create an iterator type for you (see
iter()
),
and each access can be range-checked, leaving no possiblity of accessing
through an invalidated C++ iterator.
Instances of iterator<C,P>
hold a reference to a callable Python
object which, when invoked from Python, expects a single argument c convertible
to C and creates a Python iterator that traverses [c.begin(), c.end())
. The optional CallPolicies
P
can be used to control
how elements are returned during iteration.
In the table below, c is an instance of Container.
Template Parameter |
Requirements |
Semantics |
Default |
---|---|---|---|
Container |
|
The result will convert its argument to c and call c.begin()
and c.end() to acquire iterators. To invoke Container's const
|
|
NextPolicies |
A default-constructible model of CallPolicies. |
Applied to the resulting iterators' |
An unspecified model of CallPolicies which always makes a copy of the result of deferencing the underlying C++ iterator |
namespace boost { namespace python { template <class Container, class NextPolicies = unspecified> struct iterator : object { iterator(); }; }}
iterator()
Initializes its base class with the result of:
range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
this->get()
points to a Python callable object which creates a Python iterator
as described above.
Provides an easy way to create iterators for the common case where
a C++ class being wrapped provides begin()
and end()
.
A utility class template which provides a way to reliably call its argument's
begin()
and end()
member functions. Note that there is no portable way to take the address
of a member function of a C++ standard library container, so iterators<>
can be particularly helpful when wrapping them.
In the table below, x is an instance of C.
Required Valid Expression |
Type |
---|---|
x.begin() |
Convertible to C::const_iterator if C is a const type; convertible to C::iterator otherwise. |
x.end() |
Convertible to C::const_iterator if C is a const type; convertible to C::iterator otherwise. |
namespace boost { namespace python { template <class C> struct iterators { typedef typename C::const_iterator iterator; static iterator begin(C& x); static iterator end(C& x); }; }}
If C is a const type,
typedef typename C::const_iterator iterator;
Otherwise:
typedef typename C::iterator iterator;
static iterator begin(C&);
x.begin()
static iterator end(C&);
x.end()
template <class NextPolicies, class Target, class Accessor1, class Accessor2> object range(Accessor1 start, Accessor2 finish); template <class NextPolicies, class Accessor1, class Accessor2> object range(Accessor1 start, Accessor2 finish); template <class Accessor1, class Accessor2> object range(Accessor1 start, Accessor2 finish);
NextPolicies is a default-constructible model of CallPolicies.
The first form creates a Python callable object which, when invoked,
converts its argument to a Target object x, and creates a Python
iterator which traverses [bind(start,_1)(x), bind(finish,_1)(x))
,
applying NextPolicies to the iterator's next()
function. The second form is identical
to the first, except that Target is deduced from Accessor1 as follows:
R (T::*)
,
Target is identical to T
.
R (T::*)(arguments...)
cv-opt
, where cv-opt is an optional
cv-qualifier, Target is identical to T
.
The third form is identical to the second, except that NextPolicies is an unspecified model of CallPolicies which always makes a copy of the result of deferencing the underlying C++ iterator
The use of boost::bind()
allows C++ iterators to be accessed
through functions, member functions or data member pointers. Customization
of NextPolicies (e.g. using return_internal_reference)
is useful when it is expensive to copy sequence elements of a wrapped
class type. Customization of Target is useful when Accessor1 is a
function object, or when a base class of the intended target type
would otherwise be deduced.
#include <boost/python/module.hpp> #include <boost/python/class.hpp> #include <vector> using namespace boost::python; BOOST_PYTHON_MODULE(demo) { class_<std::vector<double> >("dvec") .def("__iter__", iterator<std::vector<double> >()) ; }