diff --git a/iterator_adaptors.htm b/iterator_adaptors.htm index aa3c42a..9657a9e 100644 --- a/iterator_adaptors.htm +++ b/iterator_adaptors.htm @@ -26,6 +26,37 @@ "../../more/generic_programming.html#adaptors">adaptors which apply specific useful behaviors to arbitrary base iterators. +
The library's interface has changed since it was first released, breaking + backward compatibility: + +
``Policy Adaptors and the Boost Iterator + Adaptor Library'' is a technical paper describing this library and the + powerful design pattern on which it is based. It was presented at the C++ Template Workshop at OOPSLA + 2001; the slides from the talk are available here. Please note that while the slides + incorporate the minor interface changes described in the previous section, + the paper does not. +
struct default_iterator_policies { - template <class BaseType> - void initialize(BaseType&) - { } + // Some of these members were defined static, but Borland got confused + // and thought they were non-const. Also, Sun C++ does not like static + // function templates. - template <class Reference, class BaseType> - Reference dereference(type<Reference>, const BaseType& x) const - { return *x; } + template <class Base> + void initialize(Base&) + { } - template <class BaseType> - void increment(BaseType& x) - { ++x; } + template <class IteratorAdaptor> + typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const + { return *x.base(); } - template <class BaseType1, class BaseType2> - bool equal(const BaseType1& x, const BaseType2& y) const - { return x == y; } + template <class IteratorAdaptor> + void increment(IteratorAdaptor& x) + { ++x.base(); } - template <class BaseType> - void decrement(BaseType& x) - { --x; } + template <class IteratorAdaptor> + void decrement(IteratorAdaptor& x) + { --x.base(); } - template <class BaseType, class DifferenceType> - void advance(BaseType& x, DifferenceType n) - { x += n; } + template <class IteratorAdaptor, class DifferenceType> + void advance(IteratorAdaptor& x, DifferenceType n) + { x.base() += n; } - template <class Difference, class BaseType1, class BaseType2> - Difference distance(type<Difference>, const BaseType1& x, const BaseType2& y) const - { return y - x; } + template <class IteratorAdaptor1, class IteratorAdaptor2> + typename IteratorAdaptor1::difference_type + distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const + { return y.base() - x.base(); } - template <class BaseType1, class BaseType2> - bool less(const BaseType1& x, const BaseType2& y) const - { return x < y; } + template <class IteratorAdaptor1, class IteratorAdaptor2> + bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const + { return x.base() == y.base(); } }; -- +
Template member functions are used throughout
default_iterator_policies so that it can be employed with a wide
@@ -451,7 +482,7 @@ struct default_iterator_policies
iterator_adaptor(const
iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)
- This constructor allows for conversion from non-const to
+ This constructor allows for conversion from mutable to
constant adapted iterators. See below for more details.
Requires: B is convertible to Base.
@@ -483,34 +514,31 @@ struct default_iterator_policies
To implement a transform iterator we will only change one of the base
iterator's behaviors, so the transform_iterator_policies class can
- inherit the rest from default_iterator_policies. We will define
- the dereference() member function, which is used to implement
+ inherit the rest from default_iterator_policies. We will define the
+ dereference() member function, which is used to implement
operator*() of the adapted iterator. The implementation will
- dereference the base iterator and apply the function object. The
- type<Reference> parameter is used to convey the appropriate
- return type. The complete code for transform_iterator_policies
- is:
+ dereference the base iterator and apply the function object. The complete
+ code for transform_iterator_policies is:
-
-
-- template <class AdaptableUnaryFunction> - struct transform_iterator_policies : public default_iterator_policies - { ++}; + ++template <class AdaptableUnaryFunction> +struct transform_iterator_policies : public default_iterator_policies +{ transform_iterator_policies() { } transform_iterator_policies(const AdaptableUnaryFunction& f) - : m_f(f) { } - - template <class Reference, class BaseIterator> - Reference dereference(type<Reference>, const BaseIterator& i) const - { return m_f(*i); } + : m_f(f) { } + + template <class IteratorAdaptor> + typename IteratorAdaptor::reference + dereference(const IteratorAdaptor& iter) const + { return m_f(*iter.base()); } AdaptableUnaryFunction m_f; - }; --
The next step is to use the iterator_adaptor template to construct the transform iterator type. The nicest way to package the @@ -546,7 +574,7 @@ public:
As a finishing touch, we will create an object generator
- for the transform iterator. This is a function that makes it more
+ for the transform iterator. Our object generator makes it more
convenient to create a transform iterator.
@@ -785,12 +813,12 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
reference types for all Forward Iterators are
const T* and const T&, respectively. Stripping the
- const-ness of Value allows you to easily
- make a const iterator adaptor by supplying a const type
- for Value, and allowing the defaults for the Pointer and
- Reference parameters to take effect. Although compilers that don't
- support partial specialization won't strip const for you, having a
- const value_type is often harmless in practice.
+ const-ness of Value allows you to easily make a constant
+ iterator by supplying a const type for Value, and allowing
+ the defaults for the Pointer and Reference parameters to
+ take effect. Although compilers that don't support partial specialization
+ won't strip const for you, having a const value_type is
+ often harmless in practice.
[2] If your compiler does not support partial specialization and the base iterator is a builtin pointer type, you