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)
5 +++++++++++++++++++++++++++++
6 Iterator Facade and Adaptor
7 +++++++++++++++++++++++++++++
9 :Author: David Abrahams, Jeremy Siek, Thomas Witt
10 :Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
11 :organization: `Boost Consulting`_, Indiana University `Open Systems
12 Lab`_, `Zephyr Associates, Inc.`_
15 :Number: This is a revised version of N1530_\ =03-0113, which was
16 accepted for Technical Report 1 by the C++ standard
17 committee's library working group.
19 .. Version 1.9 of this ReStructuredText document corresponds to
20 n1530_, the paper accepted by the LWG.
22 .. _n1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
24 :copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
26 .. _`Boost Consulting`: http://www.boost-consulting.com
27 .. _`Open Systems Lab`: http://www.osl.iu.edu
28 .. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com
30 :abstract: We propose a set of class templates that help programmers
31 build standard-conforming iterators, both from scratch and
32 by adapting other iterators.
34 .. contents:: Table of Contents
40 Iterators play an important role in modern C++ programming. The
41 iterator is the central abstraction of the algorithms of the Standard
42 Library, allowing algorithms to be re-used in in a wide variety of
43 contexts. The C++ Standard Library contains a wide variety of useful
44 iterators. Every one of the standard containers comes with constant
45 and mutable iterators [#mutable]_, and also reverse versions of those
46 same iterators which traverse the container in the opposite direction.
47 The Standard also supplies ``istream_iterator`` and
48 ``ostream_iterator`` for reading from and writing to streams,
49 ``insert_iterator``, ``front_insert_iterator`` and
50 ``back_insert_iterator`` for inserting elements into containers, and
51 ``raw_storage_iterator`` for initializing raw memory [7].
53 Despite the many iterators supplied by the Standard Library, obvious
54 and useful iterators are missing, and creating new iterator types is
55 still a common task for C++ programmers. The literature documents
56 several of these, for example line_iterator [3] and Constant_iterator
57 [9]. The iterator abstraction is so powerful that we expect
58 programmers will always need to invent new iterator types.
60 Although it is easy to create iterators that *almost* conform to the
61 standard, the iterator requirements contain subtleties which can make
62 creating an iterator which *actually* conforms quite difficult.
63 Further, the iterator interface is rich, containing many operators
64 that are technically redundant and tedious to implement. To automate
65 the repetitive work of constructing iterators, we propose
66 ``iterator_facade``, an iterator base class template which provides
67 the rich interface of standard iterators and delegates its
68 implementation to member functions of the derived class. In addition
69 to reducing the amount of code necessary to create an iterator, the
70 ``iterator_facade`` also provides compile-time error detection.
71 Iterator implementation mistakes that often go unnoticed are turned
72 into compile-time errors because the derived class implementation must
73 match the expectations of the ``iterator_facade``.
75 A common pattern of iterator construction is the adaptation of one
76 iterator to form a new one. The functionality of an iterator is
77 composed of four orthogonal aspects: traversal, indirection, equality
78 comparison and distance measurement. Adapting an old iterator to
79 create a new one often saves work because one can reuse one aspect of
80 functionality while redefining the other. For example, the Standard
81 provides ``reverse_iterator``, which adapts any Bidirectional Iterator
82 by inverting its direction of traversal. As with plain iterators,
83 iterator adaptors defined outside the Standard have become commonplace
86 * Checked iter[13] adds bounds-checking to an existing iterator.
88 * The iterators of the View Template Library[14], which adapts
89 containers, are themselves adaptors over the underlying iterators.
91 * Smart iterators [5] adapt an iterator's dereferencing behavior by
92 applying a function object to the object being referenced and
95 * Custom iterators [4], in which a variety of adaptor types are enumerated.
97 * Compound iterators [1], which access a slice out of a container of containers.
99 * Several iterator adaptors from the MTL [12]. The MTL contains a
100 strided iterator, where each call to ``operator++()`` moves the
101 iterator ahead by some constant factor, and a scaled iterator, which
102 multiplies the dereferenced value by some constant.
104 .. [#concept] We use the term concept to mean a set of requirements
105 that a type must satisfy to be used with a particular template
108 .. [#mutable] The term mutable iterator refers to iterators over objects that
109 can be changed by assigning to the dereferenced iterator, while
110 constant iterator refers to iterators over objects that cannot be
113 To fulfill the need for constructing adaptors, we propose the
114 ``iterator_adaptor`` class template. Instantiations of
115 ``iterator_adaptor`` serve as a base classes for new iterators,
116 providing the default behavior of forwarding all operations to the
117 underlying iterator. The user can selectively replace these features
118 in the derived iterator class. This proposal also includes a number
119 of more specialized adaptors, such as the ``transform_iterator`` that
120 applies some user-specified function during the dereference of the
123 ========================
124 Impact on the Standard
125 ========================
127 This proposal is purely an addition to the C++ standard library.
128 However, note that this proposal relies on the proposal for New
138 This proposal is formulated in terms of the new ``iterator concepts``
139 as proposed in n1550_, since user-defined and especially adapted
140 iterators suffer from the well known categorization problems that are
141 inherent to the current iterator categories.
143 .. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
145 This proposal does not strictly depend on proposal n1550_, as there
146 is a direct mapping between new and old categories. This proposal
147 could be reformulated using this mapping if n1550_ was not accepted.
152 The question of iterator interoperability is poorly addressed in the
153 current standard. There are currently two defect reports that are
154 concerned with interoperability issues.
156 Issue 179_ concerns the fact that mutable container iterator types
157 are only required to be convertible to the corresponding constant
158 iterator types, but objects of these types are not required to
159 interoperate in comparison or subtraction expressions. This situation
160 is tedious in practice and out of line with the way built in types
161 work. This proposal implements the proposed resolution to issue
162 179_, as most standard library implementations do nowadays. In other
163 words, if an iterator type A has an implicit or user defined
164 conversion to an iterator type B, the iterator types are interoperable
165 and the usual set of operators are available.
167 Issue 280_ concerns the current lack of interoperability between
168 reverse iterator types. The proposed new reverse_iterator template
169 fixes the issues raised in 280. It provides the desired
170 interoperability without introducing unwanted overloads.
172 .. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
173 .. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
179 .. include:: iterator_facade_body.rst
184 .. include:: iterator_adaptor_body.rst
189 This proposal also contains several examples of specialized adaptors
190 which were easily implemented using ``iterator_adaptor``:
192 * ``indirect_iterator``, which iterates over iterators, pointers,
193 or smart pointers and applies an extra level of dereferencing.
195 * A new ``reverse_iterator``, which inverts the direction of a Base
196 iterator's motion, while allowing adapted constant and mutable
197 iterators to interact in the expected ways (unlike those in most
198 implementations of C++98).
200 * ``transform_iterator``, which applies a user-defined function object
201 to the underlying values when dereferenced.
203 * ``filter_iterator``, which provides a view of an iterator range in
204 which some elements of the underlying range are skipped.
208 * ``counting_iterator``, which adapts any incrementable type
209 (e.g. integers, iterators) so that incrementing/decrementing the
210 adapted iterator and dereferencing it produces successive values of
213 * ``function_output_iterator``, which makes it easier to create custom
216 Based on examples in the Boost library, users have generated many new
217 adaptors, among them a permutation adaptor which applies some
218 permutation to a random access iterator, and a strided adaptor, which
219 adapts a random access iterator by multiplying its unit of motion by a
220 constant factor. In addition, the Boost Graph Library (BGL) uses
221 iterator adaptors to adapt other graph libraries, such as LEDA [10]
222 and Stanford GraphBase [8], to the BGL interface (which requires C++
223 Standard compliant iterators).
230 Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
231 =======================================================================
238 struct iterator_core_access { /* implementation detail */ };
243 , class CategoryOrTraversal
244 , class Reference = Value&
245 , class Difference = ptrdiff_t
247 class iterator_facade;
252 , class Value = use_default
253 , class CategoryOrTraversal = use_default
254 , class Reference = use_default
255 , class Difference = use_default
257 class iterator_adaptor;
261 , class Value = use_default
262 , class CategoryOrTraversal = use_default
263 , class Reference = use_default
264 , class Difference = use_default
266 class indirect_iterator;
268 template <class Dereferenceable>
271 template <class Dereferenceable>
272 struct indirect_reference;
274 template <class Iterator>
275 class reverse_iterator;
280 , class Reference = use_default
281 , class Value = use_default
283 class transform_iterator;
285 template <class Predicate, class Iterator>
286 class filter_iterator;
290 , class CategoryOrTraversal = use_default
291 , class Difference = use_default
293 class counting_iterator;
295 template <class UnaryFunction>
296 class function_output_iterator;
300 Iterator facade [lib.iterator.facade]
301 =====================================
303 .. include:: iterator_facade_abstract.rst
305 Class template ``iterator_facade``
306 ----------------------------------
308 .. include:: iterator_facade_ref.rst
310 Iterator adaptor [lib.iterator.adaptor]
311 =======================================
313 .. include:: iterator_adaptor_abstract.rst
315 Class template ``iterator_adaptor``
316 -----------------------------------
318 .. include:: iterator_adaptor_ref.rst
321 Specialized adaptors [lib.iterator.special.adaptors]
322 ====================================================
325 The ``enable_if_convertible<X,Y>::type`` expression used in
326 this section is for exposition purposes. The converting constructors
327 for specialized adaptors should be only be in an overload set provided
328 that an object of type ``X`` is implicitly convertible to an object of
330 The signatures involving ``enable_if_convertible`` should behave
331 *as-if* ``enable_if_convertible`` were defined to be::
333 template <bool> enable_if_convertible_impl
336 template <> enable_if_convertible_impl<true>
339 template<typename From, typename To>
340 struct enable_if_convertible
341 : enable_if_convertible_impl<is_convertible<From,To>::value>
344 If an expression other than the default argument is used to supply
345 the value of a function parameter whose type is written in terms
346 of ``enable_if_convertible``, the program is ill-formed, no
349 [*Note:* The ``enable_if_convertible`` approach uses SFINAE to
350 take the constructor out of the overload set when the types are not
351 implicitly convertible.
358 .. include:: indirect_iterator_abstract.rst
360 Class template ``pointee``
361 ....................................
363 .. include:: pointee_ref.rst
365 Class template ``indirect_reference``
366 .....................................
368 .. include:: indirect_reference_ref.rst
370 Class template ``indirect_iterator``
371 ....................................
373 .. include:: indirect_iterator_ref.rst
378 .. include:: reverse_iterator_abstract.rst
380 Class template ``reverse_iterator``
381 ...................................
383 .. include:: reverse_iterator_ref.rst
389 .. include:: transform_iterator_abstract.rst
391 Class template ``transform_iterator``
392 .....................................
394 .. include:: transform_iterator_ref.rst
400 .. include:: filter_iterator_abstract.rst
403 Class template ``filter_iterator``
404 ..................................
406 .. include:: filter_iterator_ref.rst
412 .. include:: counting_iterator_abstract.rst
414 Class template ``counting_iterator``
415 ....................................
417 .. include:: counting_iterator_ref.rst
420 Function output iterator
421 ------------------------
423 .. include:: func_output_iter_abstract.rst
425 Class template ``function_output_iterator``
426 ...........................................
428 .. include:: func_output_iter_ref.rst
433 .. LocalWords: Abrahams Siek Witt istream ostream iter MTL strided interoperate
434 LocalWords: CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
435 LocalWords: GraphBase struct ptrdiff UnaryFunction const int typename bool pp
436 LocalWords: lhs rhs SFINAE markup iff tmp OtherDerived OtherIterator DWA foo
437 LocalWords: dereferenceable subobject AdaptableUnaryFunction impl pre ifdef'd
438 LocalWords: OtherIncrementable Coplien