.. parsed-literal:: template < class Derived , class Value , class AccessCategory , class TraversalCategory , class Reference = /* see below__ \*/ , class Difference = ptrdiff_t > class iterator_facade { public: typedef remove_cv::type value_type; typedef Reference reference; typedef /* see `description of operator->`__ \*/ pointer; typedef Difference difference_type; typedef iterator_tag iterator_category; reference operator\*() const; /* see below__ \*/ operator->() const; /* see below__ \*/ operator[](difference_type n) const; Derived& operator++(); Derived operator++(int); Derived& operator--(); Derived operator--(int); Derived& operator+=(difference_type n); Derived& operator-=(difference_type n); Derived operator-(difference_type n) const; }; // Comparison operators template typename enable_if_interoperable::type // exposition operator ==(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator !=(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator <(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator <=(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator >(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator >=(iterator_facade const& lhs, iterator_facade const& rhs); template typename enable_if_interoperable::type operator >=(iterator_facade const& lhs, iterator_facade const& rhs); // Iterator difference template typename enable_if_interoperable::type operator -(iterator_facade const& lhs, iterator_facade const& rhs); // Iterator addition template Derived operator+ (iterator_facade const&, typename Derived::difference_type n) __ `iterator facade requirements`_ __ `operator arrow`_ __ `operator arrow`_ __ brackets_ [*Note:* The ``enable_if_interoperable`` template used above is for exposition purposes. The member operators should be only be in an overload set provided the derived types ``Dr1`` and ``Dr2`` are interoperable, by which we mean they are convertible to each other. The ``enable_if_interoperable`` approach uses SFINAE to take the operators out of the overload set when the types are not interoperable.] .. we need a new label here because the presence of markup in the title prevents an automatic link from being generated .. _iterator facade requirements: ``iterator_facade`` requirements ................................ The ``Derived`` template parameter must be a class derived from ``iterator_facade``. The default for the ``Reference`` parameter is ``Value&`` if the access category for ``iterator_facade`` is implicitly convertible to ``writable_iterator_tag``, and ``const Value&`` otherwise. The following table describes the other requirements on the ``Derived`` parameter. Depending on the resulting iterator's ``iterator_category``, a subset of the expressions listed in the table are required to be valid. The operations in the first column must be accessible to member functions of class ``iterator_core_access``. In the table below, ``X`` is the derived iterator type, ``a`` is an object of type ``X``, ``b`` and ``c`` are objects of type ``const X``, ``n`` is an object of ``X::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``. +--------------------+-------------------+-------------------------------------+---------------------------+ |Expression |Return Type |Assertion/Note |Required to implement | | | | |Iterator Concept(s) | +====================+===================+=====================================+===========================+ |``c.dereference()`` |``X::reference`` | |Readable Iterator, Writable| | | | |Iterator | +--------------------+-------------------+-------------------------------------+---------------------------+ |``c.equal(b)`` |convertible to bool|true iff ``b`` and ``c`` are |Single Pass Iterator | | | |equivalent. | | +--------------------+-------------------+-------------------------------------+---------------------------+ |``c.equal(y)`` |convertible to bool|true iff ``c`` and ``y`` refer to the|Single Pass Iterator | | | |same position. Implements ``c == y``| | | | |and ``c != y``. | | +--------------------+-------------------+-------------------------------------+---------------------------+ |``a.advance(n)`` |unused | |Random Access Traversal | | | | |Iterator | +--------------------+-------------------+-------------------------------------+---------------------------+ |``a.increment()`` |unused | |Incrementable Iterator | +--------------------+-------------------+-------------------------------------+---------------------------+ |``a.decrement()`` |unused | |Bidirectional Traversal | | | | |Iterator | +--------------------+-------------------+-------------------------------------+---------------------------+ |``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal | | |X::difference_type | |Iterator | +--------------------+-------------------+-------------------------------------+---------------------------+ |``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal | | |X::difference_type |Implements ``c - z``, ``c < z``, ``c |Iterator | | | |<= z``, ``c > z``, and ``c >= c``. | | +--------------------+-------------------+-------------------------------------+---------------------------+ .. We should explain more about how the functions in the interface of iterator_facade are there conditionally. -JGS ``iterator_facade`` operations .............................. 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``. ``reference operator*() const;`` :Returns: ``static_cast(this)->dereference()`` ``operator->() const;`` (see below__) __ `operator arrow`_ :Returns: If ``X::reference`` is a reference type, returns an object of type ``X::pointer`` equal to:: &static_cast(this)->dereference() Otherwise returns an object of unspecified type such that, given an object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a, w.m)`` for some temporary object ``w`` of type ``X::value_type``. The type ``X::pointer`` is ``Value*`` if the access category for ``X`` is implicitly convertible to ``writable_iterator_tag``, and ``Value const*`` otherwise. .. _brackets: *unspecified* ``operator[](difference_type n) const;`` :Returns: an object convertible to ``X::reference`` and holding a copy *p* of ``a+n`` such that, for a constant object ``v`` of type ``X::value_type``, ``X::reference(a[n] = v)`` is equivalent to ``p = v``. ``Derived& operator++();`` :Effects: :: static_cast(this)->increment(); return *this; .. I realize that the committee is moving away from specifying things like this in terms of code, but I worried about the imprecision of saying that a core interface function is invoked without describing the downcast. An alternative to what I did would be to mention it above where we talk about accessibility. ``Derived operator++(int);`` :Effects: :: Derived tmp(static_cast(this)); ++*this; return tmp; ``Derived& operator--();`` :Effects: :: static_cast(this)->decrement(); return *this; ``Derived operator--(int);`` :Effects: :: Derived tmp(static_cast(this)); --*this; return tmp; ``Derived& operator+=(difference_type n);`` :Effects: :: static_cast(this)->advance(n); return *this; ``Derived& operator-=(difference_type n);`` :Effects: :: static_cast(this)->advance(-n); return *this; ``Derived operator-(difference_type n) const;`` :Effects: Derived tmp(static_cast(this)); return tmp -= n; :Returns: ``static_cast(this)->advance(-n);``