# Boost Iterator Adaptor Library

## Introduction

The Iterator Adaptor library allows you transform an arbitrary ``base'' type into a standard-conforming iterator with the behaviors you choose. Doing so is especially easy if the ``base'' type is itself an iterator. The library also supplies several example adaptors which apply specific useful behaviors to arbitrary base iterators.

## Backward Compatibility Note

The library's interface has changed since it was first released, breaking backward compatibility:

1. Policies classes now operate on instances of the whole `iterator_adaptor` object, rather than just operating on the `Base` object. This change not only gives the policies class access to both members of a pair of interacting iterators, but also eliminates the need for the ugly `type<Reference>` and `type<Difference>` parameters to various policy functions.
2. The Named Template Parameter interface has been made simpler, easier to use, and compatible with more compilers.

## Other Documentation

``Policy Adaptors and the Boost Iterator Adaptor Library'' is a technical paper describing this library and the powerful design pattern on which it is based. It was presented at the C++ Template Workshop at OOPSLA 2001; the slides from the talk are available here. Please note that while the slides incorporate the minor interface changes described in the previous section, the paper does not.

## Table of Contents

- Header `boost/iterator_adaptors.hpp`
  - Generalized Iterator Adaptor
    - Class template `iterator_adaptor`
    - Template Parameters
    - Named Template Parameters
    - The Policies Class
    - Additional Class Members
    - Example
    - (`const`/non-`const`) Iterator Interactions
    - Challenge
    - Concept Model
    - Declaration Synopsis
    - Portability
    - Notes
  - Specialized Iterator Adaptors
    - Indirect Iterator Adaptor
    - Reverse Iterator Adaptor
    - Transform Iterator Adaptor
    - Projection Iterator Adaptor
    - Filter Iterator Adaptor
- Header `boost/counting_iterator.hpp`
  Counting Iterator Adaptor
- Header `boost/function_output_iterator.hpp`
  Function Output Iterator Adaptor
- Header `boost/generator_iterator.hpp`
  Generator Iterator Adaptor
- Header `boost/permutation_iterator.hpp`
  Permutation Iterator Adaptor

Dave Abrahams started the library, applying policy class technique and handling const/non-const iterator interactions. He also contributed the `indirect_` and `reverse_` iterator generators, and expanded `counting_iterator_generator` to cover all incrementable types. He edited most of the documentation, sometimes heavily.
Jeremy Siek contributed the transform iterator adaptor, the integer-only version of `counting_iterator_generator`, the function output iterator adaptor, and most of the documentation.
John Potter contributed the `projection_` and `filter_` iterator generators and made some simplifications to the main `iterator_adaptor` template.
Jens Maurer contributed the generator iterator adaptor.
Toon Knapen contributed the permutation iterator adaptor.

## Class template `iterator_adaptor`

Implementing standard conforming iterators is a non-trivial task. There are some fine points such as the interactions between an iterator and its corresponding const_iterator, and there are myriad operators that should be implemented but are easily forgotten or mishandled, such as `operator->()`. Using `iterator_adaptor`, you can easily implement an iterator class, and even more easily extend and adapt existing iterator types. Moreover, it is easy to make a pair of interoperable `const` and `non-const` iterators.

`iterator_adaptor` is declared like this:

    template <class Base, class Policies,
        class ValueOrNamedParam = typename std::iterator_traits<Base>::value_type,
        class ReferenceOrNamedParam = ...(see below),
        class PointerOrNamedParam = ...(see below),
        class CategoryOrNamedParam = typename std::iterator_traits<Base>::iterator_category,
        class DistanceOrNamedParam = typename std::iterator_traits<Base>::difference_type>
    struct iterator_adaptor;

### Template Parameters

Although `iterator_adaptor` takes seven template parameters, defaults have been carefully chosen to minimize the number of parameters you must supply in most cases, especially if `BaseType` is an iterator.

Parameter | Description
--- | ---
`BaseType` | The type being wrapped.
`Policies` | A policy class that supplies core functionality to the resulting iterator. A detailed description can be found below.
`Value` | The `value_type` of the resulting iterator, unless const. If Value is `const X` the `value_type` will be (non-`const`) `X`[1]. If the `value_type` you wish to use is an abstract base class see note [5]. Default: `std::iterator_traits<BaseType>::value_type` [2]
`Reference` | The `reference` type of the resulting iterator, and in particular, the result type of `operator*()`. Default: If `Value` is supplied, `Value&` is used. Otherwise `std::iterator_traits<BaseType>::reference` is used. [7]
`Pointer` | The `pointer` type of the resulting iterator, and in particular, the result type of `operator->()`. Default: If `Value` was supplied, then `Value*`, otherwise `std::iterator_traits<BaseType>::pointer`. [7]
`Category` | The `iterator_category` type for the resulting iterator. Default: `std::iterator_traits<BaseType>::iterator_category`
`Distance` | The `difference_type` for the resulting iterator. Default: `std::iterator_traits<BaseType>::difference_type`
`NamedParam` | A named template parameter (see below).

### Named Template Parameters

With seven template parameters, providing arguments for `iterator_adaptor` in the correct order can be challenging. Also, often times one would like to specify the sixth or seventh template parameter, but use the defaults for the third through fifth. As a solution to these problems we provide a mechanism for naming the last five template parameters, and providing them in any order through a set of named template parameters. The following classes are provided for specifying the parameters. Any of these classes can be used for any of the last five template parameters of `iterator_adaptor`.

>     template <class Value> struct value_type_is;
>     template <class Reference> struct reference_is;
>     template <class Pointer> struct pointer_is;
>     template <class Distance> struct difference_type_is;
>     template <class Category> struct iterator_category_is;

For example, the following adapts `foo_iterator` to create an InputIterator with `reference` type `foo`, and whose other traits are determined according to the defaults described above.

>     typedef iterator_adaptor<foo_iterator, foo_policies,
>       reference_is<foo>, iterator_category_is<std::input_iterator_tag>
>       > MyIterator;

### The Policies Class

The main task in using `iterator_adaptor` is creating an appropriate `Policies` class. The `Policies` class will become the functional heart of the resulting iterator, supplying the core operations that determine its behavior. The `iterator_adaptor` template defines all of the operators required of a Random Access Iterator by dispatching to a `Policies` object. Your `Policies` class must implement a subset of the core iterator operations below corresponding to the iterator categories you want it to support.

Policies Class Requirements
`T`: adapted iterator type; `x, y`: objects of type T; `p`: `T::policies_type` `d`: `T::difference_type`; `i1`, `i2`: `T::base_type`
Expression | Effects | Implements Operations | Required for Iterator Categories
--- | --- | --- | ---
`p.initialize(b)` | optionally modify base iterator during iterator construction | constructors | Input/ Output/ Forward/ Bidirectional/ Random Access
`p.dereference(x)` | returns an element of the iterator's `reference` type | `*x`, `x[d]`
`p.equal(x, y)` | tests the iterator for equality | `i1 == i2`, `i1 != i2`
`p.increment(x)` | increments the iterator | `++x`, `x++`
`p.decrement(x)` | decrements the iterator | `--x`, `x--` | Bidirectional/ Random Access
`p.distance(x, y)` | measures the distance between iterators | `y - x`, `x < y` | Random Access
`p.advance(x, n)` | adds an integer offset to iterators | `x + d`, `d + x`, `x += d`, `x - d`, `x -= d`

The library also supplies a "trivial" policy class, `default_iterator_policies`, which implements all seven of the core operations in the usual way. If you wish to create an iterator adaptor that only changes a few of the base type's behaviors, then you can derive your new policy class from `default_iterator_policies` to avoid retyping the usual behaviors. You should also look at `default_iterator_policies` as the ``boilerplate'' for your own policy classes, defining functions with the same interface. This is the definition of `default_iterator_policies`:

>     struct default_iterator_policies
>     {
>         // Some of these members were defined static, but Borland got confused
>         // and thought they were non-const. Also, Sun C++ does not like static
>         // function templates.

>         template <class Base>
>         void initialize(Base&)
>             { }

>         template <class IteratorAdaptor>
>         typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const
>             { return *x.base(); }

>         template <class IteratorAdaptor>
>         void increment(IteratorAdaptor& x)
>             { ++x.base(); }

>         template <class IteratorAdaptor>
>         void decrement(IteratorAdaptor& x)
>             { --x.base(); }

>         template <class IteratorAdaptor, class DifferenceType>
>         void advance(IteratorAdaptor& x, DifferenceType n)
>             { x.base() += n; }

>         template <class IteratorAdaptor1, class IteratorAdaptor2>
>         typename IteratorAdaptor1::difference_type
>         distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
>             { return y.base() - x.base(); }

>         template <class IteratorAdaptor1, class IteratorAdaptor2>
>         bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
>             { return x.base() == y.base(); }
>     };

Template member functions are used throughout `default_iterator_policies` so that it can be employed with a wide range of iterators. If we had used concrete types above, we'd have tied the usefulness of `default_iterator_policies` to a particular range of adapted iterators. If you follow the same pattern with your `Policies` classes, you can use them to generate more specialized adaptors along the lines of those supplied by this library.

### Additional Members

In addition to all of the member functions required of a Random Access Iterator, the `iterator_adaptor` class template defines the following members.

`explicit iterator_adaptor(const Base&, const Policies& = Policies())` Construct an adapted iterator from a base object and a policies object. As this constructor is `explicit`, it does not provide for implicit conversions from the `Base` type to the iterator adaptor.
`template <class B, class V, class R, class P> iterator_adaptor(const iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)` This constructor allows for conversion from mutable to constant adapted iterators. See below for more details. Requires: `B` is convertible to `Base`.
`const base_type& base() const;` Return a const reference to the base object.
`base_type& base();` Return a reference to the base object. This is to give the policies object access to the base object. See above for policies iterator_adaptor interaction.[8]

### Example

It is often useful to automatically apply some function to the value returned by dereferencing an iterator. The transform iterator makes it easy to create an iterator adaptor which does just that. Here we will show how easy it is to implement the transform iterator using the `iterator_adaptor` template.

We want to be able to adapt a range of iterators and functions, so the policies class will have a template parameter for the function type and it will have a data member of that type. We know that the function takes one argument and that we'll need to be able to deduce the `result_type` of the function so we can use it for the adapted iterator's `value_type`. AdaptableUnaryFunction is the Concept that fulfills those requirements.

To implement a transform iterator we will only change one of the base iterator's behaviors, so the `transform_iterator_policies` class can inherit the rest from `default_iterator_policies`. We will define the `dereference()` member function, which is used to implement `operator*()` of the adapted iterator. The implementation will dereference the base iterator and apply the function object. The complete code for `transform_iterator_policies` is:

>     template <class AdaptableUnaryFunction>
>     struct transform_iterator_policies : public default_iterator_policies
>     {
>         transform_iterator_policies() { }

>         transform_iterator_policies(const AdaptableUnaryFunction& f)
>             : m_f(f) { }

>         template <class IteratorAdaptor>
>         typename IteratorAdaptor::reference
>         dereference(const IteratorAdaptor& iter) const
>             { return m_f(*iter.base()); }

>         AdaptableUnaryFunction m_f;
>     };

The next step is to use the `iterator_adaptor` template to construct the transform iterator type. The nicest way to package the construction of the transform iterator is to create a type generator. The first template parameter to the generator will be the type of the function object and the second will be the base iterator type. We use `iterator_adaptor` to define the transform iterator type as a nested `typedef` inside the `transform_iterator_generator` class. Because the function may return by-value, we must limit the `iterator_category` to Input Iterator, and the iterator's `reference` type cannot be a true reference (the standard allows this for input iterators), so in this case we can use few of `iterator_adaptor`'s default template arguments.

>     template <class AdaptableUnaryFunction, class Iterator>
>     struct transform_iterator_generator
>     {
>         typedef typename AdaptableUnaryFunction::result_type value_type;
>     public:
>         typedef iterator_adaptor<Iterator,
>             transform_iterator_policies<AdaptableUnaryFunction>,
>             value_type, value_type, value_type*, std::input_iterator_tag>
>           type;
>     };

As a finishing touch, we will create an object generator for the transform iterator. Our object generator makes it more convenient to create a transform iterator.

>     template <class AdaptableUnaryFunction, class Iterator>
>     typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
>     make_transform_iterator(Iterator base,
>                             const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
>     {
>         typedef typename transform_iterator_generator<AdaptableUnaryFunction,
>           Iterator>::type result_t;
>         return result_t(base, f);
>     }

Here is an example that shows how to use a transform iterator to iterate through a range of numbers, multiplying each of them by 2 and printing the result to standard output.

>     #include <functional>
>     #include <algorithm>
>     #include <iostream>
>     #include <boost/iterator_adaptors.hpp>

>     int main(int, char*[])
>     {
>       int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
>       const int N = sizeof(x)/sizeof(int);
>       std::cout << "multiplying the array by 2:" << std::endl;
>       std::copy(boost::make_transform_iterator(x, std::bind1st(std::multiplies<int>(), 2)),
>           boost::make_transform_iterator(x + N, std::bind1st(std::multiplies<int>(), 2)),
>           std::ostream_iterator<int>(std::cout, " "));
>       std::cout << std::endl;
>       return 0;
>     }

> This output is:

>     2 4 6 8 10 12 14 16

### Iterator Interactions

C++ allows `const` and non-`const` pointers to interact in the following intuitive ways:

- a non-`const` pointer to `T` can be implicitly converted to a `const` pointer to `T`.
- `const` and non-`const` pointers to `T` can be freely mixed in comparison expressions.
- `const` and non-`const` pointers to `T` can be freely subtracted, in any order.

Getting user-defined iterators to work together that way is nontrivial (see here for an example of where the C++ standard got it wrong), but `iterator_adaptor` can make it easy. The rules are as follows:

- Adapted iterators that share the same `Policies`, `Category`, and `Distance` parameters are called interoperable.
- An adapted iterator can be implicitly converted to any other adapted iterator with which it is interoperable, so long as the `Base` type of the source iterator can be converted to the `Base` type of the target iterator.
- Interoperable iterators can be freely mixed in comparison expressions so long as the `Policies` class has `equal` (and, for random access iterators, `distance`) members that can accept both `Base` types in either order.
- Interoperable iterators can be freely mixed in subtraction expressions so long as the `Policies` class has a `distance` member that can accept both `Base` types in either order.

#### Example

The Projection Iterator adaptor is similar to the transform iterator adaptor in that its `operator*()` applies some function to the result of dereferencing the base iterator and then returns the result. The difference is that the function must return a reference to some existing object (for example, a data member within the `value_type` of the base iterator).

The projection_iterator_pair_generator template is a special two-type generator for mutable and constant versions of a projection iterator. It is defined as follows:

>     template <class AdaptableUnaryFunction, class Iterator, class ConstIterator>
>     struct projection_iterator_pair_generator {
>         typedef typename AdaptableUnaryFunction::result_type value_type;
>         typedef projection_iterator_policies<AdaptableUnaryFunction> policies;
>     public:
>         typedef iterator_adaptor<Iterator,policies,value_type> iterator;
>         typedef iterator_adaptor<ConstIterator,policies,value_type,
>             const value_type&,const value_type*> const_iterator;
>     };

It is assumed that the `Iterator` and `ConstIterator` arguments are corresponding mutable and constant iterators.

- Clearly, then, the `projection_iterator_pair_generator`'s `iterator` and `const_iterator` are interoperable, since they share the same `Policies` and since `Category` and `Distance` as supplied by `std::iterator_traits` through the default template parameters to `iterator_adaptor` should be the same.
- Since `Iterator` can presumably be converted to `ConstIterator`, the projection `iterator` will be convertible to the projection `const_iterator`.
- Since `projection_iterator_policies` implements only the `dereference` operation, and inherits all other behaviors from `default_iterator_policies`, which has fully-templatized `equal` and `distance` operations, the `iterator` and `const_iterator` can be freely mixed in comparison and subtraction expressions.

### Challenge

There is an unlimited number of ways the `iterator_adaptors` class can be used to create iterators. One interesting exercise would be to re-implement the iterators of `std::list` and `slist` using `iterator_adaptors`, where the adapted `Iterator` types would be node pointers.

### Concept Model

Depending on the `Base` and `Policies` template parameters, an `iterator_adaptor` can be a Input Iterator, Forward Iterator, Bidirectional Iterator, or Random Access Iterator.

### Declaration Synopsis

    template <class Base, class Policies,
        class Value = typename std::iterator_traits<Base>::value_type,
        class Reference = ...(see below),
        class Pointer = ...(see below),
        class Category = typename std::iterator_traits<Base>::iterator_category,
        class Distance = typename std::iterator_traits<Base>::difference_type
             >
    struct iterator_adaptor
    {
        typedef Distance difference_type;
        typedef typename boost::remove_const<Value>::type value_type;
        typedef Pointer pointer;
        typedef Reference reference;
        typedef Category iterator_category;
        typedef Base base_type;
        typedef Policies policies_type;

        iterator_adaptor();
        explicit iterator_adaptor(const Base&, const Policies& = Policies());

        base_type&       base();
        const base_type& base() const;

        template <class B, class V, class R, class P>
        iterator_adaptor(
            const iterator_adaptor<B,Policies,V,R,P,Category,Distance>&);

        reference operator*() const; [6]
        operator_arrow_result_type operator->() const; [3]
        value_type operator[](difference_type n) const; [4], [6]

        iterator_adaptor& operator++();
        iterator_adaptor& operator++(int);
        iterator_adaptor& operator--();
        iterator_adaptor& operator--(int);

        iterator_adaptor& operator+=(difference_type n);
        iterator_adaptor& operator-=(difference_type n);

        iterator_adaptor& operator-(Distance x) const;
    };

    template <class B, class P, class V, class R, class Ptr,
        class C, class D1, class D2>
    iterator_adaptor<B,P,V,R,Ptr,C,D1>
    operator+(iterator_adaptor<B,P,V,R,Ptr,C,D1>, D2);

    template <class B, class P, class V, class R, class Ptr,
        class C, class D1, class D2>
    iterator_adaptor<B,P,V,R,P,C,D1>
    operator+(D2, iterator_adaptor<B,P,V,R,Ptr,C,D1> p);

    template <class B1, class B2, class P, class V1, class V2,
        class R1, class R2, class P1, class P2, class C, class D>
    Distance operator-(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
                       const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);

    template <class B1, class B2, class P, class V1, class V2,
        class R1, class R2, class P1, class P2, class C, class D>
    bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
                    const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);

    // and similarly for operators !=, <, <=, >=, >

### Portability

Generally, the iterator adaptors library can be compiled with all compilers supporting iterator traits and type traits.

Microsoft VC++ is not able to handle iterator adaptors based on a `vector<T>::iterator` without specifying all template paramters explicitly. In case not all template parameters are specified explicitly, the iterator adaptors library will deduce these types using iterator_traits. But since in VC++ a `vector<T>::iterator` is a `T*`, VC++ can't handle using iterator_traits due to the lack of partial template specialization.

### Notes

[1] The standard specifies that the `value_type` of `const` iterators to `T` (e.g. `const T*`) is `non-const T`, while the `pointer` and `reference` types for all Forward Iterators are `const T*` and `const T&`, respectively. Stripping the `const`-ness of `Value` allows you to easily make a constant iterator by supplying a `const` type for `Value`, and allowing the defaults for the `Pointer` and `Reference` parameters to take effect. Although compilers that don't support partial specialization won't strip `const` for you, having a `const value_type` is often harmless in practice.

[2] If your compiler does not support partial specialization and the base iterator is a builtin pointer type, you will not be able to use the default for `Value` and will have to specify this type explicitly.

[3] The result type for the `operator->()` depends on the category and value type of the iterator and is somewhat complicated to describe. But be assured, it works in a stardard conforming fashion, providing access to members of the objects pointed to by the iterator.

[4] The result type of `operator[]()` is `value_type` instead of `reference` as might be expected. There are two reasons for this choice. First, the C++ standard only requires that the return type of an arbitrary Random Access Iterator's `operator[]`be ``convertible to T'' (Table 76), so when adapting an arbitrary base iterator we may not have a reference to return. Second, and more importantly, for certain kinds of iterators, returning a reference could cause serious memory problems due to the reference being bound to a temporary object whose lifetime ends inside of the `operator[]`.

[5] The `value_type` of an iterator may not be an abstract base class, however many common uses of iterators never need the `value_type`, only the `reference` type. If you wish to create such an iterator adaptor, use a dummy type such as `char` for the `Value` parameter, and use a reference to your abstract base class for the `Reference` parameter. Note that such an iterator does not fulfill the C++ standards requirements for a Forward Iterator, so you will need to use a less restrictive iterator category such as `std::input_iterator_tag`.

[6] There is a common misconception that an iterator should have two versions of `operator*` and of `operator[]`, one version that is a `const` member function and one version that is non-`const`. Perhaps the source of this misconception is that containers typically have const and non-const versions of many of their member functions. Iterators, however, are different. A particular iterator type can be either mutable or constant (but not both). One can assign to and change the object pointed to by a mutable iterator whereas a constant iterator returns constant objects when dereferenced. Whether the iterator object itself is `const` has nothing to do with whether the iterator is mutable or constant. This is analogous to the way built-in pointer types behave. For example, one can modify objects pointed to by a `const` pointer

        int* const x = new int;
        int i = 3;
        *x = i;

but one cannot modify objects pointed to by a pointer to `const`

        int const* x = new int;
        int i = 3;
        *x = i;

[7] If you are using a compiler that does not have a version of `std::iterator_traits` that works for pointers (i.e., if your compiler does not support partial specialization) then if the `Base` type is a const pointer, then the correct defaults for the `reference` and `pointer` types can not be deduced. You must specify these types explicitly.

[8] Exposing the base object might be considered as being dangerous. A possible fix would require compiler support for template friends. As this is not widely available today, the base object remains exposed for now.

Revised 30 Nov 2001

© Copyright Dave Abrahams and Jeremy Siek 2001. 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.