123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- .. Distributed under the Boost
- .. Software License, Version 1.0. (See accompanying
- .. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- .. Version 1.3 of this ReStructuredText document corresponds to
- n1530_, the paper accepted by the LWG for TR1.
- .. Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
- .. parsed-literal::
- template <
- class Derived
- , class Value
- , class CategoryOrTraversal
- , class Reference = Value&
- , class Difference = ptrdiff_t
- >
- class iterator_facade {
- public:
- typedef remove_const<Value>::type value_type;
- typedef Reference reference;
- typedef Value\* pointer;
- typedef Difference difference_type;
- typedef /* see below__ \*/ 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;
- protected:
- typedef iterator_facade iterator_facade\_;
- };
- // Comparison operators
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
- operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- // Iterator difference
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- /* see below__ \*/
- operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- // Iterator addition
- template <class Dr, class V, class TC, class R, class D>
- Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
- typename Derived::difference_type n);
- template <class Dr, class V, class TC, class R, class D>
- Derived operator+ (typename Derived::difference_type n,
- iterator_facade<Dr,V,TC,R,D> const&);
- __ `iterator category`_
- __ `operator arrow`_
- __ brackets_
- __ minus_
- .. _`iterator category`:
- The ``iterator_category`` member of ``iterator_facade`` is
- .. parsed-literal::
- *iterator-category*\ (CategoryOrTraversal, reference, value_type)
- where *iterator-category* is defined as follows:
- .. include:: facade_iterator_category.rst
- 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-if* ``enable_if_interoperable``
- were defined to be::
- template <bool, typename> enable_if_interoperable_impl
- {};
- template <typename T> enable_if_interoperable_impl<true,T>
- { typedef T type; };
- template<typename Dr1, typename Dr2, typename T>
- struct enable_if_interoperable
- : enable_if_interoperable_impl<
- is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
- , T
- >
- {};
- ``iterator_facade`` Requirements
- --------------------------------
- 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 ``const X``,
- ``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``.
- .. _`core operations`:
- .. topic:: ``iterator_facade`` Core Operations
- +--------------------+----------------------+-------------------------+---------------------------+
- |Expression |Return Type |Assertion/Note |Used to implement Iterator |
- | | | |Concept(s) |
- +====================+======================+=========================+===========================+
- |``c.dereference()`` |``F::reference`` | |Readable Iterator, Writable|
- | | | |Iterator |
- +--------------------+----------------------+-------------------------+---------------------------+
- |``c.equal(y)`` |convertible to bool |true iff ``c`` and ``y`` |Single Pass Iterator |
- | | |refer to the same | |
- | | |position. | |
- +--------------------+----------------------+-------------------------+---------------------------+
- |``a.increment()`` |unused | |Incrementable Iterator |
- +--------------------+----------------------+-------------------------+---------------------------+
- |``a.decrement()`` |unused | |Bidirectional Traversal |
- | | | |Iterator |
- +--------------------+----------------------+-------------------------+---------------------------+
- |``a.advance(n)`` |unused | |Random Access Traversal |
- | | | |Iterator |
- +--------------------+----------------------+-------------------------+---------------------------+
- |``c.distance_to(z)``|convertible to |equivalent to |Random Access Traversal |
- | |``F::difference_type``|``distance(c, X(z))``. |Iterator |
- +--------------------+----------------------+-------------------------+---------------------------+
- ``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<Derived const*>(this)->dereference()``
- ``operator->() const;`` (see below__)
- __ `operator arrow`_
- :Returns: If ``reference`` is a reference type, an object
- of type ``pointer`` equal to::
- &static_cast<Derived const*>(this)->dereference()
- Otherwise returns an object of unspecified type such that,
- ``(*static_cast<Derived const*>(this))->m`` is equivalent to ``(w = **static_cast<Derived const*>(this),
- w.m)`` for some temporary object ``w`` of type ``value_type``.
- .. _brackets:
- *unspecified* ``operator[](difference_type n) 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_type
- const&>((*this)[n])`` is equivalent to
- ``static_cast<value_type const&>(*(*this + n))``
- ``Derived& operator++();``
- :Effects:
- ::
- static_cast<Derived*>(this)->increment();
- return *static_cast<Derived*>(this);
- ``Derived operator++(int);``
- :Effects:
- ::
- Derived tmp(static_cast<Derived const*>(this));
- ++*this;
- return tmp;
- ``Derived& operator--();``
- :Effects:
- ::
- static_cast<Derived*>(this)->decrement();
- return *static_cast<Derived*>(this);
- ``Derived operator--(int);``
- :Effects:
- ::
- Derived tmp(static_cast<Derived const*>(this));
- --*this;
- return tmp;
- ``Derived& operator+=(difference_type n);``
- :Effects:
- ::
- static_cast<Derived*>(this)->advance(n);
- return *static_cast<Derived*>(this);
- ``Derived& operator-=(difference_type n);``
- :Effects:
-
- ::
- static_cast<Derived*>(this)->advance(-n);
- return *static_cast<Derived*>(this);
- ``Derived operator-(difference_type n) const;``
- :Effects:
- ::
- Derived tmp(static_cast<Derived const*>(this));
- return tmp -= n;
- ::
- template <class Dr, class V, class TC, class R, class D>
- Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
- typename Derived::difference_type n);
- template <class Dr, class V, class TC, class R, class D>
- Derived operator+ (typename Derived::difference_type n,
- iterator_facade<Dr,V,TC,R,D> const&);
- :Effects:
- ::
- Derived tmp(static_cast<Derived const*>(this));
- return tmp += n;
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
- Otherwise,
- ``((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``!((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
- Otherwise,
- ``!((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0``.
- Otherwise,
- ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0``.
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0``.
- Otherwise,
- ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0``.
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0``.
- Otherwise,
- ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0``.
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,bool>::type
- operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0``.
- Otherwise,
- ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0``.
- .. _minus:
- ::
- template <class Dr1, class V1, class TC1, class R1, class D1,
- class Dr2, class V2, class TC2, class R2, class D2>
- typename enable_if_interoperable<Dr1,Dr2,difference>::type
- operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
- iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
- :Return Type:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``difference`` shall be
- ``iterator_traits<Dr1>::difference_type``.
- Otherwise
- ``difference`` shall be ``iterator_traits<Dr2>::difference_type``
- :Returns:
- if ``is_convertible<Dr2,Dr1>::value``
- then
- ``-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)``.
- Otherwise,
- ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)``.
|