c++boost.gif (8819 bytes)

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 containers of pointers such as std::list<foo*> as if there were containers of the pointed-to type (in this case std::list<foo>). 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 Pointer>
  struct indirect_iterator_generator;
  
  template <class BaseIterator,
	    class Value, class Pointer, class Reference, 
            class ConstPointer, class ConstReference>
  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 class indirect_iterator_generator is a helper class whose purpose is to construct an indirect iterator type. 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 for the type being pointed to (the Value) as well as reference and pointer versions of the type.
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 that 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

ParameterDescription
BaseIterator The iterator type being wrapped. The value type of the base iterator should be a pointer (a Trivial Iterator).
Value The value-type of the value-type of the base iterator. That is, the type of object that is accessed by dereferences in the base iterator twice.
Default:
std::iterator_traits<std::iterator_traits<BaseIterator>::value_type>::value_type
Reference The corresponding reference type for the Value.
Default: Value&
Pointer The corresponding pointer type for the Value.
Default: Value*

Model of

If the base iterator is a model of Random Access Iterator then so is the resulting indirect iterator. If the base iterator supports less functionality than this the resulting indirect iterator will also support less functionality.

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:
indirect_iterator_generator::type(const BaseIterator& it)


The Indirect Iterator Pair Generator

Sometimes a mutable/const pair of iterator types is needed, such as when implementing a container type. 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 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(), 1));

  std::copy(mutable_indirect_first, mutable_indirect_last,
	    std::ostream_iterator(std::cout, ","));
  std::cout << std::endl;
  // to be continued...
The output is:
b,c,d,e,f,g,h,

Template Parameters

ParameterDescription
BaseIterator The iterator type being wrapped. The value type of the base iterator should be a pointer (a Trivial Iterator).
Value The value-type of the value-type of the base iterator. That is, the type of object that is accessed by dereferences in the base iterator twice.
Default:
std::iterator_traits<std::iterator_traits<BaseIterator>::value_type>::value_type
Reference The corresponding reference type for the Value.
Default: Value&
Pointer The corresponding pointer type for the Value.
Default: Value*
ConstReference The corresponding const reference type for the Value.
Default: const Value&
ConstPointer The corresponding const pointer type for the Value.
Default: const Value*

Model of

If the base iterator is a model of Random Access Iterator then so is the resulting indirect iterator types. If the base iterator supports less functionality than this the resulting indirect iterator types will also support less functionality. The resulting iterator type is mutable, and the resulting const_iterator type is constant.

Members

The resulting iterator and const_iterator types implements the member functions and operators required of the Random Access Iterator concept. In addition they support the following constructors:
indirect_iterator_pair_generator::iterator(const BaseIterator& it)
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(std::cout, ","));
  std::cout << std::endl;

  return 0;
}
The output is:
a,b,c,d,e,f,g,

Revised 10 Feb 2001

© Copyright Jeremy Siek 2000. 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.