facade.qbk 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. [section:facade Iterator Facade]
  2. While the iterator interface is rich, there is a core subset of the
  3. interface that is necessary for all the functionality. We have
  4. identified the following core behaviors for iterators:
  5. * dereferencing
  6. * incrementing
  7. * decrementing
  8. * equality comparison
  9. * random-access motion
  10. * distance measurement
  11. In addition to the behaviors listed above, the core interface elements
  12. include the associated types exposed through iterator traits:
  13. `value_type`, `reference`, `difference_type`, and
  14. `iterator_category`.
  15. Iterator facade uses the Curiously Recurring Template
  16. Pattern (CRTP) [Cop95]_ so that the user can specify the behavior
  17. of `iterator_facade` in a derived class. Former designs used
  18. policy objects to specify the behavior, but that approach was
  19. discarded for several reasons:
  20. 1. the creation and eventual copying of the policy object may create
  21. overhead that can be avoided with the current approach.
  22. 2. The policy object approach does not allow for custom constructors
  23. on the created iterator types, an essential feature if
  24. `iterator_facade` should be used in other library
  25. implementations.
  26. 3. Without the use of CRTP, the standard requirement that an
  27. iterator's `operator++` returns the iterator type itself
  28. would mean that all iterators built with the library would
  29. have to be specializations of `iterator_facade<...>`, rather
  30. than something more descriptive like
  31. `indirect_iterator<T*>`. Cumbersome type generator
  32. metafunctions would be needed to build new parameterized
  33. iterators, and a separate `iterator_adaptor` layer would be
  34. impossible.
  35. [h2 Usage]
  36. The user of `iterator_facade` derives his iterator class from a
  37. specialization of `iterator_facade` and passes the derived
  38. iterator class as `iterator_facade`\ 's first template parameter.
  39. The order of the other template parameters have been carefully
  40. chosen to take advantage of useful defaults. For example, when
  41. defining a constant lvalue iterator, the user can pass a
  42. const-qualified version of the iterator's `value_type` as
  43. `iterator_facade`\ 's `Value` parameter and omit the
  44. `Reference` parameter which follows.
  45. The derived iterator class must define member functions implementing
  46. the iterator's core behaviors. The following table describes
  47. expressions which are required to be valid depending on the category
  48. of the derived iterator type. These member functions are described
  49. briefly below and in more detail in the iterator facade
  50. requirements.
  51. [table Core Interface
  52. [
  53. [Expression]
  54. [Effects]
  55. ]
  56. [
  57. [`i.dereference()`]
  58. [Access the value referred to]
  59. ]
  60. [
  61. [`i.equal(j)`]
  62. [Compare for equality with `j`]
  63. ]
  64. [
  65. [`i.increment()`]
  66. [Advance by one position]
  67. ]
  68. [
  69. [`i.decrement()`]
  70. [Retreat by one position]
  71. ]
  72. [
  73. [`i.advance(n)`]
  74. [Advance by `n` positions]
  75. ]
  76. [
  77. [`i.distance_to(j)`]
  78. [Measure the distance to `j`]
  79. ]
  80. ]
  81. [/ .. Should we add a comment that a zero overhead implementation of iterator_facade is possible with proper inlining?]
  82. In addition to implementing the core interface functions, an iterator
  83. derived from `iterator_facade` typically defines several
  84. constructors. To model any of the standard iterator concepts, the
  85. iterator must at least have a copy constructor. Also, if the iterator
  86. type `X` is meant to be automatically interoperate with another
  87. iterator type `Y` (as with constant and mutable iterators) then
  88. there must be an implicit conversion from `X` to `Y` or from `Y`
  89. to `X` (but not both), typically implemented as a conversion
  90. constructor. Finally, if the iterator is to model Forward Traversal
  91. Iterator or a more-refined iterator concept, a default constructor is
  92. required.
  93. [h2 Iterator Core Access]
  94. `iterator_facade` and the operator implementations need to be able
  95. to access the core member functions in the derived class. Making the
  96. core member functions public would expose an implementation detail to
  97. the user. The design used here ensures that implementation details do
  98. not appear in the public interface of the derived iterator type.
  99. Preventing direct access to the core member functions has two
  100. advantages. First, there is no possibility for the user to accidently
  101. use a member function of the iterator when a member of the value_type
  102. was intended. This has been an issue with smart pointer
  103. implementations in the past. The second and main advantage is that
  104. library implementers can freely exchange a hand-rolled iterator
  105. implementation for one based on `iterator_facade` without fear of
  106. breaking code that was accessing the public core member functions
  107. directly.
  108. In a naive implementation, keeping the derived class' core member
  109. functions private would require it to grant friendship to
  110. `iterator_facade` and each of the seven operators. In order to
  111. reduce the burden of limiting access, `iterator_core_access` is
  112. provided, a class that acts as a gateway to the core member functions
  113. in the derived iterator class. The author of the derived class only
  114. needs to grant friendship to `iterator_core_access` to make his core
  115. member functions available to the library.
  116. `iterator_core_access` will be typically implemented as an empty
  117. class containing only private static member functions which invoke the
  118. iterator core member functions. There is, however, no need to
  119. standardize the gateway protocol. Note that even if
  120. `iterator_core_access` used public member functions it would not
  121. open a safety loophole, as every core member function preserves the
  122. invariants of the iterator.
  123. [h2 `operator[]`]
  124. The indexing operator for a generalized iterator presents special
  125. challenges. A random access iterator's `operator[]` is only
  126. required to return something convertible to its `value_type`.
  127. Requiring that it return an lvalue would rule out currently-legal
  128. random-access iterators which hold the referenced value in a data
  129. member (e.g. |counting|_), because `*(p+n)` is a reference
  130. into the temporary iterator `p+n`, which is destroyed when
  131. `operator[]` returns.
  132. .. |counting| replace:: `counting_iterator`
  133. Writable iterators built with `iterator_facade` implement the
  134. semantics required by the preferred resolution to `issue 299`_ and
  135. adopted by proposal n1550_: the result of `p[n]` is an object
  136. convertible to the iterator's `value_type`, and `p[n] = x` is
  137. equivalent to `*(p + n) = x` (Note: This result object may be
  138. implemented as a proxy containing a copy of `p+n`). This approach
  139. will work properly for any random-access iterator regardless of the
  140. other details of its implementation. A user who knows more about
  141. the implementation of her iterator is free to implement an
  142. `operator[]` that returns an lvalue in the derived iterator
  143. class; it will hide the one supplied by `iterator_facade` from
  144. clients of her iterator.
  145. .. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
  146. .. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
  147. .. _`operator arrow`:
  148. [h2 `operator->`]
  149. The `reference` type of a readable iterator (and today's input
  150. iterator) need not in fact be a reference, so long as it is
  151. convertible to the iterator's `value_type`. When the `value_type`
  152. is a class, however, it must still be possible to access members
  153. through `operator->`. Therefore, an iterator whose `reference`
  154. type is not in fact a reference must return a proxy containing a copy
  155. of the referenced value from its `operator->`.
  156. The return types for `iterator_facade`\ 's `operator->` and
  157. `operator[]` are not explicitly specified. Instead, those types
  158. are described in terms of a set of requirements, which must be
  159. satisfied by the `iterator_facade` implementation.
  160. .. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
  161. Patterns, C++ Report, February 1995, pp. 24-27.
  162. [section:facade_reference Reference]
  163. template <
  164. class Derived
  165. , class Value
  166. , class CategoryOrTraversal
  167. , class Reference = Value&
  168. , class Difference = ptrdiff_t
  169. >
  170. class iterator_facade {
  171. public:
  172. typedef remove_const<Value>::type value_type;
  173. typedef Reference reference;
  174. typedef Value\* pointer;
  175. typedef Difference difference_type;
  176. typedef /* see below__ \*/ iterator_category;
  177. reference operator\*() const;
  178. /* see below__ \*/ operator->() const;
  179. /* see below__ \*/ operator[](difference_type n) const;
  180. Derived& operator++();
  181. Derived operator++(int);
  182. Derived& operator--();
  183. Derived operator--(int);
  184. Derived& operator+=(difference_type n);
  185. Derived& operator-=(difference_type n);
  186. Derived operator-(difference_type n) const;
  187. protected:
  188. typedef iterator_facade iterator_facade\_;
  189. };
  190. // Comparison operators
  191. template <class Dr1, class V1, class TC1, class R1, class D1,
  192. class Dr2, class V2, class TC2, class R2, class D2>
  193. typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
  194. operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  195. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  196. template <class Dr1, class V1, class TC1, class R1, class D1,
  197. class Dr2, class V2, class TC2, class R2, class D2>
  198. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  199. operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  200. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  201. template <class Dr1, class V1, class TC1, class R1, class D1,
  202. class Dr2, class V2, class TC2, class R2, class D2>
  203. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  204. operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  205. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  206. template <class Dr1, class V1, class TC1, class R1, class D1,
  207. class Dr2, class V2, class TC2, class R2, class D2>
  208. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  209. operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  210. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  211. template <class Dr1, class V1, class TC1, class R1, class D1,
  212. class Dr2, class V2, class TC2, class R2, class D2>
  213. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  214. operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  215. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  216. template <class Dr1, class V1, class TC1, class R1, class D1,
  217. class Dr2, class V2, class TC2, class R2, class D2>
  218. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  219. operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  220. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  221. // Iterator difference
  222. template <class Dr1, class V1, class TC1, class R1, class D1,
  223. class Dr2, class V2, class TC2, class R2, class D2>
  224. /* see below__ \*/
  225. operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  226. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  227. // Iterator addition
  228. template <class Dr, class V, class TC, class R, class D>
  229. Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
  230. typename Derived::difference_type n);
  231. template <class Dr, class V, class TC, class R, class D>
  232. Derived operator+ (typename Derived::difference_type n,
  233. iterator_facade<Dr,V,TC,R,D> const&);
  234. __ `iterator category`_
  235. __ `operator arrow`_
  236. __ brackets_
  237. __ minus_
  238. .. _`iterator category`:
  239. The `iterator_category` member of `iterator_facade` is
  240. .. parsed-literal::
  241. *iterator-category*\ (CategoryOrTraversal, reference, value_type)
  242. where *iterator-category* is defined as follows:
  243. .. include:: facade_iterator_category.rst
  244. The `enable_if_interoperable` template used above is for exposition
  245. purposes. The member operators should only be in an overload set
  246. provided the derived types `Dr1` and `Dr2` are interoperable,
  247. meaning that at least one of the types is convertible to the other. The
  248. `enable_if_interoperable` approach uses SFINAE to take the operators
  249. out of the overload set when the types are not interoperable.
  250. The operators should behave *as-if* `enable_if_interoperable`
  251. were defined to be:
  252. template <bool, typename> enable_if_interoperable_impl
  253. {};
  254. template <typename T> enable_if_interoperable_impl<true,T>
  255. { typedef T type; };
  256. template<typename Dr1, typename Dr2, typename T>
  257. struct enable_if_interoperable
  258. : enable_if_interoperable_impl<
  259. is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
  260. , T
  261. >
  262. {};
  263. [h2 Requirements]
  264. The following table describes the typical valid expressions on
  265. `iterator_facade`\ 's `Derived` parameter, depending on the
  266. iterator concept(s) it will model. The operations in the first
  267. column must be made accessible to member functions of class
  268. `iterator_core_access`. In addition,
  269. `static_cast<Derived*>(iterator_facade*)` shall be well-formed.
  270. In the table below, `F` is `iterator_facade<X,V,C,R,D>`, `a` is an
  271. object of type `X`, `b` and `c` are objects of type `const X`,
  272. `n` is an object of `F::difference_type`, `y` is a constant
  273. object of a single pass iterator type interoperable with `X`, and `z`
  274. is a constant object of a random access traversal iterator type
  275. interoperable with `X`.
  276. .. _`core operations`:
  277. .. topic:: `iterator_facade` Core Operations
  278. [table Core Operations
  279. [
  280. [Expression]
  281. [Return Type]
  282. [Assertion/Note]
  283. [Used to implement Iterator Concept(s)]
  284. ]
  285. [
  286. [`c.dereference()`]
  287. [`F::reference`]
  288. []
  289. [Readable Iterator, Writable Iterator]
  290. ]
  291. [
  292. [`c.equal(y)`]
  293. [convertible to bool]
  294. [true iff `c` and `y` refer to the same position]
  295. [Single Pass Iterator]
  296. ]
  297. [
  298. [`a.increment()`]
  299. [unused]
  300. []
  301. [Incrementable Iterator]
  302. ]
  303. [
  304. [`a.decrement()`]
  305. [unused]
  306. []
  307. [Bidirectional Traversal Iterator]
  308. ]
  309. [
  310. [`a.advance(n)`]
  311. [unused]
  312. []
  313. [Random Access Traversal Iterator]
  314. ]
  315. [
  316. [`c.distance_to(z)`]
  317. [convertible to `F::difference_type`]
  318. [equivalent to `distance(c, X(z))`.]
  319. [Random Access Traversal Iterator]
  320. ]
  321. ]
  322. [h2 Operations]
  323. The operations in this section are described in terms of operations on
  324. the core interface of `Derived` which may be inaccessible
  325. (i.e. private). The implementation should access these operations
  326. through member functions of class `iterator_core_access`.
  327. reference operator*() const;
  328. [*Returns:] `static_cast<Derived const*>(this)->dereference()`
  329. operator->() const; (see below__)
  330. __ `operator arrow`_
  331. [*Returns:] If `reference` is a reference type, an object of type `pointer` equal to: `&static_cast<Derived const*>(this)->dereference()`
  332. Otherwise returns an object of unspecified type such that,
  333. `(*static_cast<Derived const*>(this))->m` is equivalent to `(w = **static_cast<Derived const*>(this),
  334. w.m)` for some temporary object `w` of type `value_type`.
  335. .. _brackets:
  336. *unspecified* operator[](difference_type n) const;
  337. [*Returns:] an object convertible to `value_type`. For constant
  338. objects `v` of type `value_type`, and `n` of type
  339. `difference_type`, `(*this)[n] = v` is equivalent to
  340. `*(*this + n) = v`, and `static_cast<value_type
  341. const&>((*this)[n])` is equivalent to
  342. `static_cast<value_type const&>(*(*this + n))`
  343. Derived& operator++();
  344. [*Effects:]
  345. static_cast<Derived*>(this)->increment();
  346. return *static_cast<Derived*>(this);
  347. Derived operator++(int);
  348. [*Effects:]
  349. Derived tmp(static_cast<Derived const*>(this));
  350. ++*this;
  351. return tmp;
  352. Derived& operator--();
  353. [*Effects:]
  354. static_cast<Derived*>(this)->decrement();
  355. return *static_cast<Derived*>(this);
  356. Derived operator--(int);
  357. [*Effects:]
  358. Derived tmp(static_cast<Derived const*>(this));
  359. --*this;
  360. return tmp;
  361. Derived& operator+=(difference_type n);
  362. [*Effects:]
  363. static_cast<Derived*>(this)->advance(n);
  364. return *static_cast<Derived*>(this);
  365. Derived& operator-=(difference_type n);
  366. [*Effects:]
  367. static_cast<Derived*>(this)->advance(-n);
  368. return *static_cast<Derived*>(this);
  369. Derived operator-(difference_type n) const;
  370. [*Effects:]
  371. Derived tmp(static_cast<Derived const*>(this));
  372. return tmp -= n;
  373. template <class Dr, class V, class TC, class R, class D>
  374. Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
  375. typename Derived::difference_type n);
  376. template <class Dr, class V, class TC, class R, class D>
  377. Derived operator+ (typename Derived::difference_type n,
  378. iterator_facade<Dr,V,TC,R,D> const&);
  379. [*Effects:]
  380. Derived tmp(static_cast<Derived const*>(this));
  381. return tmp += n;
  382. template <class Dr1, class V1, class TC1, class R1, class D1,
  383. class Dr2, class V2, class TC2, class R2, class D2>
  384. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  385. operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  386. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  387. [*Returns:]
  388. [pre
  389. if `is_convertible<Dr2,Dr1>::value`
  390. then
  391. `((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
  392. Otherwise,
  393. `((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
  394. ]
  395. template <class Dr1, class V1, class TC1, class R1, class D1,
  396. class Dr2, class V2, class TC2, class R2, class D2>
  397. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  398. operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  399. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  400. [*Returns:]
  401. [pre
  402. if `is_convertible<Dr2,Dr1>::value`
  403. then
  404. `!((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
  405. Otherwise,
  406. `!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
  407. ]
  408. template <class Dr1, class V1, class TC1, class R1, class D1,
  409. class Dr2, class V2, class TC2, class R2, class D2>
  410. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  411. operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  412. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  413. [*Returns:]
  414. [pre
  415. if `is_convertible<Dr2,Dr1>::value`
  416. then
  417. `((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0`.
  418. Otherwise,
  419. `((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
  420. ]
  421. template <class Dr1, class V1, class TC1, class R1, class D1,
  422. class Dr2, class V2, class TC2, class R2, class D2>
  423. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  424. operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  425. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  426. [*Returns:]
  427. [pre
  428. if `is_convertible<Dr2,Dr1>::value`
  429. then
  430. `((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0`.
  431. Otherwise,
  432. `((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
  433. ]
  434. template <class Dr1, class V1, class TC1, class R1, class D1,
  435. class Dr2, class V2, class TC2, class R2, class D2>
  436. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  437. operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  438. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  439. [*Returns:]
  440. [pre
  441. if `is_convertible<Dr2,Dr1>::value`
  442. then
  443. `((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0`.
  444. Otherwise,
  445. `((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
  446. ]
  447. template <class Dr1, class V1, class TC1, class R1, class D1,
  448. class Dr2, class V2, class TC2, class R2, class D2>
  449. typename enable_if_interoperable<Dr1,Dr2,bool>::type
  450. operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  451. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  452. [*Returns:]
  453. [pre
  454. if `is_convertible<Dr2,Dr1>::value`
  455. then
  456. `((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0`.
  457. Otherwise,
  458. `((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
  459. ]
  460. .. _minus:
  461. template <class Dr1, class V1, class TC1, class R1, class D1,
  462. class Dr2, class V2, class TC2, class R2, class D2>
  463. typename enable_if_interoperable<Dr1,Dr2,difference>::type
  464. operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
  465. iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
  466. [*Return Type:]
  467. [pre
  468. if `is_convertible<Dr2,Dr1>::value`
  469. then
  470. `difference` shall be
  471. `iterator_traits<Dr1>::difference_type`.
  472. Otherwise
  473. `difference` shall be `iterator_traits<Dr2>::difference_type`
  474. ]
  475. [*Returns:]
  476. [pre
  477. if `is_convertible<Dr2,Dr1>::value`
  478. then
  479. `-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)`.
  480. Otherwise,
  481. `((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
  482. ]
  483. [endsect]
  484. [include facade_tutorial.qbk]
  485. [endsect]