c++boost.gif (8819 bytes)

Transform Iterator Adaptor

Defined in header boost/iterator_adaptors.hpp

The transform iterator adaptor augments an iterator by applying some function object to the result of dereferencing the iterator. Another words, the operator* of the transform iterator first dereferences the base iterator, passes the result of this to the function object, and then returns the result. The following pseudo-code shows the basic idea:

  value_type transform_iterator::operator*() const {
    return f(*this->base_iterator);
  }
All of the other operators of the transform iterator behave in the same fashion as the base iterator.

Synopsis

namespace boost {
  template <class AdaptableUnaryFunction, class BaseIterator>
  class transform_iterator_generator;

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

The Transform Iterator Type Generator

The class transform_iterator_generator is a helper class who's purpose is to construct a transform iterator type. The template parameters for this class are the AdaptableUnaryFunction function object type and the BaseIterator type that is being wrapped.
template <class AdaptableUnaryFunction, class Iterator>
class transform_iterator_generator
{
public:
    typedef iterator_adaptor<...> type;
};

Example

The following is an example of how to use the transform_iterator_generator class to iterate through a range of numbers, multiplying each of them by 2 when they are dereferenced.

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

int
main(int, char*[])
{
  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };

  typedef std::binder1st< std::multiplies<int> > Function;
  typedef boost::transform_iterator_generator<Function, int*>::type doubling_iterator;

  doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
    i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));

  std::cout << "multiplying the array by 2:" << std::endl;
  while (i != i_end)
    std::cout << *i++ << " ";
  std::cout << std::endl;

  // to be continued...
The output from this part is:
2 4 6 8 10 12 14 16

Template Parameters

ParameterDescription
AdaptableUnaryFunction The function object that transforms each element in the iterator range.
BaseIterator The iterator type being wrapped. This type must at least be a model of the InputIterator concept.

Model of

The transform iterator adaptor (the type transform_iterator_generator<...>::type) is a model of Input Iterator[1].

Members

The transform iterator type implements the member functions and operators required of the Random Access Iterator concept, except that the reference type is the same as the value_type so operator*() returns by-value. In addition it has the following constructor:
transform_iterator_generator::type(const BaseIterator& it, const AdaptableUnaryFunction& f = AdaptableUnaryFunction())


The Make Transform Iterator Function

template <class AdaptableUnaryFunction, class BaseIterator>
typename transform_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
make_transform_iterator(BaseIterator base, const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
This function provides a convenient way to create transform iterators.

Example

Continuing from the previous example, we use the make_transform_iterator() function to add four to each element of the array.
  std::cout << "adding 4 to each element in the array:" << std::endl;

  std::copy(boost::make_transform_iterator(x, std::bind1st(std::plus(), 4)),
	    boost::make_transform_iterator(x + N, std::bind1st(std::plus(), 4)),
	    std::ostream_iterator(std::cout, " "));
  std::cout << std::endl;

  return 0;
}
The output from this part is:
5 6 7 8 9 10 11 12

Notes

[1] If the base iterator is a model of Random Access Iterator then the transform iterator will also suppport most of the functionality required by the Random Access Iterator concept. However, a transform iterator can never completely satisfy the requirements for Forward Iterator (or of any concepts that refine Forward Iterator, which includes Random Access Iterator and Bidirectional Iterator) since the operator* of the transform iterator always returns by-value.