Boost.Python - <boost/python/iterator.hpp>

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

## Contents

Introduction
Classes
  Class template `iterator`
    Class `iterator` synopsis
    Class template `iterator` constructor
  Class template `iterators`
    Class `iterators` synopsis
    Class template `iterators` nested types
    Class template `iterators` static functions
Functions
  range
Examples

## Introduction

`<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.

## Classes

### Class Template `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` | [c.begin(),c.end()) is a valid Iterator range. | The result will convert its argument to `c` and call `c.begin()` and `c.end()` to acquire iterators. To invoke `Container`'s `const` `begin()` and `end()` functions, make it `const`.
`NextPolicies` | A default-constructible model of CallPolicies. | Applied to the resulting iterators' `next()` method. | An unspecified model of CallPolicies which always makes a copy of the result of deferencing the underlying C++ iterator

#### Class Template iterator synopsis

    namespace boost { namespace python
    {
      template <class Container
                 , class NextPolicies = unspecified>
      struct iterator : object
      {
          iterator();
      };
    }}

#### Class Template iterator constructor

    iterator()

Effects:
  Initializes its base class with the result of:

      range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)

Postconditions: `this->get()` points to a Python callable object which creates a Python iterator as described above.
Rationale: Provides an easy way to create iterators for the common case where a C++ class being wrapped provides `begin()` and `end()`.

### Class Template `iterators`

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.

#### Class Template iterators synopsis

    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);
      };
    }}

#### Class Template iterators nested types

If C is a `const` type,

    typedef typename C::const_iterator iterator;

Otherwise:

    typedef typename C::iterator iterator;

#### Class Template iterators static functions

    static iterator begin(C&);

Returns: `x.begin()`

    static iterator end(C&);

Returns: `x.end()`

## Functions

    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);

Requires: `NextPolicies` is a default-constructible model of CallPolicies.
Effects:
  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:
    1. If `Accessor1` is a function type, `Target` is the type of its first argument.
    2. If `Accessor1` is a data member pointer of the form `R (T::*)`, `Target` is identical to `T`.
    3. If `Accessor1` is a member function pointer of the form `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
Rationale: 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.

## Examples

    #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> >())
            ;
    }

A more comprehensive example can be found in:

`libs/python/test/iterator.cpp`
`libs/python/test/input_iterator.cpp`
`libs/python/test/input_iterator.py`

  Revised 13 November, 2002

  © Copyright Dave Abrahams 2002. All Rights Reserved.