While the iterator interface is rich, there is a core subset of the
interface that is necessary for all the functionality. We have
identified the following core behaviors for iterators:

dereferencing

incrementing

decrementing

equality comparison

random-access motion

distance measurement

In addition to the behaviors listed above, the core interface elements
include the associated types exposed through iterator traits:
value_type, reference, difference_type, and
iterator_category.

Iterator facade uses the Curiously Recurring Template
Pattern (CRTP) [Cop95] so that the user can specify the behavior
of iterator_facade in a derived class. Former designs used
policy objects to specify the behavior, but that approach was
discarded for several reasons:

the creation and eventual copying of the policy object may create
overhead that can be avoided with the current approach.

The policy object approach does not allow for custom constructors
on the created iterator types, an essential feature if
iterator_facade should be used in other library
implementations.

Without the use of CRTP, the standard requirement that an
iterator's operator++ returns the iterator type itself
would mean that all iterators built with the library would
have to be specializations of iterator_facade<...>, rather
than something more descriptive like
indirect_iterator<T*>. Cumbersome type generator
metafunctions would be needed to build new parameterized
iterators, and a separate iterator_adaptor layer would be
impossible.

The user of iterator_facade derives his iterator class from a
specialization of iterator_facade and passes the derived
iterator class as iterator_facade's first template parameter.
The order of the other template parameters have been carefully
chosen to take advantage of useful defaults. For example, when
defining a constant lvalue iterator, the user can pass a
const-qualified version of the iterator's value_type as
iterator_facade's Value parameter and omit the
Reference parameter which follows.

The derived iterator class must define member functions implementing
the iterator's core behaviors. The following table describes
expressions which are required to be valid depending on the category
of the derived iterator type. These member functions are described
briefly below and in more detail in the iterator facade
requirements.

Expression

Effects

i.dereference()

Access the value referred to

i.equal(j)

Compare for equality with j

i.increment()

Advance by one position

i.decrement()

Retreat by one position

i.advance(n)

Advance by n positions

i.distance_to(j)

Measure the distance to j

In addition to implementing the core interface functions, an iterator
derived from iterator_facade typically defines several
constructors. To model any of the standard iterator concepts, the
iterator must at least have a copy constructor. Also, if the iterator
type X is meant to be automatically interoperate with another
iterator type Y (as with constant and mutable iterators) then
there must be an implicit conversion from X to Y or from Y
to X (but not both), typically implemented as a conversion
constructor. Finally, if the iterator is to model Forward Traversal
Iterator or a more-refined iterator concept, a default constructor is
required.

iterator_facade and the operator implementations need to be able
to access the core member functions in the derived class. Making the
core member functions public would expose an implementation detail to
the user. The design used here ensures that implementation details do
not appear in the public interface of the derived iterator type.

Preventing direct access to the core member functions has two
advantages. First, there is no possibility for the user to accidently
use a member function of the iterator when a member of the value_type
was intended. This has been an issue with smart pointer
implementations in the past. The second and main advantage is that
library implementers can freely exchange a hand-rolled iterator
implementation for one based on iterator_facade without fear of
breaking code that was accessing the public core member functions
directly.

In a naive implementation, keeping the derived class' core member
functions private would require it to grant friendship to
iterator_facade and each of the seven operators. In order to
reduce the burden of limiting access, iterator_core_access is
provided, a class that acts as a gateway to the core member functions
in the derived iterator class. The author of the derived class only
needs to grant friendship to iterator_core_access to make his core
member functions available to the library.

iterator_core_access will be typically implemented as an empty
class containing only private static member functions which invoke the
iterator core member functions. There is, however, no need to
standardize the gateway protocol. Note that even if
iterator_core_access used public member functions it would not
open a safety loophole, as every core member function preserves the
invariants of the iterator.

The indexing operator for a generalized iterator presents special
challenges. A random access iterator's operator[] is only
required to return something convertible to its value_type.
Requiring that it return an lvalue would rule out currently-legal
random-access iterators which hold the referenced value in a data
member (e.g. counting_iterator), because *(p+n) is a reference
into the temporary iterator p+n, which is destroyed when
operator[] returns.

Writable iterators built with iterator_facade implement the
semantics required by the preferred resolution to issue 299 and
adopted by proposal n1550: the result of p[n] is an object
convertible to the iterator's value_type, and p[n]=x is
equivalent to *(p+n)=x (Note: This result object may be
implemented as a proxy containing a copy of p+n). This approach
will work properly for any random-access iterator regardless of the
other details of its implementation. A user who knows more about
the implementation of her iterator is free to implement an
operator[] that returns an lvalue in the derived iterator
class; it will hide the one supplied by iterator_facade from
clients of her iterator.

The reference type of a readable iterator (and today's input
iterator) need not in fact be a reference, so long as it is
convertible to the iterator's value_type. When the value_type
is a class, however, it must still be possible to access members
through operator->. Therefore, an iterator whose reference
type is not in fact a reference must return a proxy containing a copy
of the referenced value from its operator->.

The return types for iterator_facade's operator-> and
operator[] are not explicitly specified. Instead, those types
are described in terms of a set of requirements, which must be
satisfied by the iterator_facade implementation.

iterator-category(C,R,V) :=
if (C is convertible to std::input_iterator_tag
|| C is convertible to std::output_iterator_tag
)
return C
else if (C is not convertible to incrementable_traversal_tag)
the program is ill-formed
else return a type X satisfying the following two constraints:
1. X is convertible to X1, and not to any more-derived
type, where X1 is defined by:
if (R is a reference type
&& C is convertible to forward_traversal_tag)
{
if (C is convertible to random_access_traversal_tag)
X1 = random_access_iterator_tag
else if (C is convertible to bidirectional_traversal_tag)
X1 = bidirectional_iterator_tag
else
X1 = forward_iterator_tag
}
else
{
if (C is convertible to single_pass_traversal_tag
&& R is convertible to V)
X1 = input_iterator_tag
else
X1 = C
}
2. category-to-traversal(X) is convertible to the most
derived traversal tag type to which X is also
convertible, and not to any more-derived traversal tag
type.

[Note: the intention is to allow iterator_category to be one of
the five original category tags when convertibility to one of the
traversal tags would add no information]

The enable_if_interoperable template used above is for exposition
purposes. The member operators should only be in an overload set
provided the derived types Dr1 and Dr2 are interoperable,
meaning that at least one of the types is convertible to the other. The
enable_if_interoperable approach uses SFINAE to take the operators
out of the overload set when the types are not interoperable.
The operators should behave as-ifenable_if_interoperable
were defined to be:

The following table describes the typical valid expressions on
iterator_facade's Derived parameter, depending on the
iterator concept(s) it will model. The operations in the first
column must be made accessible to member functions of class
iterator_core_access. In addition,
static_cast<Derived*>(iterator_facade*) shall be well-formed.

In the table below, F is iterator_facade<X,V,C,R,D>, a is an
object of type X, b and c are objects of type constX,
n is an object of F::difference_type, y is a constant
object of a single pass iterator type interoperable with X, and z
is a constant object of a random access traversal iterator type
interoperable with X.

The operations in this section are described in terms of operations on
the core interface of Derived which may be inaccessible
(i.e. private). The implementation should access these operations
through member functions of class iterator_core_access.

Otherwise returns an object of unspecified type such that,
(*static_cast<Derivedconst*>(this))->m is equivalent to (w=**static_cast<Derivedconst*>(this),w.m) for some temporary object w of type value_type.

unspecifiedoperator[](difference_typen)const;

Returns:

an object convertible to value_type. For constant
objects v of type value_type, and n of type
difference_type, (*this)[n]=v is equivalent to
*(*this+n)=v, and static_cast<value_typeconst&>((*this)[n]) is equivalent to
static_cast<value_typeconst&>(*(*this+n))

In this section we'll walk through the implementation of a few
iterators using iterator_facade, based around the simple
example of a linked list of polymorphic objects. This example was
inspired by a posting by Keith Macdonald on the Boost-Users
mailing list.

Now we have to determine which iterator traversal concept our
node_iterator is going to model. Singly-linked lists only have
forward links, so our iterator can't can't be a bidirectional
traversal iterator. Our iterator should be able to make multiple
passes over the same linked list (unlike, say, an
istream_iterator which consumes the stream it traverses), so it
must be a forward traversal iterator. Therefore, we'll pass
boost::forward_traversal_tag in this position1.

iterator_facade also supports old-style category
tags, so we could have passed std::forward_iterator_tag here;
either way, the resulting iterator's iterator_category will
end up being std::forward_iterator_tag.

The Reference argument becomes the type returned by
node_iterator's dereference operation, and will also be the
same as std::iterator_traits<node_iterator>::reference. The
library's default for this parameter is Value&; since
node_base& is a good choice for the iterator's reference
type, we can omit this argument, or pass use_default.

The Difference argument determines how the distance between
two node_iterators will be measured and will also be the
same as std::iterator_traits<node_iterator>::difference_type.
The library's default for Difference is std::ptrdiff_t, an
appropriate type for measuring the distance between any two
addresses in memory, and one that works for almost any iterator,
so we can omit this argument, too.

Next we need to decide how to represent the iterator's position.
This representation will take the form of data members, so we'll
also need to write constructors to initialize them. The
node_iterator's position is quite naturally represented using
a pointer to a node_base. We'll need a constructor to build an
iterator from a node_base*, and a default constructor to
satisfy the forward traversal iterator requirements2.
Our node_iterator then becomes:

Technically, the C++ standard places almost no
requirements on a default-constructed iterator, so if we were
really concerned with efficiency, we could've written the
default constructor to leave m_node uninitialized.

We therefore need to supply dereference,
equal, and increment members. We don't want these members
to become part of node_iterator's public interface, so we can
make them private and grant friendship to
boost::iterator_core_access, a "back-door" that
iterator_facade uses to get access to the core operations:

The term mutable iterator means an iterator through which
the object it references (its "referent") can be modified. A
constant iterator is one which doesn't allow modification of
its referent.

The words constant and mutable don't refer to the ability to
modify the iterator itself. For example, an intconst* is a
non-constconstant iterator, which can be incremented
but doesn't allow modification of its referent, and int*const is a constmutable iterator, which cannot be
modified but which allows modification of its referent.

Confusing? We agree, but those are the standard terms. It
probably doesn't help much that a container's constant iterator
is called const_iterator.

Now, our node_iterator gives clients access to both node's print(std::ostream&)const member function, but also its
mutating double_me() member. If we wanted to build a
constantnode_iterator, we'd only have to make three
changes:

The C++ standard requires an iterator's value_typenot be
const-qualified, so iterator_facade strips the
const from its Value parameter in order to produce the
iterator's value_type. Making the Value argument
const provides a useful hint to iterator_facade that the
iterator is a constant iterator, and the default Reference
argument will be correct for all lvalue iterators.

As a matter of fact, node_iterator and const_node_iterator
are so similar that it makes sense to factor the common code out
into a template as follows:

Our const_node_iterator works perfectly well on its own, but
taken together with node_iterator it doesn't quite meet
expectations. For example, we'd like to be able to pass a
node_iterator where a node_const_iterator was expected,
just as you can with std::list<int>'s iterator and
const_iterator. Furthermore, given a node_iterator and a
node_const_iterator into the same list, we should be able to
compare them for equality.

This expected ability to use two different iterator types together
is known as interoperability. Achieving interoperability in
our case is as simple as templatizing the equal function and
adding a templatized converting constructor34:

Now node_iterator and node_const_iterator behave exactly as
you'd expect... almost. We can compare them and we can convert in
one direction: from node_iterator to node_const_iterator.
If we try to convert from node_const_iterator to
node_iterator, we'll get an error when the converting
constructor tries to initialize node_iterator's m_node, a
node* with a nodeconst*. So what's the problem?

The problem is that
boost::is_convertible<node_const_iterator,node_iterator>::value
will be true, but it should be false. is_convertible
lies because it can only see as far as the declaration of
node_iter's converting constructor, but can't look inside at
the definition to make sure it will compile. A perfect solution
would make node_iter's converting constructor disappear when
the m_node conversion would fail.

In fact, that sort of magic is possible using
boost::enable_if. By rewriting the converting constructor as
follows, we can remove it from the overload set when it's not
appropriate:

This concludes our iterator_facade tutorial, but before you
stop reading we urge you to take a look at iterator_adaptor.
There's another way to approach writing these iterators which might
even be superior.