iterator_categories.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><!-- saved from url=(0022)http://internet.e-mail --><title>Improved Iterator Categories and Requirements</title>
  2. <meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
  3. <meta content="Microsoft FrontPage 5.0" name="GENERATOR"></head>
  4. <body bgcolor="#ffffff">
  5. <p align="right">
  6. <table border="0">
  7. <tbody>
  8. <tr>
  9. <td width="125">
  10. <p align="right">Document number: </p></td>
  11. <td width="190">
  12. <p>J16/01-0011 = WG21 N1297 </p></td></tr>
  13. <tr>
  14. <td width="125">
  15. <p align="right">Date: </p></td>
  16. <td width="190">
  17. <p>March 21, 2001 </p></td></tr>
  18. <tr>
  19. <td width="125">
  20. <p align="right">Author: </p></td>
  21. <td width="190">
  22. <p>Jeremy Siek, <br>University of Notre Dame </p></td></tr>
  23. <tr>
  24. <td width="125">
  25. <p></p></td>
  26. <td width="190">
  27. <p><a href="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>
  28. </p></td></tr></tbody></table></p>
  29. <h1>
  30. <center>Improved Iterator Categories and Requirements</center></h1>
  31. <h2>Introduction</h2>The standard iterator categories and requirements are
  32. flawed because they use a single hierarchy of requirements to address two
  33. orthogonal issues: <b><i>iterator traversal</i></b> and <b><i>dereference return
  34. type</i></b>. The current iterator requirement hierarchy is mainly geared
  35. towards iterator traversal (hence the category names), while requirements that
  36. address dereference return type sneak in at various places. The following table
  37. gives a summary of the current dereference return type requirements in the
  38. iterator categories.
  39. <p>
  40. </p><center>
  41. <a name="table:1">
  42. <b>Table 1.</b> Summary of current dereference return type
  43. requirements.</a><table border="1">
  44. <tbody>
  45. <tr>
  46. <td>Output Iterator</td>
  47. <td><tt>*i = a</tt> </td></tr>
  48. <tr>
  49. <td>Input Iterator</td>
  50. <td><tt>*i</tt> is convertible to <tt>T</tt></td></tr>
  51. <tr>
  52. <td>Forward Iterator</td>
  53. <td><tt>*i</tt> is <tt>T&amp;</tt> (or <tt>const T&amp;</tt> once <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200">issue
  54. 200</a> is resolved)</td></tr>
  55. <tr>
  56. <td>Random Access Iterator</td>
  57. <td><tt>i[n]</tt> is convertible to <tt>T</tt> (which is odd because the
  58. operational semantics say <tt>i[n]</tt> is equivalent to <tt>*(i + n)</tt>
  59. which would have a return type of <tt>T&amp;</tt>) </td></tr></tbody></table></center>
  60. <h2>Examples of useful iterators that do not ``fit''</h2>
  61. <p>Because of the mixing of iterator traversal and dereference return type, many
  62. useful iterators can not be appropriately categorized. For example,
  63. <tt>vector&lt;bool&gt;::iterator</tt> is almost a random access iterator, but
  64. the return type is not <tt>bool&amp;</tt> (see <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#96">issue
  65. 96</a> and Herb Sutter's paper J16/99-0008 = WG21 N1185). Therefore, the
  66. iterators only meet the requirements of input iterator and output iterator. This
  67. is so nonintuitive that at least one implementation erroneously assigns
  68. <tt>random_access_iterator_tag</tt> as its <tt>iterator_category</tt>. Also,
  69. <tt>vector&lt;bool&gt;</tt> is not the only example of useful iterators that do
  70. not return true references: there is the often cited example of disk-based
  71. collections.
  72. </p><p>Another example is a counting iterator, an iterator the returns a sequence of
  73. integers when incremented and dereferenced (see <a href="http://www.boost.org/libs/iterator/doc/counting_iterator.html"><tt>boost::counting_iterator</tt></a>).
  74. There are two ways to implement this iterator, 1) make the <tt>reference</tt>
  75. type be a true reference (a reference to an integer data member of the counting
  76. iterator) or 2) make the <tt>reference</tt> type be the same as the
  77. <tt>value_type</tt>. Option 1) runs into the problems discussed in <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#198">Issue
  78. 198</a>, the reference will not be valid after the iterator is destroyed. Option
  79. 2) is therefore a better choice, but then we have a counting iterator that
  80. cannot be a random access iterator.
  81. </p><p>Yet another example is a transform iterator, an iterator adaptor that applies
  82. a unary function object to the dereference value of the wrapped iterator (see <a href="http://www.boost.org/libs/iterator/doc/transform_iterator.html"><tt>boost::transform_iterator</tt></a>).
  83. For unary functions such as <tt>std::times</tt> the return type of
  84. <tt>operator*</tt> clearly needs to be the <tt>result_type</tt> of the function
  85. object, which is typically not a reference. However, with the current iterator
  86. requirements, if you wrap <tt>int*</tt> with a transform iterator, you do not
  87. get a random access iterator as expected, but an input iterator.
  88. </p><p>A fourth example is found in the vertex and edge iterators of the <a href="http://www.boost.org/libs/graph/doc/table_of_contents.html">Boost Graph
  89. Library</a>. These iterators return vertex and edge descriptors, which are
  90. lightweight handles created on-the-fly. They must be returned by-value. As a
  91. result, their current standard iterator category is
  92. <tt>std::input_iterator_tag</tt>, which means that, strictly speaking, you could
  93. not use these iterators with algorithms like <tt>std::min_element()</tt>. As a
  94. temporary solution, we introduced the concept <a href="http://www.boost.org/libs/utility/MultiPassInputIterator.html">Multi-Pass
  95. Input Iterator</a> to describe the vertex and edge descriptors, but as the
  96. design notes for concept suggest, a better solution is needed.
  97. </p><p>In short, there are many useful iterators that do not fit into the current
  98. standard iterator categories. As a result, the following bad things happen:
  99. </p><ul>
  100. <li>Iterators are often miss-categorized.
  101. </li><li>Algorithm requirements are more strict than necessary, because they can
  102. not separate out the need for random-access from the need for a true reference
  103. return type. </li></ul>
  104. <h2>Proposal for new iterator categories and requirements</h2>The iterator
  105. requirements should be separated into two hierarchies. One set of concepts
  106. handles the return type semantics:
  107. <ul>
  108. <li><a href="#concept_ReadableIterator">Readable
  109. Iterator</a>
  110. </li><li><a href="#concept_WritableIterator">Writable
  111. Iterator</a>
  112. </li><li><a href="#concept_SwappableIterator">Swappable
  113. Iterator</a>
  114. </li><li><a href="#concept_ConstantLvalueIterator">Constant
  115. Lvalue Iterator</a>
  116. </li><li><a href="#concept_MutableLvalueIterator">Mutable
  117. Lvalue Iterator</a> </li></ul>The other set of concepts handles iterator
  118. traversal:
  119. <ul>
  120. <li><a href="#concept_ForwardTraversalIterator">Forward
  121. Traversal Iterator</a>
  122. </li><li><a href="#concept_BidirectionalTraversalIterator">Bidirectional
  123. Traversal Iterator</a>
  124. </li><li><a href="#concept_RandomAccessTraversalIterator">Random
  125. Access Traversal Iterator</a> </li></ul>The current Input Iterator and Output
  126. Iterator requirements will continue to be used as is. Note that Input Iterator
  127. implies Readable Iterator and Output Iterator implies Writable Iterator.
  128. <p>Note: we considered defining a Single-Pass Iterator, which could be combined
  129. with Readable or Writable Iterator to replace the Input and Output Iterator
  130. requirements. We rejected this idea because there are several differences
  131. between Input and Output Iterators that make it hard to merge them: Input
  132. Iterator requires Equality Comparable while Output Iterator does not and Input
  133. Iterator requires Assignable while Output Iterator does not.
  134. </p><h3>New categories and traits classes</h3>Each of the new iterator requirements
  135. will need a category tag. <pre>namespace std {
  136. // Return Type Categories
  137. struct readable_iterator_tag { };
  138. struct writable_iterator_tag { };
  139. struct swappable_iterator_tag { };
  140. struct mutable_lvalue_iterator_tag : virtual public writable_iterator_tag,
  141. virtual public readable_iterator_tag { };
  142. struct constant_lvalue_iterator_tag : public readable_iterator_tag { };
  143. // Traversal Categories
  144. struct forward_traversal_tag { };
  145. struct bidirectional_traversal_tag : public forward_traversal_tag { };
  146. struct random_access_traversal_tag : public bidirectional_traversal_tag { };
  147. }
  148. </pre>And there will need to be a way to access these category tags using a
  149. traits mechanism. Adding new typedefs to <tt>std::iterator_traits</tt> is not an
  150. acceptable solution because that would break every existing iterator. Instead,
  151. we propose two new traits classes. It is important that these traits classes are
  152. <b>backward compatible</b>, that is, they should work with any iterator for
  153. which there is a valid definition of <tt>std::iterator_traits</tt>. This can be
  154. accomplished by making the default behavior of the traits classes map the
  155. <tt>iterator_category</tt> of the iterator to the appropriate return or
  156. traversal category. For new iterators, either specializations of these traits
  157. classes can be defined, or the iterator can provide nested typedefs, and inherit
  158. from <tt>new_iterator_base</tt> (which is just a signal to the traits class that
  159. it is a new iterator). As with <tt>std::iterator_traits</tt>, specializations
  160. for <tt>T*</tt> are provided. <pre>namespace std {
  161. struct new_iterator_base { };
  162. template &lt;typename Iterator&gt;
  163. struct return_category
  164. {
  165. <b><i>// Pseudo-code</i></b>
  166. if (Iterator inherits from new_iterator_base) {
  167. typedef typename Iterator::return_category type;
  168. } else {
  169. typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
  170. typedef typename OldTraits::iterator_category Cat;
  171. if (Cat inherits from std::forward_iterator_tag)
  172. if (is-const(T))
  173. typedef boost::constant_lvalue_iterator_tag type;
  174. else
  175. typedef boost::mutable_lvalue_iterator_tag type;
  176. else if (Cat inherits from std::input_iterator_tag)
  177. typedef boost::readable_iterator_tag type;
  178. else if (Cat inherits from std::output_iterator_tag)
  179. typedef boost::writable_iterator_tag type;
  180. }
  181. };
  182. template &lt;typename T&gt;
  183. struct return_category&lt;T*&gt;
  184. {
  185. <b><i>// Pseudo-code</i></b>
  186. if (is-const(T))
  187. typedef boost::constant_lvalue_iterator_tag type;
  188. else
  189. typedef boost::mutable_lvalue_iterator_tag type;
  190. };
  191. template &lt;typename Iterator&gt;
  192. struct traversal_category
  193. {
  194. <b><i>// Pseudo-code</i></b>
  195. if (Iterator inherits from new_iterator_base) {
  196. typedef typename Iterator::traversal_category type;
  197. } else {
  198. typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
  199. typedef typename OldTraits::iterator_category Cat;
  200. if (Cat inherits from std::random_access_iterator_tag)
  201. typedef boost::random_access_traversal_tag type;
  202. else if (Cat inherits from std::bidirectional_iterator_tag)
  203. typedef boost::bidirectional_traversal_tag type;
  204. else if (Cat inherits from std::forward_iterator_tag)
  205. typedef boost::forward_traversal_tag type;
  206. }
  207. };
  208. template &lt;typename T&gt;
  209. struct traversal_category&lt;T*&gt;
  210. {
  211. typedef boost::random_access_traversal_tag type;
  212. };
  213. }
  214. </pre>
  215. <h2>Impact on the Standard Algorithms</h2>Many of the standard algorithms place
  216. more requirements than necessary on their iterator parameters due to the
  217. coarseness of the current iterator categories. By using the new iterator
  218. categories a better fit can be achieved, thereby increasing the reusability of
  219. the algorithms. These changes will not affect user-code, though they will
  220. require changes by standard implementers: dispatching should be based on the new
  221. categories, and in places return values may need to be handled more carefully.
  222. In particular, uses of <tt>std::swap()</tt> will need to be replaced with
  223. <tt>std::iter_swap()</tt>, and <tt>std::iter_swap()</tt> will need to call
  224. <tt>std::swap()</tt>.
  225. <p>
  226. </p><center>
  227. <a name="table:2">
  228. <b>Table 2.</b> Requirement changes for standard
  229. algorithms.</a><table border="1">
  230. <tbody>
  231. <tr>
  232. <th>Algorithm</th>
  233. <th>Requirement Change</th></tr>
  234. <tr>
  235. <td>find_end</td>
  236. <td rowspan="12">Forward Iterator<br>-&gt; Forward Traversal Iterator and
  237. Readable Iterator </td></tr>
  238. <tr>
  239. <td>find_first_of</td></tr>
  240. <tr>
  241. <td>adjacent_find</td></tr>
  242. <tr>
  243. <td>search</td></tr>
  244. <tr>
  245. <td>search_n</td></tr>
  246. <tr>
  247. <td>rotate_copy</td></tr>
  248. <tr>
  249. <td>lower_bound</td></tr>
  250. <tr>
  251. <td>upper_bound</td></tr>
  252. <tr>
  253. <td>equal_range</td></tr>
  254. <tr>
  255. <td>binary_search</td></tr>
  256. <tr>
  257. <td>min_element</td></tr>
  258. <tr>
  259. <td>max_element</td></tr>
  260. <tr>
  261. <td>iter_swap</td>
  262. <td>Forward Iterator<br>-&gt; Swappable Iterator </td></tr>
  263. <tr>
  264. <td>fill</td>
  265. <td rowspan="2">Forward Iterator<br>-&gt; Forward Traversal Iterator and
  266. Writable Iterator </td></tr>
  267. <tr>
  268. <td>generate</td></tr>
  269. <tr>
  270. <td>swap_ranges</td>
  271. <td rowspan="2">Forward Iterator<br>-&gt; Forward Traversal Iterator and
  272. Swappable Iterator </td></tr>
  273. <tr>
  274. <td>rotate</td></tr>
  275. <tr>
  276. <td>replace</td>
  277. <td rowspan="5">Forward Iterator<br>-&gt; Forward Traversal Iterator
  278. and<br>Readable Iterator and Writable Iterator </td>
  279. </tr><tr>
  280. <td>replace_if</td></tr>
  281. <tr>
  282. <td>remove</td></tr>
  283. <tr>
  284. <td>remove_if</td></tr>
  285. <tr>
  286. <td>unique</td></tr>
  287. <tr>
  288. <td>reverse</td>
  289. <td rowspan="2">Bidirectional Iterator<br>-&gt; Bidirectional Traversal
  290. Iterator and Swappable Iterator </td></tr>
  291. <tr>
  292. <td>partition</td></tr>
  293. <tr>
  294. <td>copy_backwards</td>
  295. <td>Bidirectional Iterator<br>-&gt; Bidirectional Traversal Iterator and
  296. Readable Iterator<br>Bidirectional Iterator<br>-&gt; Bidirectional
  297. Traversal Iterator and Writable Iterator </td></tr>
  298. <tr>
  299. <td>next_permutation</td>
  300. <td rowspan="2">Bidirectional Iterator<br>-&gt; Bidirectional Traversal
  301. Iterator and <br>Swappable Iterator and Readable Iterator </td>
  302. </tr><tr>
  303. <td>prev_permutation</td></tr>
  304. <tr>
  305. <td>stable_partition</td>
  306. <td rowspan="2">Bidirectional Iterator<br>-&gt; Bidirectional Traversal
  307. Iterator and <br>Readable Iterator and Writable Iterator </td>
  308. </tr><tr>
  309. <td>inplace_merge</td></tr>
  310. <tr>
  311. <td>reverse_copy</td>
  312. <td>Bidirectional Iterator<br>-&gt; Bidirectional Traversal Iterator and
  313. Readable Iterator </td></tr>
  314. <tr>
  315. <td>random_shuffle</td>
  316. <td rowspan="9">Random Access Iterator<br>-&gt; Random Access Traversal
  317. Iterator and Swappable Iterator </td></tr>
  318. <tr>
  319. <td>sort</td></tr>
  320. <tr>
  321. <td>stable_sort</td></tr>
  322. <tr>
  323. <td>partial_sort</td></tr>
  324. <tr>
  325. <td>nth_element</td></tr>
  326. <tr>
  327. <td>push_heap</td></tr>
  328. <tr>
  329. <td>pop_heap</td></tr>
  330. <tr>
  331. <td>make_heap</td></tr>
  332. <tr>
  333. <td>sort_heap</td></tr></tbody></table></center>
  334. <h2>The New Iterator Requirements</h2>
  335. <h3>Notation</h3>
  336. <table>
  337. <tbody>
  338. <tr>
  339. <td><tt>X</tt></td>
  340. <td>The iterator type.</td></tr>
  341. <tr>
  342. <td><tt>T</tt></td>
  343. <td>The value type of <tt>X</tt>, i.e.,
  344. <tt>std::iterator_traits&lt;X&gt;::value_type</tt>.</td></tr>
  345. <tr>
  346. <td><tt>x</tt>, <tt>y</tt></td>
  347. <td>An object of type <tt>X</tt>.</td></tr>
  348. <tr>
  349. <td><tt>t</tt></td>
  350. <td>An object of type <tt>T</tt>.</td></tr></tbody></table>
  351. <p>
  352. </p><hr>
  353. <!--------------------------------------------------------------------------->
  354. <h3><a name="concept_ReadableIterator"></a>Readable Iterator </h3>A Readable
  355. Iterator is an iterator that dereferences to produce an rvalue that is
  356. convertible to the <tt>value_type</tt> of the iterator.
  357. <h3>Associated Types</h3>
  358. <table border="1">
  359. <tbody>
  360. <tr>
  361. <td>Value type</td>
  362. <td><tt>std::iterator_traits&lt;X&gt;::value_type</tt></td>
  363. <td>The type of the objects pointed to by the iterator.</td></tr>
  364. <tr>
  365. <td>Reference type</td>
  366. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
  367. <td>The return type of dereferencing the iterator. This type must be
  368. convertible to <tt>T</tt>. </td></tr>
  369. <tr>
  370. <td>Return Category</td>
  371. <td><tt>std::return_category&lt;X&gt;::type</tt></td>
  372. <td>A type convertible to <tt>std::readable_iterator_tag</tt>
  373. </td></tr></tbody></table>
  374. <h3>Refinement of</h3><a href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy
  375. Constructible</a>
  376. <h3>Valid expressions</h3>
  377. <table border="1">
  378. <tbody>
  379. <tr>
  380. <th>Name</th>
  381. <th>Expression</th>
  382. <th>Type requirements</th>
  383. <th>Return type</th></tr>
  384. <tr>
  385. <td>Dereference</td>
  386. <td><tt>*x</tt></td>
  387. <td> </td>
  388. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td></tr>
  389. <tr>
  390. <td>Member access</td>
  391. <td><tt>x-&gt;m</tt></td>
  392. <td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
  393. <td>If <tt>m</tt> is a data member, the type of <tt>m</tt>. If <tt>m</tt>
  394. is a member function, the return type of <tt>m</tt>. </td></tr></tbody></table>
  395. <p>
  396. </p><hr>
  397. <!--------------------------------------------------------------------------->
  398. <h3><a name="concept_WritableIterator"></a>Writable Iterator </h3>A Writable
  399. Iterator is an iterator that can be used to store a value using the
  400. dereference-assignment expression.
  401. <h3>Definitions</h3>If <tt>x</tt> is an Writable Iterator of type <tt>X</tt>,
  402. then the expression <tt>*x = a;</tt> stores the value <tt>a</tt> into
  403. <tt>x</tt>. Note that <tt>operator=</tt>, like other C++ functions, may be
  404. overloaded; it may, in fact, even be a template function. In general, then,
  405. <tt>a</tt> may be any of several different types. A type <tt>A</tt> belongs to
  406. the <i>set of value types</i> of <tt>X</tt> if, for an object <tt>a</tt> of type
  407. <tt>A</tt>, <tt>*x = a;</tt> is well-defined and does not require performing any
  408. non-trivial conversions on <tt>a</tt>.
  409. <h3>Associated Types</h3>
  410. <table border="1">
  411. <tbody>
  412. <tr>
  413. <td>Return Category</td>
  414. <td><tt>std::return_category&lt;X&gt;::type</tt></td>
  415. <td>A type convertible to <tt>std::writable_iterator_tag</tt>
  416. </td></tr></tbody></table>
  417. <h3>Refinement of</h3><a href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy
  418. Constructible</a>
  419. <h3>Valid expressions</h3>
  420. <table border="1">
  421. <tbody>
  422. <tr>
  423. <th>Name</th>
  424. <th>Expression</th>
  425. <th>Return type</th></tr>
  426. <tr>
  427. <td>Dereference assignment</td>
  428. <td><tt>*x = a</tt></td>
  429. <td>unspecified</td></tr></tbody></table>
  430. <p>
  431. </p><hr>
  432. <!--------------------------------------------------------------------------->
  433. <h3><a name="concept_SwappableIterator"></a>Swappable Iterator </h3>A Swappable
  434. Iterator is an iterator whose dereferenced values can be swapped.
  435. <p>Note: the requirements for Swappable Iterator are dependent on the issues
  436. surrounding <tt>std::swap()</tt> being resolved. Here we assume that the issue
  437. will be resolved by allowing the overload of <tt>std::swap()</tt> for
  438. user-defined types.
  439. </p><p>Note: Readable Iterator and Writable Iterator combined implies Swappable
  440. Iterator because of the fully templated <tt>std::swap()</tt>. However, Swappable
  441. Iterator does not imply Readable Iterator nor Writable Iterator.
  442. </p><h3>Associated Types</h3>
  443. <table border="1">
  444. <tbody>
  445. <tr>
  446. <td>Return Category</td>
  447. <td><tt>std::return_category&lt;X&gt;::type</tt></td>
  448. <td>A type convertible to <tt>std::swappable_iterator_tag</tt>
  449. </td></tr></tbody></table>
  450. <h3>Valid expressions</h3>Of the two valid expressions listed below, only one
  451. <b>OR</b> the other is required. If <tt>std::iter_swap()</tt> is overloaded for
  452. <tt>X</tt> then <tt>std::swap()</tt> is not required. If
  453. <tt>std::iter_swap()</tt> is not overloaded for <tt>X</tt> then the default
  454. (fully templated) version is used, which will call <tt>std::swap()</tt> (this
  455. means changing the current requirements for <tt>std::iter_swap()</tt>).
  456. <p>
  457. <table border="1">
  458. <tbody>
  459. <tr>
  460. <th>Name</th>
  461. <th>Expression</th>
  462. <th>Return type</th></tr>
  463. <tr>
  464. <td>Iterator Swap</td>
  465. <td><tt>std::iter_swap(x, y)</tt></td>
  466. <td>void</td></tr>
  467. <tr>
  468. <td>Dereference and Swap</td>
  469. <td><tt>std::swap(*x, *y)</tt></td>
  470. <td>void</td></tr></tbody></table>
  471. </p><p>
  472. </p><hr>
  473. <!--------------------------------------------------------------------------->
  474. <h3><a name="concept_ConstantLvalueIterator"></a>Constant Lvalue Iterator </h3>A
  475. Constant Lvalue Iterator is an iterator that dereferences to produce a const
  476. reference to the pointed-to object, i.e., the associated <tt>reference</tt> type
  477. is <tt>const T&amp;</tt>. Changing the value of or destroying an iterator that
  478. models Constant Lvalue Iterator does not invalidate pointers and references
  479. previously obtained from that iterator.
  480. <h3>Refinement of</h3><a href="#concept_ReadableIterator">Readable
  481. Iterator</a>
  482. <h3>Associated Types</h3>
  483. <table border="1">
  484. <tbody>
  485. <tr>
  486. <td>Reference type</td>
  487. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
  488. <td>The return type of dereferencing the iterator, which must be <tt>const
  489. T&amp;</tt>. </td></tr><!-- I don't think this is needed
  490. <tr>
  491. <td>Pointer type</td>
  492. <td><tt>std::iterator_traits&lt;X&gt;::pointer</tt></td>
  493. <td>
  494. The pointer to the value type, which must be <tt>const T*</tt>.
  495. </td>
  496. </tr>
  497. -->
  498. <tr>
  499. <td>Return Category</td>
  500. <td><tt>std::return_category&lt;X&gt;::type</tt></td>
  501. <td>A type convertible to <tt>std::constant_lvalue_iterator_tag</tt>
  502. </td></tr></tbody></table><!-- these are not necessary now that we use reference as operator* return type
  503. <h3>Valid expressions</h3>
  504. <Table border>
  505. <tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
  506. <tr>
  507. <td>Dereference</td>
  508. <td><tt>*x</tt></td>
  509. <td>&nbsp;</td>
  510. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
  511. </tr>
  512. <tr>
  513. <td>Member access</td>
  514. <td><tt>x-&gt;m</tt></td>
  515. <td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
  516. <td>
  517. &nbsp;
  518. </td>
  519. </tr>
  520. </table>
  521. -->
  522. <p>
  523. </p><hr>
  524. <!--------------------------------------------------------------------------->
  525. <h3><a name="concept_MutableLvalueIterator"></a>Mutable Lvalue Iterator </h3>A
  526. Mutable Lvalue Iterator is an iterator that dereferences to produce a reference
  527. to the pointed-to object. The associated <tt>reference</tt> type is
  528. <tt>T&amp;</tt>. Changing the value of or destroying an iterator that models
  529. Mutable Lvalue Iterator does not invalidate pointers and references previously
  530. obtained from that iterator.
  531. <h3>Refinement of</h3><a href="#concept_ReadableIterator">Readable
  532. Iterator</a>, <a href="#concept_WritableIterator">Writable
  533. Iterator</a>, and <a href="#concept_SwappableIterator">Swappable
  534. Iterator</a>.
  535. <h3>Associated Types</h3>
  536. <table border="1">
  537. <tbody>
  538. <tr>
  539. <td>Reference type</td>
  540. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
  541. <td>The return type of dereferencing the iterator, which must be
  542. <tt>T&amp;</tt>.</td></tr><!-- I don't think this is necessary
  543. <tr>
  544. <td>Pointer type</td>
  545. <td><tt>std::iterator_traits&lt;X&gt;::pointer</tt></td>
  546. <td>
  547. The pointer to the value type, which is <tt>T*</tt>.
  548. </td>
  549. </tr>
  550. -->
  551. <tr>
  552. <td>Return Category</td>
  553. <td><tt>std::return_category&lt;X&gt;::type</tt></td>
  554. <td>A type convertible to <tt>std::mutable_lvalue_iterator_tag</tt>
  555. </td></tr></tbody></table><!-- no longer needed since the return type is specified as reference in the readable iterator
  556. <h3>Valid expressions</h3>
  557. <Table border>
  558. <tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
  559. <tr>
  560. <td>Dereference</td>
  561. <td><tt>*x</tt></td>
  562. <td>&nbsp;</td>
  563. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
  564. </tr>
  565. <tr>
  566. <td>Member access</td>
  567. <td><tt>x-&gt;m</tt></td>
  568. <td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
  569. <td>
  570. &nbsp;
  571. </td>
  572. </tr>
  573. </table>
  574. -->
  575. <p>
  576. </p><hr>
  577. <!--------------------------------------------------------------------------->
  578. <h3><a name="concept_ForwardTraversalIterator"></a>Forward Traversal Iterator
  579. </h3>The Forward Iterator is an iterator that can be incremented. Also, it is
  580. permissible to make multiple passes through the iterator's range.
  581. <h3>Refinement of</h3><a href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy
  582. Constructible</a>, <a href="http://www.boost.org/libs/utility/Assignable.html">Assignable</a>, <a href="https://www.boost.org/sgi/stl/DefaultConstructible.html">Default
  583. Constructible</a>, and <a href="https://www.boost.org/sgi/stl/EqualityComparable.html">Equality
  584. Comparable</a>
  585. <h3>Associated types</h3>
  586. <table border="1">
  587. <tbody>
  588. <tr>
  589. <td>Difference Type</td>
  590. <td><tt>std::iterator_traits&lt;X&gt;::difference_type</tt></td>
  591. <td>A signed integral type used for representing distances between
  592. iterators that point into the same range. </td></tr>
  593. <tr>
  594. <td>Traversal Category</td>
  595. <td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
  596. <td>A type convertible to <tt>std::forward_traversal_tag</tt>
  597. </td></tr></tbody></table>
  598. <h3>Valid expressions</h3>
  599. <table border="1">
  600. <tbody>
  601. <tr>
  602. <th>Name</th>
  603. <th>Expression</th>
  604. <th>Type requirements</th>
  605. <th>Return type</th></tr>
  606. <tr>
  607. <td>Preincrement</td>
  608. <td><tt>++i</tt></td>
  609. <td> </td>
  610. <td><tt>X&amp;</tt></td></tr>
  611. <tr>
  612. <td>Postincrement</td>
  613. <td><tt>i++</tt></td>
  614. <td> </td>
  615. <td>convertible to <tt>const X&amp;</tt></td></tr></tbody></table>
  616. <p>
  617. </p><hr>
  618. <!--------------------------------------------------------------------------->
  619. <h3><a name="concept_BidirectionalTraversalIterator"></a>Bidirectional Traversal
  620. Iterator </h3>An iterator that can be incremented and decremented.
  621. <h3>Refinement of</h3><a href="#concept_ForwardTraversalIterator">Forward
  622. Traversal Iterator</a>
  623. <h3>Associated types</h3>
  624. <table border="1">
  625. <tbody>
  626. <tr>
  627. <td>Traversal Category</td>
  628. <td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
  629. <td>A type convertible to <tt>std::bidirectional_traversal_tag</tt>
  630. </td></tr></tbody></table>
  631. <h3>Valid expressions</h3>
  632. <table border="1">
  633. <tbody>
  634. <tr>
  635. <th>Name</th>
  636. <th>Expression</th>
  637. <th>Type requirements</th>
  638. <th>Return type</th></tr>
  639. <tr>
  640. <td>Predecrement</td>
  641. <td><tt>--i</tt></td>
  642. <td> </td>
  643. <td><tt>X&amp;</tt></td></tr>
  644. <tr>
  645. <td>Postdecrement</td>
  646. <td><tt>i--</tt></td>
  647. <td> </td>
  648. <td>convertible to <tt>const X&amp;</tt></td></tr></tbody></table>
  649. <p>
  650. </p><hr>
  651. <!--------------------------------------------------------------------------->
  652. <h3><a name="concept_RandomAccessTraversalIterator"></a>Random Access Traversal
  653. Iterator </h3>An iterator that provides constant-time methods for moving forward
  654. and backward in arbitrary-sized steps.
  655. <h3>Refinement of</h3><a href="#concept_BidirectionalTraversalIterator">Bidirectional
  656. Traversal Iterator</a> and <a href="https://www.boost.org/sgi/stl/LessThanComparable.html">Less Than
  657. Comparable</a> where <tt>&lt;</tt> is a total ordering
  658. <h3>Associated types</h3>
  659. <table border="1">
  660. <tbody>
  661. <tr>
  662. <td>Traversal Category</td>
  663. <td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
  664. <td>A type convertible to <tt>std::random_access_traversal_tag</tt>
  665. </td></tr></tbody></table>
  666. <h3>Valid expressions</h3>
  667. <table border="1">
  668. <tbody>
  669. <tr>
  670. <th>Name</th>
  671. <th>Expression</th>
  672. <th>Type requirements</th>
  673. <th>Return type</th></tr>
  674. <tr>
  675. <td>Iterator addition</td>
  676. <td><tt>i += n</tt></td>
  677. <td> </td>
  678. <td><tt>X&amp;</tt></td></tr>
  679. <tr>
  680. <td>Iterator addition</td>
  681. <td><tt>i + n</tt> or <tt>n + i</tt></td>
  682. <td> </td>
  683. <td><tt>X</tt></td></tr>
  684. <tr>
  685. <td>Iterator subtraction</td>
  686. <td><tt>i -= n</tt></td>
  687. <td> </td>
  688. <td><tt>X&amp;</tt></td></tr>
  689. <tr>
  690. <td>Iterator subtraction</td>
  691. <td><tt>i - n</tt></td>
  692. <td> </td>
  693. <td><tt>X</tt></td></tr>
  694. <tr>
  695. <td>Difference</td>
  696. <td><tt>i - j</tt></td>
  697. <td> </td>
  698. <td><tt>std::iterator_traits&lt;X&gt;::difference_type</tt></td></tr>
  699. <tr>
  700. <td>Element operator</td>
  701. <td><tt>i[n]</tt></td>
  702. <td><tt>X</tt> must also be a model of <a href="#concept_ReadableIterator">Readable
  703. Iterator</a>. </td>
  704. <td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td></tr>
  705. <tr>
  706. <td>Element assignment</td>
  707. <td><tt>i[n] = t</tt></td>
  708. <td><tt>X</tt> must also be a model of <a href="#concept_WritableIterator">Writable
  709. Iterator</a>.</td>
  710. <td>unspecified</td></tr></tbody></table>
  711. <p>
  712. </p><hr>
  713. <!-- LocalWords: HTML BGCOLOR FFFFFF TR TD Siek HREF mailto jsiek
  714. --><!-- LocalWords: lsc edu tt const href http anubis dkuug dk JTC SC WG docs lt
  715. --><!-- LocalWords: lwg html bool gt Sutter's htm Lvalue namespace std struct
  716. --><!-- LocalWords: lvalue typename OldTraits reusability min iter prev inplace
  717. --><!-- LocalWords: rvalue templated Preincrement Postincrement Predecrement
  718. --><!-- LocalWords: Postdecrement
  719. --></body></html>