diff --git a/doc/facade-and-adaptor.html b/doc/facade-and-adaptor.html index 49961bd..018b502 100755 --- a/doc/facade-and-adaptor.html +++ b/doc/facade-and-adaptor.html @@ -614,7 +614,7 @@ template < , class Difference = ptrdiff_t > class iterator_facade { -public: + public: typedef remove_const<Value>::type value_type; typedef Reference reference; typedef Value* pointer; @@ -631,6 +631,8 @@ public: Derived& operator+=(difference_type n); Derived& operator-=(difference_type n); Derived operator-(difference_type n) const; + protected: + typedef iterator_facade iterator_facade_; }; // Comparison operators @@ -1202,6 +1204,7 @@ class iterator_adaptor explicit iterator_adaptor(Base iter); Base const& base() const; protected: + typedef iterator_adaptor iterator_adaptor_; Base const& base_reference() const; Base& base_reference(); private: // Core iterator interface for iterator_facade. diff --git a/doc/facade-and-adaptor.pdf b/doc/facade-and-adaptor.pdf index 65ecde4..7b052e1 100755 Binary files a/doc/facade-and-adaptor.pdf and b/doc/facade-and-adaptor.pdf differ diff --git a/doc/iterator_adaptor.html b/doc/iterator_adaptor.html index e03cf67..d09d4c5 100644 --- a/doc/iterator_adaptor.html +++ b/doc/iterator_adaptor.html @@ -3,7 +3,7 @@ - + Iterator Adaptor @@ -12,7 +12,6 @@ -

Iterator Adaptor

@@ -32,6 +31,7 @@ Railway Operation and Construction
Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
+
@@ -55,7 +55,7 @@ depends on the operations supported by the iterator_facade are redefined in the Derived class.

-

Table of Contents

+

Table of Contents

You probably didn't think of it this way, but the node_base* -object which underlies node_iterator is itself an iterator, +object that underlies node_iterator is itself an iterator, just like all other pointers. If we examine that pointer closely from an iterator perspective, we can see that it has much in common with the node_iterator we're building. First, they share most @@ -358,9 +359,10 @@ of the same associated types (value_typeoperator* and operator== on the node_iterator return the result of invoking the same operations on the underlying pointer, via the node_iterator's -dereference and equal member functions). However, the operator++ for -node_iterator behaves differently than for node_base* -since it follows the m_next pointer.

+dereference and equal member functions). The only real behavioral difference +between node_base* and node_iterator can be observed when +they are incremented: node_iterator follows the +m_next pointer, while node_base* just applies an address offset.

It turns out that the pattern of building an iterator on another iterator-like type (the Base 1 type) while modifying just a few aspects of the underlying type's behavior is an @@ -384,16 +386,12 @@ class node_iter private: struct enabler {}; // a private type avoids misuse - typedef boost::iterator_adaptor< - node_iter<Value>, Value*, boost::use_default, boost::forward_traversal_tag - > super_t; - public: node_iter() - : super_t(0) {} + : node_iter::iterator_adaptor_(0) {} explicit node_iter(Value* p) - : super_t(p) {} + : node_iter::iterator_adaptor_(p) {} template <class OtherValue> node_iter( @@ -403,14 +401,20 @@ class node_iter , enabler >::type = enabler() ) - : super_t(other.base()) {} + : node_iter::iterator_adaptor_(other.base()) {} private: friend class boost::iterator_core_access; void increment() { this->base_reference() = this->base()->next(); } }; -

You can see an example program which exercises this version of the +

Note the use of node_iter::iterator_adaptor_ here: because +iterator_adaptor defines a nested iterator_adaptor_ type +that refers to itself, that gives us a convenient way to refer to +the complicated base class type of node_iter<Value>. [Note: +this technique is known not to work with Borland C++ 5.6.4 and +Metrowerks CodeWarrior versions prior to 9.0]

+

You can see an example program that exercises this version of the node iterators here.

In the case of node_iter, it's not very compelling to pass boost::use_default as iterator_adaptor's Value @@ -423,7 +427,7 @@ iterator type argument and reverses its direction of traversal, since the original iterator and the reversed one have all the same associated types, iterator_adaptor's delegation of default types to its Base saves the implementor of -boost::reverse_iterator from writing

+boost::reverse_iterator from writing:

 std::iterator_traits<Iterator>::some-associated-type
 
diff --git a/doc/iterator_adaptor.pdf b/doc/iterator_adaptor.pdf index 4854b0a..1dca935 100755 Binary files a/doc/iterator_adaptor.pdf and b/doc/iterator_adaptor.pdf differ diff --git a/doc/iterator_adaptor_ref.rst b/doc/iterator_adaptor_ref.rst index fb6a88c..b8de30d 100644 --- a/doc/iterator_adaptor_ref.rst +++ b/doc/iterator_adaptor_ref.rst @@ -23,6 +23,7 @@ explicit iterator_adaptor(Base iter); Base const& base() const; protected: + typedef iterator_adaptor iterator_adaptor\_; Base const& base_reference() const; Base& base_reference(); private: // Core iterator interface for iterator_facade. diff --git a/doc/iterator_adaptor_tutorial.rst b/doc/iterator_adaptor_tutorial.rst index ed1aa7e..4106846 100755 --- a/doc/iterator_adaptor_tutorial.rst +++ b/doc/iterator_adaptor_tutorial.rst @@ -21,7 +21,7 @@ we're going to pick up right where it left off. words, the original iterator traverses a one-element array. You probably didn't think of it this way, but the ``node_base*`` -object which underlies ``node_iterator`` is itself an iterator, +object that underlies ``node_iterator`` is itself an iterator, just like all other pointers. If we examine that pointer closely from an iterator perspective, we can see that it has much in common with the ``node_iterator`` we're building. First, they share most @@ -30,9 +30,10 @@ of the same associated types (``value_type``, ``reference``, core functionality is the same: ``operator*`` and ``operator==`` on the ``node_iterator`` return the result of invoking the same operations on the underlying pointer, via the ``node_iterator``\ 's -|dereference_and_equal|_). However, the ``operator++`` for -``node_iterator`` behaves differently than for ``node_base*`` -since it follows the ``m_next`` pointer. +|dereference_and_equal|_). The only real behavioral difference +between ``node_base*`` and ``node_iterator`` can be observed when +they are incremented: ``node_iterator`` follows the +``m_next`` pointer, while ``node_base*`` just applies an address offset. .. |dereference_and_equal| replace:: ``dereference`` and ``equal`` member functions .. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations @@ -60,16 +61,12 @@ behaviors other than ``increment``. The implementation of private: struct enabler {}; // a private type avoids misuse - typedef boost::iterator_adaptor< - node_iter, Value*, boost::use_default, boost::forward_traversal_tag - > super_t; - public: node_iter() - : super_t(0) {} + : node_iter::iterator_adaptor_(0) {} explicit node_iter(Value* p) - : super_t(p) {} + : node_iter::iterator_adaptor_(p) {} template node_iter( @@ -79,14 +76,21 @@ behaviors other than ``increment``. The implementation of , enabler >::type = enabler() ) - : super_t(other.base()) {} + : node_iter::iterator_adaptor_(other.base()) {} private: friend class boost::iterator_core_access; void increment() { this->base_reference() = this->base()->next(); } }; -You can see an example program which exercises this version of the +Note the use of ``node_iter::iterator_adaptor_`` here: because +``iterator_adaptor`` defines a nested ``iterator_adaptor_`` type +that refers to itself, that gives us a convenient way to refer to +the complicated base class type of ``node_iter``. [Note: +this technique is known not to work with Borland C++ 5.6.4 and +Metrowerks CodeWarrior versions prior to 9.0] + +You can see an example program that exercises this version of the node iterators `here`__. __ ../example/node_iterator3.cpp @@ -102,7 +106,7 @@ iterator type argument and reverses its direction of traversal, since the original iterator and the reversed one have all the same associated types, ``iterator_adaptor``\ 's delegation of default types to its ``Base`` saves the implementor of -``boost::reverse_iterator`` from writing +``boost::reverse_iterator`` from writing: .. parsed-literal:: diff --git a/doc/iterator_facade.html b/doc/iterator_facade.html index 1c51e9a..207485b 100644 --- a/doc/iterator_facade.html +++ b/doc/iterator_facade.html @@ -3,7 +3,7 @@ - + Iterator Facade @@ -12,7 +12,6 @@ -

Iterator Facade

@@ -32,6 +31,7 @@ Railway Operation and Construction
Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
+
@@ -43,7 +43,7 @@ and associated types, to be supplied by a derived iterator class.
-

Table of Contents

+

Table of Contents

  • Overview
    • Usage
    • @@ -143,7 +143,7 @@ of the derived iterator type. These member functions are described briefly below and in more detail in the iterator facade requirements.

      - +
      @@ -261,7 +261,6 @@ are described in terms of a set of requirements, which must be satisfied by the iterator_facade implementation.

      - @@ -284,7 +283,7 @@ template < , class Difference = ptrdiff_t > class iterator_facade { -public: + public: typedef remove_const<Value>::type value_type; typedef Reference reference; typedef Value* pointer; @@ -301,6 +300,8 @@ public: Derived& operator+=(difference_type n); Derived& operator-=(difference_type n); Derived operator-(difference_type n) const; + protected: + typedef iterator_facade iterator_facade_; }; // Comparison operators @@ -444,8 +445,8 @@ object of a single pass iterator type interoperable with X.

      -

      iterator_facade Core Operations

      -
      [Cop95](1, 2) [Coplien, 1995] Coplien, J., Curiously Recurring Template Patterns, C++ Report, February 1995, pp. 24-27.
      +

      iterator_facade Core Operations

      +
      @@ -1089,7 +1090,7 @@ iterator! For a working example of its use, see

      A constant node_iterator