iterator_facade_ref.rst 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. .. Distributed under the Boost
  2. .. Software License, Version 1.0. (See accompanying
  3. .. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. .. Version 1.3 of this ReStructuredText document corresponds to
  5. n1530_, the paper accepted by the LWG for TR1.
  6. .. Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
  7. .. parsed-literal::
  8. template <
  9. class Derived
  10. , class Value
  11. , class CategoryOrTraversal
  12. , class Reference = Value&
  13. , class Difference = ptrdiff_t
  14. >
  15. class iterator_facade {
  16. public:
  17. typedef remove_const<Value>::type value_type;
  18. typedef Reference reference;
  19. typedef Value\* pointer;
  20. typedef Difference difference_type;
  21. typedef /* see below__ \*/ iterator_category;
  22. reference operator\*() const;
  23. /* see below__ \*/ operator->() const;
  24. /* see below__ \*/ operator[](difference_type n) const;
  25. Derived& operator++();
  26. Derived operator++(int);
  27. Derived& operator--();
  28. Derived operator--(int);
  29. Derived& operator+=(difference_type n);
  30. Derived& operator-=(difference_type n);
  31. Derived operator-(difference_type n) const;
  32. protected:
  33. typedef iterator_facade iterator_facade\_;
  34. };
  35. // Comparison operators
  36. template <class Dr1, class V1, class TC1, class R1, class D1,
  37. class Dr2, class V2, class TC2, class R2, class D2>
  38. typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
  39. operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  40. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  41. template <class Dr1, class V1, class TC1, class R1, class D1,
  42. class Dr2, class V2, class TC2, class R2, class D2>
  43. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  44. operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  45. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  46. template <class Dr1, class V1, class TC1, class R1, class D1,
  47. class Dr2, class V2, class TC2, class R2, class D2>
  48. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  49. operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  50. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  51. template <class Dr1, class V1, class TC1, class R1, class D1,
  52. class Dr2, class V2, class TC2, class R2, class D2>
  53. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  54. operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  55. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  56. template <class Dr1, class V1, class TC1, class R1, class D1,
  57. class Dr2, class V2, class TC2, class R2, class D2>
  58. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  59. operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  60. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  61. template <class Dr1, class V1, class TC1, class R1, class D1,
  62. class Dr2, class V2, class TC2, class R2, class D2>
  63. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  64. operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  65. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  66. // Iterator difference
  67. template <class Dr1, class V1, class TC1, class R1, class D1,
  68. class Dr2, class V2, class TC2, class R2, class D2>
  69. /* see below__ \*/
  70. operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  71. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  72. // Iterator addition
  73. template <class Dr, class V, class TC, class R, class D>
  74. Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
  75. typename Derived::difference_type n);
  76. template <class Dr, class V, class TC, class R, class D>
  77. Derived operator+ (typename Derived::difference_type n,
  78. iterator_facade<Dr,V,TC,R,D> const&);
  79. __ `iterator category`_
  80. __ `operator arrow`_
  81. __ brackets_
  82. __ minus_
  83. .. _`iterator category`:
  84. The ``iterator_category`` member of ``iterator_facade`` is
  85. .. parsed-literal::
  86. *iterator-category*\ (CategoryOrTraversal, reference, value_type)
  87. where *iterator-category* is defined as follows:
  88. .. include:: facade_iterator_category.rst
  89. The ``enable_if_interoperable`` template used above is for exposition
  90. purposes. The member operators should only be in an overload set
  91. provided the derived types ``Dr1`` and ``Dr2`` are interoperable,
  92. meaning that at least one of the types is convertible to the other. The
  93. ``enable_if_interoperable`` approach uses SFINAE to take the operators
  94. out of the overload set when the types are not interoperable.
  95. The operators should behave *as-if* ``enable_if_interoperable``
  96. were defined to be::
  97. template <bool, typename> enable_if_interoperable_impl
  98. {};
  99. template <typename T> enable_if_interoperable_impl<true,T>
  100. { typedef T type; };
  101. template<typename Dr1, typename Dr2, typename T>
  102. struct enable_if_interoperable
  103. : enable_if_interoperable_impl<
  104. is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
  105. , T
  106. >
  107. {};
  108. ``iterator_facade`` Requirements
  109. --------------------------------
  110. The following table describes the typical valid expressions on
  111. ``iterator_facade``\ 's ``Derived`` parameter, depending on the
  112. iterator concept(s) it will model. The operations in the first
  113. column must be made accessible to member functions of class
  114. ``iterator_core_access``. In addition,
  115. ``static_cast<Derived*>(iterator_facade*)`` shall be well-formed.
  116. In the table below, ``F`` is ``iterator_facade<X,V,C,R,D>``, ``a`` is an
  117. object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
  118. ``n`` is an object of ``F::difference_type``, ``y`` is a constant
  119. object of a single pass iterator type interoperable with ``X``, and ``z``
  120. is a constant object of a random access traversal iterator type
  121. interoperable with ``X``.
  122. .. _`core operations`:
  123. .. topic:: ``iterator_facade`` Core Operations
  124. +--------------------+----------------------+-------------------------+---------------------------+
  125. |Expression |Return Type |Assertion/Note |Used to implement Iterator |
  126. | | | |Concept(s) |
  127. +====================+======================+=========================+===========================+
  128. |``c.dereference()`` |``F::reference`` | |Readable Iterator, Writable|
  129. | | | |Iterator |
  130. +--------------------+----------------------+-------------------------+---------------------------+
  131. |``c.equal(y)`` |convertible to bool |true iff ``c`` and ``y`` |Single Pass Iterator |
  132. | | |refer to the same | |
  133. | | |position. | |
  134. +--------------------+----------------------+-------------------------+---------------------------+
  135. |``a.increment()`` |unused | |Incrementable Iterator |
  136. +--------------------+----------------------+-------------------------+---------------------------+
  137. |``a.decrement()`` |unused | |Bidirectional Traversal |
  138. | | | |Iterator |
  139. +--------------------+----------------------+-------------------------+---------------------------+
  140. |``a.advance(n)`` |unused | |Random Access Traversal |
  141. | | | |Iterator |
  142. +--------------------+----------------------+-------------------------+---------------------------+
  143. |``c.distance_to(z)``|convertible to |equivalent to |Random Access Traversal |
  144. | |``F::difference_type``|``distance(c, X(z))``. |Iterator |
  145. +--------------------+----------------------+-------------------------+---------------------------+
  146. ``iterator_facade`` operations
  147. ------------------------------
  148. The operations in this section are described in terms of operations on
  149. the core interface of ``Derived`` which may be inaccessible
  150. (i.e. private). The implementation should access these operations
  151. through member functions of class ``iterator_core_access``.
  152. ``reference operator*() const;``
  153. :Returns: ``static_cast<Derived const*>(this)->dereference()``
  154. ``operator->() const;`` (see below__)
  155. __ `operator arrow`_
  156. :Returns: If ``reference`` is a reference type, an object
  157. of type ``pointer`` equal to::
  158. &static_cast<Derived const*>(this)->dereference()
  159. Otherwise returns an object of unspecified type such that,
  160. ``(*static_cast<Derived const*>(this))->m`` is equivalent to ``(w = **static_cast<Derived const*>(this),
  161. w.m)`` for some temporary object ``w`` of type ``value_type``.
  162. .. _brackets:
  163. *unspecified* ``operator[](difference_type n) const;``
  164. :Returns: an object convertible to ``value_type``. For constant
  165. objects ``v`` of type ``value_type``, and ``n`` of type
  166. ``difference_type``, ``(*this)[n] = v`` is equivalent to
  167. ``*(*this + n) = v``, and ``static_cast<value_type
  168. const&>((*this)[n])`` is equivalent to
  169. ``static_cast<value_type const&>(*(*this + n))``
  170. ``Derived& operator++();``
  171. :Effects:
  172. ::
  173. static_cast<Derived*>(this)->increment();
  174. return *static_cast<Derived*>(this);
  175. ``Derived operator++(int);``
  176. :Effects:
  177. ::
  178. Derived tmp(static_cast<Derived const*>(this));
  179. ++*this;
  180. return tmp;
  181. ``Derived& operator--();``
  182. :Effects:
  183. ::
  184. static_cast<Derived*>(this)->decrement();
  185. return *static_cast<Derived*>(this);
  186. ``Derived operator--(int);``
  187. :Effects:
  188. ::
  189. Derived tmp(static_cast<Derived const*>(this));
  190. --*this;
  191. return tmp;
  192. ``Derived& operator+=(difference_type n);``
  193. :Effects:
  194. ::
  195. static_cast<Derived*>(this)->advance(n);
  196. return *static_cast<Derived*>(this);
  197. ``Derived& operator-=(difference_type n);``
  198. :Effects:
  199. ::
  200. static_cast<Derived*>(this)->advance(-n);
  201. return *static_cast<Derived*>(this);
  202. ``Derived operator-(difference_type n) const;``
  203. :Effects:
  204. ::
  205. Derived tmp(static_cast<Derived const*>(this));
  206. return tmp -= n;
  207. ::
  208. template <class Dr, class V, class TC, class R, class D>
  209. Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
  210. typename Derived::difference_type n);
  211. template <class Dr, class V, class TC, class R, class D>
  212. Derived operator+ (typename Derived::difference_type n,
  213. iterator_facade<Dr,V,TC,R,D> const&);
  214. :Effects:
  215. ::
  216. Derived tmp(static_cast<Derived const*>(this));
  217. return tmp += n;
  218. ::
  219. template <class Dr1, class V1, class TC1, class R1, class D1,
  220. class Dr2, class V2, class TC2, class R2, class D2>
  221. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  222. operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  223. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  224. :Returns:
  225. if ``is_convertible<Dr2,Dr1>::value``
  226. then
  227. ``((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
  228. Otherwise,
  229. ``((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
  230. ::
  231. template <class Dr1, class V1, class TC1, class R1, class D1,
  232. class Dr2, class V2, class TC2, class R2, class D2>
  233. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  234. operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  235. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  236. :Returns:
  237. if ``is_convertible<Dr2,Dr1>::value``
  238. then
  239. ``!((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
  240. Otherwise,
  241. ``!((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
  242. ::
  243. template <class Dr1, class V1, class TC1, class R1, class D1,
  244. class Dr2, class V2, class TC2, class R2, class D2>
  245. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  246. operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  247. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  248. :Returns:
  249. if ``is_convertible<Dr2,Dr1>::value``
  250. then
  251. ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0``.
  252. Otherwise,
  253. ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0``.
  254. ::
  255. template <class Dr1, class V1, class TC1, class R1, class D1,
  256. class Dr2, class V2, class TC2, class R2, class D2>
  257. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  258. operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  259. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  260. :Returns:
  261. if ``is_convertible<Dr2,Dr1>::value``
  262. then
  263. ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0``.
  264. Otherwise,
  265. ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0``.
  266. ::
  267. template <class Dr1, class V1, class TC1, class R1, class D1,
  268. class Dr2, class V2, class TC2, class R2, class D2>
  269. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  270. operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  271. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  272. :Returns:
  273. if ``is_convertible<Dr2,Dr1>::value``
  274. then
  275. ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0``.
  276. Otherwise,
  277. ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0``.
  278. ::
  279. template <class Dr1, class V1, class TC1, class R1, class D1,
  280. class Dr2, class V2, class TC2, class R2, class D2>
  281. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  282. operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  283. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  284. :Returns:
  285. if ``is_convertible<Dr2,Dr1>::value``
  286. then
  287. ``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0``.
  288. Otherwise,
  289. ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0``.
  290. .. _minus:
  291. ::
  292. template <class Dr1, class V1, class TC1, class R1, class D1,
  293. class Dr2, class V2, class TC2, class R2, class D2>
  294. typename enable_if_interoperable<Dr1,Dr2,difference>::type
  295. operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  296. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  297. :Return Type:
  298. if ``is_convertible<Dr2,Dr1>::value``
  299. then
  300. ``difference`` shall be
  301. ``iterator_traits<Dr1>::difference_type``.
  302. Otherwise
  303. ``difference`` shall be ``iterator_traits<Dr2>::difference_type``
  304. :Returns:
  305. if ``is_convertible<Dr2,Dr1>::value``
  306. then
  307. ``-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)``.
  308. Otherwise,
  309. ``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)``.