# Indirect Iterator Adaptor

Defined in header boost/iterator_adaptors.hpp

The indirect iterator adaptor augments an iterator by applying an extra dereference inside of `operator*()`. For example, this iterator makes it possible to view a container of pointers or smart-pointers (e.g. `std::list<boost::shared_ptr<foo> >`) as if it were a container of the pointed-to type. The following pseudo-code shows the basic idea of the indirect iterator:

>     // inside a hypothetical indirect_iterator class...
>     typedef std::iterator_traits<BaseIterator>::value_type Pointer;
>     typedef std::iterator_traits<Pointer>::reference reference;

>     reference indirect_iterator::operator*() const {
>       return **this->base_iterator;
>     }

## Synopsis

>     namespace boost {
>       template <class BaseIterator,
>                 class Value, class Reference, class Category, class Pointer>
>       struct indirect_iterator_generator;

>       template <class BaseIterator,
>                 class Value, class Reference, class ConstReference,
>                 class Category, class Pointer, class ConstPointer>
>       struct indirect_iterator_pair_generator;

>       template <class BaseIterator>
>       typename indirect_iterator_generator<BaseIterator>::type
>       make_indirect_iterator(BaseIterator base)
>     }

## The Indirect Iterator Type Generator

The `indirect_iterator_generator` template is a generator of indirect iterator types. The main template parameter for this class is the `BaseIterator` type that is being wrapped. In most cases the type of the elements being pointed to can be deduced using `std::iterator_traits`, but in some situations the user may want to override this type, so there are also template parameters that allow a user to control the `value_type`, `pointer`, and `reference` types of the resulting iterators.

>     template <class BaseIterator,
>               class Value, class Reference, class Pointer>
>     class indirect_iterator_generator
>     {
>     public:
>       typedef iterator_adaptor<...> type; // the resulting indirect iterator type
>     };

### Example

This example uses the `indirect_iterator_generator` to create indirect iterators which dereference the pointers stored in the `pointers_to_chars` array to access the `char`s in the `characters` array.

>     #include <boost/config.hpp>
>     #include <vector>
>     #include <iostream>
>     #include <iterator>
>     #include <boost/iterator_adaptors.hpp>

>     int main(int, char*[])
>     {
>       char characters[] = "abcdefg";
>       const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
>       char* pointers_to_chars[N];                        // at the end.
>       for (int i = 0; i < N; ++i)
>         pointers_to_chars[i] = &characters[i];

>       boost::indirect_iterator_generator<char**, char>::type
>         indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);

>       std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
>       std::cout << std::endl;

>       // to be continued...

### Template Parameters

Parameter | Description
--- | ---
`BaseIterator` | The iterator type being wrapped. The `value_type` of the base iterator should itself be dereferenceable. The return type of the `operator*` for the `value_type` should match the `Reference` type.

`Value`

The `value_type` of the resulting iterator, unless const. If Value is `const X`, a conforming compiler makes the `value_type` `non-const X` [1]. Note that if the default is used for `Value`, then there must be a valid specialization of `iterator_traits` for the value type of the base iterator.
Default: `std::iterator_traits<
std::iterator_traits<BaseIterator>::value_type >::value_type` [2]

`Reference` | The `reference` type of the resulting iterator, and in particular, the result type of `operator*()`. Default: `Value&`
`Pointer` | The `pointer` type of the resulting iterator, and in particular, the result type of `operator->()`. Default: `Value*`
`Category` | The `iterator_category` type for the resulting iterator. Default: `std::iterator_traits<BaseIterator>::iterator_category`

### Concept Model

The indirect iterator will model whichever standard iterator concept category is modeled by the base iterator. Thus, if the base iterator is a model of Random Access Iterator then so is the resulting indirect iterator. If the base iterator models a more restrictive concept, the resulting indirect iterator will model the same concept [3].

### Members

The indirect iterator type implements the member functions and operators required of the Random Access Iterator concept. In addition it has the following constructor:

    explicit indirect_iterator_generator::type(const BaseIterator& it)

## The Indirect Iterator Pair Generator

Sometimes a pair of `const`/non-`const` pair of iterators is needed, such as when implementing a container. The `indirect_iterator_pair_generator` class makes it more convenient to create this pair of iterator types.

>     template <class BaseIterator,
>               class Value, class Pointer, class Reference,
>               class ConstPointer, class ConstReference>
>     class indirect_iterator_pair_generator
>     {
>     public:
>       typedef iterator_adaptor<...> iterator;       // the mutable indirect iterator type
>       typedef iterator_adaptor<...> const_iterator; // the immutable indirect iterator type
>     };

### Example

>       // continuing from the last example...

>       typedef boost::indirect_iterator_pair_generator<char**,
>         char, char*, char&, const char*, const char&> PairGen;

>       char mutable_characters[N];
>       char* pointers_to_mutable_chars[N];
>       for (int i = 0; i < N; ++i)
>         pointers_to_mutable_chars[i] = &mutable_characters[i];

>       PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
>         mutable_indirect_last(pointers_to_mutable_chars + N);
>       PairGen::const_iterator const_indirect_first(pointers_to_chars),
>         const_indirect_last(pointers_to_chars + N);

>       std::transform(const_indirect_first, const_indirect_last,
>          mutable_indirect_first, std::bind1st(std::plus<char>(), 1));

>       std::copy(mutable_indirect_first, mutable_indirect_last,
>           std::ostream_iterator<char>(std::cout, ","));
>       std::cout << std::endl;
>       // to be continued...

The output is:

>     b,c,d,e,f,g,h,

### Template Parameters

Parameter | Description
--- | ---
`BaseIterator` | The iterator type being wrapped. The `value_type` of the base iterator should itself be dereferenceable. The return type of the `operator*` for the `value_type` should match the `Reference` type.
`Value` | The `value_type` of the resulting iterators. If Value is `const X`, a conforming compiler makes the `value_type` `non-const X` [1]. Note that if the default is used for `Value`, then there must be a valid specialization of `iterator_traits` for the value type of the base iterator. Default: `std::iterator_traits< std::iterator_traits<BaseIterator>::value_type >::value_type` [2]
`Reference` | The `reference` type of the resulting `iterator`, and in particular, the result type of its `operator*()`. Default: `Value&`
`Pointer` | The `pointer` type of the resulting `iterator`, and in particular, the result type of its `operator->()`. Default: `Value*`
`ConstReference` | The `reference` type of the resulting `const_iterator`, and in particular, the result type of its `operator*()`. Default: `const Value&`
`ConstPointer` | The `pointer` type of the resulting `const_iterator`, and in particular, the result type of its `operator->()`. Default: `const Value*`
`Category` | The `iterator_category` type for the resulting iterator. Default: `std::iterator_traits<BaseIterator>::iterator_category`

### Concept Model

The indirect iterators will model whichever standard iterator concept category is modeled by the base iterator. Thus, if the base iterator is a model of Random Access Iterator then so are the resulting indirect iterators. If the base iterator models a more restrictive concept, the resulting indirect iterators will model the same concept [3].

### Members

The resulting `iterator` and `const_iterator` types implement the member functions and operators required of the Random Access Iterator concept. In addition they support the following constructors:

>     explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it)
>     explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)

## The Indirect Iterator Object Generator

The `make_indirect_iterator()` function provides a more convenient way to create indirect iterator objects. The function saves the user the trouble of explicitly writing out the iterator types.

>     template <class BaseIterator>
>     typename indirect_iterator_generator<BaseIterator>::type
>     make_indirect_iterator(BaseIterator base)

### Example

Here we again print the `char`s from the array `characters` by accessing them through the array of pointers `pointer_to_chars`, but this time we use the `make_indirect_iterator()` function which saves us some typing.

>       // continuing from the last example...

>       std::copy(boost::make_indirect_iterator(pointers_to_chars),
>           boost::make_indirect_iterator(pointers_to_chars + N),
>           std::ostream_iterator<char>(std::cout, ","));
>       std::cout << std::endl;

>       return 0;
>     }

The output is:

>     a,b,c,d,e,f,g,

### Notes

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

[3]There is a caveat to which concept the indirect iterator can model. If the return type of the `operator*` for the base iterator's value type is not a true reference, then strickly speaking, the indirect iterator can not be a model of Forward Iterator or any of the concepts that refine it. In this case the `Category` for the indirect iterator should be specified as `std::input_iterator_tag`. However, even in this case, if the base iterator is a random access iterator, the resulting indirect iterator will still satisfy most of the requirements for Random Access Iterator.

Revised 28 Feb 2001

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