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 this->f(*this->base_iterator);
  }
All of the other operators of the transform iterator behave in the same fashion as those of 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 whose 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. The argument_type of the function object must match the value type of the base iterator. The result_type of the function object will be the resulting iterator's value_type. If you want the resulting iterator to behave as an iterator, the result of the function should be solely a function of its argument.
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 Transform Iterator Object Generator

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.

Revised 09 Mar 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.