diff --git a/iterator_adaptors.htm b/iterator_adaptors.htm index e8494e8..8f6323c 100644 --- a/iterator_adaptors.htm +++ b/iterator_adaptors.htm @@ -23,7 +23,8 @@ for constructing commonly used iterator adaptors.

  • iterator_adaptors.
  • iterator_adaptor.
  • transform_iterator -
  • indirect_iterators +
  • Indirect Iterator Adaptors +
  • Projection Iterator Adaptors
  • reverse_iterators
  • integer_range @@ -39,7 +40,11 @@ interactions. He also contributed the indirect_iterators and Jeremy Siek contributed transform_iterator, integer_range, -and this documentation. +and this documentation.
    + +John Potter +contributed indirect_iterator and projection_iterator +and made some simplifications to iterator_adaptor.

    The Iterator Adaptors Class

    @@ -60,10 +65,10 @@ follows:
    -template <class Iterator, 
    -          class ConstIterator, 
    +template <class Iterator,
    +          class ConstIterator,
               class Traits = std::iterator_traits<Iterator>,
    -          class ConstTraits = std::iterator_traits<ConstIterator>, 
    +          class ConstTraits = std::iterator_traits<ConstIterator>,
               class Policies = default_iterator_policies>
     struct iterator_adaptors
     {
    @@ -119,7 +124,7 @@ struct default_iterator_policies
         { return *x; }
     
       template <class Iterator>
    -  void increment(Iterator& x) const
    +  static void increment(Iterator& x)
         { ++x; }
     
       template <class Iterator1, class Iterator2>
    @@ -128,12 +133,12 @@ struct default_iterator_policies
     
       // required for a BidirectionalIterator
       template <class Iterator>
    -  void decrement(Iterator& x) const
    +  static void decrement(Iterator& x)
         { --x; }
     
       // required for a RandomAccessIterator
       template <class Iterator, class DifferenceType>
    -  void advance(Iterator& x, DifferenceType n) const
    +  static void advance(Iterator& x, DifferenceType n)
         { x += n; }
     
       template <class Difference, class Iterator1, class Iterator2>
    @@ -174,9 +179,8 @@ arguments.
     
    -template <class Iterator, 
    +template <class Iterator,
               class Policies = default_iterator_policies,
    -          class NonconstIterator = Iterator,         
               class Traits = std::iterator_traits<Iterator> >
     struct iterator_adaptor;
     
    @@ -319,67 +323,107 @@ main(int, char*[])
    -

    The Indirect Iterators Class

    +

    The Indirect Iterator Adaptors

    It is not all that uncommon to create data structures that consist of pointers to pointers. For such a structure it might be nice to have an iterator that applies a double-dereference inside the operator*(). The implementation of this is similar to the -transform_iterators[3]. We first create a -policies class which does a double-dereference in the -dereference() method. We then create a traits class, this -time also including a template parameter for the traits of the second -level iterators as well as the first. Lastly we wrap this up in the -type generator indirect_iterators, using -iterator_adaptors to do most of the work. +transform_iterators[3]. When talking about a +data structure of pointers to pointers (or more generally, iterators +to iterators), we call the first level iterators the outer +iterators and the second level iterators the inner +iterators. For example, if the outer iterator type is T** +then the inner iterator type is T*. + +To implement the indirect adaptors, we first create a policies class +which does a double-dereference in the dereference() method.

    -  struct indirect_iterator_policies : public default_iterator_policies
    -  {
    +struct indirect_iterator_policies : public default_iterator_policies
    +{
         template <class Reference, class Iterator>
         Reference dereference(type<Reference>, const Iterator& x) const
    -      { return **x; }
    -  };
    +        { return **x; }
    +};
    +
    - template <class IndirectIterator, - class IndirectTraits = std::iterator_traits<IndirectIterator>, - class Traits = - std::iterator_traits<typename IndirectTraits::value_type> - > - struct indirect_traits - { - typedef typename IndirectTraits::difference_type difference_type; - typedef typename Traits::value_type value_type; - typedef typename Traits::pointer pointer; - typedef typename Traits::reference reference; - typedef typename IndirectTraits::iterator_category iterator_category; - }; +We then create a traits class, including a template parameter for both +the inner and outer iterators and traits classes. The +difference_type and iterator_category come from the +outer iterator, while the value_type, pointer, and +reference types come from the inner iterator. - template <class IndirectIterator, class ConstIndirectIterator, - class IndirectTraits = - std::iterator_traits<IndirectIterator>, - class ConstIndirectTraits = - std::iterator_traits<ConstIndirectIterator>, - class Traits = - std::iterator_traits<typename IndirectTraits::value_type> - > - struct indirect_iterators - { - typedef typename IndirectTraits::value_type Iterator; - typedef typename Traits::value_type ValueType; - typedef iterator_adaptors<IndirectIterator, ConstIndirectIterator, - indirect_traits<IndirectIterator, IndirectTraits, Traits>, - indirect_traits<ConstIndirectIterator, ConstIndirectTraits, Traits>, - indirect_iterator_policies - > Adaptors; +

    + +
    +
    +template <class OuterIterator, class InnerIterator,
    +          class OuterTraits = std::iterator_traits<OuterIterator>,
    +          class InnerTraits = std::iterator_traits<InnerIterator>
    +         >
    +struct indirect_traits
    +{
    +    typedef typename OuterTraits::difference_type difference_type;
    +    typedef typename InnerTraits::value_type value_type;
    +    typedef typename InnerTraits::pointer pointer;
    +    typedef typename InnerTraits::reference reference;
    +    typedef typename OuterTraits::iterator_category iterator_category;
    +};
    +
    + +Lastly we wrap this up in two type generators: +indirect_iterator for creating a single indirect iterator +type, and indirect_iterators for creating an const/non-const +pair of indirect iterator types. We use the iterator_adaptor +and iterator_adaptors classes here to do most of the work. + +

    + +
    +
    +template <class OuterIterator, class InnerIterator,
    +          class OuterTraits = std::iterator_traits<OuterIterator>,
    +          class InnerTraits = std::iterator_traits<InnerIterator>
    +         >
    +struct indirect_iterator
    +{
    +    typedef iterator_adaptor<OuterIterator,
    +        indirect_iterator_policies,
    +        indirect_traits<OuterIterator, InnerIterator,
    +                        OuterTraits, InnerTraits>
    +    > type;
    +};
    +
    +template <class OuterIterator,      // Mutable or Immutable, does not matter
    +          class InnerIterator,      // Mutable
    +          class ConstInnerIterator, // Immutable
    +          class OuterTraits = std::iterator_traits<OuterIterator>,
    +          class InnerTraits = std::iterator_traits<InnerIterator>,
    +          class ConstInnerTraits = std::iterator_traits<ConstInnerIterator>
    +         >
    +struct indirect_iterators
    +{
    +    typedef iterator_adaptors<OuterIterator, OuterIterator,
    +        indirect_traits<OuterIterator, InnerIterator,
    +                        OuterTraits, InnerTraits>,
    +        indirect_traits<OuterIterator, ConstInnerIterator,
    +                        OuterTraits, ConstInnerTraits>,
    +        indirect_iterator_policies
    +        > Adaptors;
         typedef typename Adaptors::iterator iterator;
         typedef typename Adaptors::const_iterator const_iterator;
    -  };
    +};
     
    + +

    The Projection Iterator Adaptors

    + + +

    The Reverse Iterators Class