mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			439 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			439 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. 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)
 | |
| 
 | |
| +++++++++++++++++++++++++++++
 | |
|  Iterator Facade and Adaptor
 | |
| +++++++++++++++++++++++++++++
 | |
| 
 | |
| :Author: David Abrahams, Jeremy Siek, Thomas Witt
 | |
| :Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
 | |
| :organization: `Boost Consulting`_, Indiana University `Open Systems
 | |
|                Lab`_, `Zephyr Associates, Inc.`_
 | |
| :date: $Date$
 | |
| 
 | |
| :Number: This is a revised version of N1530_\ =03-0113, which was
 | |
|          accepted for Technical Report 1 by the C++ standard
 | |
|          committee's library working group.  
 | |
| 
 | |
| .. Version 1.9 of this ReStructuredText document corresponds to
 | |
|    n1530_, the paper accepted by the LWG.
 | |
| 
 | |
| .. _n1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
 | |
| 
 | |
| :copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. 
 | |
| 
 | |
| .. _`Boost Consulting`: http://www.boost-consulting.com
 | |
| .. _`Open Systems Lab`: http://www.osl.iu.edu
 | |
| .. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com
 | |
| 
 | |
| :abstract: We propose a set of class templates that help programmers
 | |
|            build standard-conforming iterators, both from scratch and
 | |
|            by adapting other iterators.
 | |
| 
 | |
| .. contents:: Table of Contents
 | |
| 
 | |
| ============
 | |
|  Motivation
 | |
| ============
 | |
| 
 | |
| Iterators play an important role in modern C++ programming. The
 | |
| iterator is the central abstraction of the algorithms of the Standard
 | |
| Library, allowing algorithms to be re-used in in a wide variety of
 | |
| contexts.  The C++ Standard Library contains a wide variety of useful
 | |
| iterators. Every one of the standard containers comes with constant
 | |
| and mutable iterators [#mutable]_, and also reverse versions of those
 | |
| same iterators which traverse the container in the opposite direction.
 | |
| The Standard also supplies ``istream_iterator`` and
 | |
| ``ostream_iterator`` for reading from and writing to streams,
 | |
| ``insert_iterator``, ``front_insert_iterator`` and
 | |
| ``back_insert_iterator`` for inserting elements into containers, and
 | |
| ``raw_storage_iterator`` for initializing raw memory [7].
 | |
| 
 | |
| Despite the many iterators supplied by the Standard Library, obvious
 | |
| and useful iterators are missing, and creating new iterator types is
 | |
| still a common task for C++ programmers.  The literature documents
 | |
| several of these, for example line_iterator [3] and Constant_iterator
 | |
| [9].  The iterator abstraction is so powerful that we expect
 | |
| programmers will always need to invent new iterator types.
 | |
| 
 | |
| Although it is easy to create iterators that *almost* conform to the
 | |
| standard, the iterator requirements contain subtleties which can make
 | |
| creating an iterator which *actually* conforms quite difficult.
 | |
| Further, the iterator interface is rich, containing many operators
 | |
| that are technically redundant and tedious to implement.  To automate
 | |
| the repetitive work of constructing iterators, we propose
 | |
| ``iterator_facade``, an iterator base class template which provides
 | |
| the rich interface of standard iterators and delegates its
 | |
| implementation to member functions of the derived class.  In addition
 | |
| to reducing the amount of code necessary to create an iterator, the
 | |
| ``iterator_facade`` also provides compile-time error detection.
 | |
| Iterator implementation mistakes that often go unnoticed are turned
 | |
| into compile-time errors because the derived class implementation must
 | |
| match the expectations of the ``iterator_facade``.
 | |
| 
 | |
| A common pattern of iterator construction is the adaptation of one
 | |
| iterator to form a new one.  The functionality of an iterator is
 | |
| composed of four orthogonal aspects: traversal, indirection, equality
 | |
| comparison and distance measurement.  Adapting an old iterator to
 | |
| create a new one often saves work because one can reuse one aspect of
 | |
| functionality while redefining the other.  For example, the Standard
 | |
| provides ``reverse_iterator``, which adapts any Bidirectional Iterator
 | |
| by inverting its direction of traversal.  As with plain iterators,
 | |
| iterator adaptors defined outside the Standard have become commonplace
 | |
| in the literature:
 | |
| 
 | |
| * Checked iter[13] adds bounds-checking to an existing iterator.
 | |
| 
 | |
| * The iterators of the View Template Library[14], which adapts
 | |
|   containers, are themselves adaptors over the underlying iterators.
 | |
| 
 | |
| * Smart iterators [5] adapt an iterator's dereferencing behavior by
 | |
|   applying a function object to the object being referenced and
 | |
|   returning the result.
 | |
| 
 | |
| * Custom iterators [4], in which a variety of adaptor types are enumerated.
 | |
| 
 | |
| * Compound iterators [1], which access a slice out of a container of containers.
 | |
| 
 | |
| * Several iterator adaptors from the MTL [12].  The MTL contains a
 | |
|   strided iterator, where each call to ``operator++()`` moves the
 | |
|   iterator ahead by some constant factor, and a scaled iterator, which
 | |
|   multiplies the dereferenced value by some constant.
 | |
| 
 | |
| .. [#concept] We use the term concept to mean a set of requirements
 | |
|    that a type must satisfy to be used with a particular template
 | |
|    parameter.
 | |
| 
 | |
| .. [#mutable] The term mutable iterator refers to iterators over objects that
 | |
|    can be changed by assigning to the dereferenced iterator, while
 | |
|    constant iterator refers to iterators over objects that cannot be
 | |
|    modified.
 | |
| 
 | |
| To fulfill the need for constructing adaptors, we propose the
 | |
| ``iterator_adaptor`` class template.  Instantiations of
 | |
| ``iterator_adaptor`` serve as a base classes for new iterators,
 | |
| providing the default behavior of forwarding all operations to the
 | |
| underlying iterator.  The user can selectively replace these features
 | |
| in the derived iterator class.  This proposal also includes a number
 | |
| of more specialized adaptors, such as the ``transform_iterator`` that
 | |
| applies some user-specified function during the dereference of the
 | |
| iterator.
 | |
| 
 | |
| ========================
 | |
|  Impact on the Standard
 | |
| ========================
 | |
| 
 | |
| This proposal is purely an addition to the C++ standard library.
 | |
| However, note that this proposal relies on the proposal for New
 | |
| Iterator Concepts.
 | |
| 
 | |
| ========
 | |
|  Design
 | |
| ========
 | |
| 
 | |
| Iterator Concepts
 | |
| =================
 | |
| 
 | |
| This proposal is formulated in terms of the new ``iterator concepts``
 | |
| as proposed in n1550_, since user-defined and especially adapted
 | |
| iterators suffer from the well known categorization problems that are
 | |
| inherent to the current iterator categories.
 | |
| 
 | |
| .. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
 | |
| 
 | |
| This proposal does not strictly depend on proposal n1550_, as there
 | |
| is a direct mapping between new and old categories. This proposal
 | |
| could be reformulated using this mapping if n1550_ was not accepted.
 | |
| 
 | |
| Interoperability
 | |
| ================
 | |
| 
 | |
| The question of iterator interoperability is poorly addressed in the
 | |
| current standard.  There are currently two defect reports that are
 | |
| concerned with interoperability issues.
 | |
| 
 | |
| Issue 179_ concerns the fact that mutable container iterator types
 | |
| are only required to be convertible to the corresponding constant
 | |
| iterator types, but objects of these types are not required to
 | |
| interoperate in comparison or subtraction expressions.  This situation
 | |
| is tedious in practice and out of line with the way built in types
 | |
| work.  This proposal implements the proposed resolution to issue
 | |
| 179_, as most standard library implementations do nowadays. In other
 | |
| words, if an iterator type A has an implicit or user defined
 | |
| conversion to an iterator type B, the iterator types are interoperable
 | |
| and the usual set of operators are available.
 | |
| 
 | |
| Issue 280_ concerns the current lack of interoperability between
 | |
| reverse iterator types. The proposed new reverse_iterator template
 | |
| fixes the issues raised in 280. It provides the desired
 | |
| interoperability without introducing unwanted overloads.
 | |
| 
 | |
| .. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
 | |
| .. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
 | |
| 
 | |
| 
 | |
| Iterator Facade
 | |
| ===============
 | |
| 
 | |
| .. include:: iterator_facade_body.rst
 | |
| 
 | |
| Iterator Adaptor
 | |
| ================
 | |
| 
 | |
| .. include:: iterator_adaptor_body.rst
 | |
| 
 | |
| Specialized Adaptors
 | |
| ====================
 | |
| 
 | |
| This proposal also contains several examples of specialized adaptors
 | |
| which were easily implemented using ``iterator_adaptor``:
 | |
| 
 | |
| * ``indirect_iterator``, which iterates over iterators, pointers,
 | |
|   or smart pointers and applies an extra level of dereferencing.
 | |
| 
 | |
| * A new ``reverse_iterator``, which inverts the direction of a Base
 | |
|   iterator's motion, while allowing adapted constant and mutable
 | |
|   iterators to interact in the expected ways (unlike those in most
 | |
|   implementations of C++98).
 | |
| 
 | |
| * ``transform_iterator``, which applies a user-defined function object
 | |
|   to the underlying values when dereferenced.
 | |
| 
 | |
| * ``filter_iterator``, which provides a view of an iterator range in
 | |
|   which some elements of the underlying range are skipped.
 | |
| 
 | |
| .. _counting: 
 | |
| 
 | |
| * ``counting_iterator``, which adapts any incrementable type
 | |
|   (e.g. integers, iterators) so that incrementing/decrementing the
 | |
|   adapted iterator and dereferencing it produces successive values of
 | |
|   the Base type.
 | |
| 
 | |
| * ``function_output_iterator``, which makes it easier to create custom
 | |
|   output iterators.
 | |
| 
 | |
| Based on examples in the Boost library, users have generated many new
 | |
| adaptors, among them a permutation adaptor which applies some
 | |
| permutation to a random access iterator, and a strided adaptor, which
 | |
| adapts a random access iterator by multiplying its unit of motion by a
 | |
| constant factor.  In addition, the Boost Graph Library (BGL) uses
 | |
| iterator adaptors to adapt other graph libraries, such as LEDA [10]
 | |
| and Stanford GraphBase [8], to the BGL interface (which requires C++
 | |
| Standard compliant iterators).
 | |
| 
 | |
| ===============
 | |
|  Proposed Text
 | |
| ===============
 | |
| 
 | |
| 
 | |
| Header ``<iterator_helper>`` synopsis    [lib.iterator.helper.synopsis]
 | |
| =======================================================================
 | |
| 
 | |
| 
 | |
| ::
 | |
| 
 | |
|   struct use_default;
 | |
| 
 | |
|   struct iterator_core_access { /* implementation detail */ };
 | |
|   
 | |
|   template <
 | |
|       class Derived
 | |
|     , class Value
 | |
|     , class CategoryOrTraversal
 | |
|     , class Reference  = Value&
 | |
|     , class Difference = ptrdiff_t
 | |
|   >
 | |
|   class iterator_facade;
 | |
| 
 | |
|   template <
 | |
|       class Derived
 | |
|     , class Base
 | |
|     , class Value      = use_default
 | |
|     , class CategoryOrTraversal  = use_default
 | |
|     , class Reference  = use_default
 | |
|     , class Difference = use_default
 | |
|   >
 | |
|   class iterator_adaptor;
 | |
|   
 | |
|   template <
 | |
|       class Iterator
 | |
|     , class Value = use_default
 | |
|     , class CategoryOrTraversal = use_default
 | |
|     , class Reference = use_default
 | |
|     , class Difference = use_default
 | |
|   >
 | |
|   class indirect_iterator;
 | |
|   
 | |
|   template <class Dereferenceable>
 | |
|   struct pointee;
 | |
| 
 | |
|   template <class Dereferenceable>
 | |
|   struct indirect_reference;
 | |
| 
 | |
|   template <class Iterator>
 | |
|   class reverse_iterator;
 | |
| 
 | |
|   template <
 | |
|       class UnaryFunction
 | |
|     , class Iterator
 | |
|     , class Reference = use_default
 | |
|     , class Value = use_default
 | |
|   >
 | |
|   class transform_iterator;
 | |
| 
 | |
|   template <class Predicate, class Iterator>
 | |
|   class filter_iterator;
 | |
| 
 | |
|   template <
 | |
|       class Incrementable
 | |
|     , class CategoryOrTraversal  = use_default
 | |
|     , class Difference = use_default
 | |
|   >
 | |
|   class counting_iterator;
 | |
| 
 | |
|   template <class UnaryFunction>
 | |
|   class function_output_iterator;
 | |
| 
 | |
| 
 | |
| 
 | |
| Iterator facade [lib.iterator.facade]
 | |
| =====================================
 | |
| 
 | |
| .. include:: iterator_facade_abstract.rst
 | |
| 
 | |
| Class template ``iterator_facade``
 | |
| ----------------------------------
 | |
| 
 | |
| .. include:: iterator_facade_ref.rst
 | |
| 
 | |
| Iterator adaptor [lib.iterator.adaptor]
 | |
| =======================================
 | |
| 
 | |
| .. include:: iterator_adaptor_abstract.rst
 | |
| 
 | |
| Class template ``iterator_adaptor``
 | |
| -----------------------------------
 | |
| 
 | |
| .. include:: iterator_adaptor_ref.rst
 | |
| 
 | |
| 
 | |
| Specialized adaptors [lib.iterator.special.adaptors]
 | |
| ====================================================
 | |
| 
 | |
| 
 | |
| The ``enable_if_convertible<X,Y>::type`` expression used in
 | |
| this section is for exposition purposes. The converting constructors
 | |
| for specialized adaptors should be only be in an overload set provided
 | |
| that an object of type ``X`` is implicitly convertible to an object of
 | |
| type ``Y``.  
 | |
| The signatures involving ``enable_if_convertible`` should behave
 | |
| *as-if* ``enable_if_convertible`` were defined to be::
 | |
| 
 | |
|   template <bool> enable_if_convertible_impl
 | |
|   {};
 | |
| 
 | |
|   template <> enable_if_convertible_impl<true>
 | |
|   { struct type; };
 | |
| 
 | |
|   template<typename From, typename To>
 | |
|   struct enable_if_convertible
 | |
|     : enable_if_convertible_impl<is_convertible<From,To>::value>
 | |
|   {};
 | |
| 
 | |
| If an expression other than the default argument is used to supply
 | |
| the value of a function parameter whose type is written in terms
 | |
| of ``enable_if_convertible``, the program is ill-formed, no
 | |
| diagnostic required.
 | |
| 
 | |
| [*Note:* The ``enable_if_convertible`` approach uses SFINAE to
 | |
| take the constructor out of the overload set when the types are not
 | |
| implicitly convertible.  
 | |
| ]
 | |
| 
 | |
| 
 | |
| Indirect iterator
 | |
| -----------------
 | |
| 
 | |
| .. include:: indirect_iterator_abstract.rst
 | |
| 
 | |
| Class template ``pointee``
 | |
| ....................................
 | |
| 
 | |
| .. include:: pointee_ref.rst
 | |
| 
 | |
| Class template ``indirect_reference``
 | |
| .....................................
 | |
| 
 | |
| .. include:: indirect_reference_ref.rst
 | |
| 
 | |
| Class template ``indirect_iterator``
 | |
| ....................................
 | |
| 
 | |
| .. include:: indirect_iterator_ref.rst
 | |
| 
 | |
| Reverse iterator
 | |
| ----------------
 | |
| 
 | |
| .. include:: reverse_iterator_abstract.rst
 | |
| 
 | |
| Class template ``reverse_iterator``
 | |
| ...................................
 | |
| 
 | |
| .. include:: reverse_iterator_ref.rst
 | |
| 
 | |
| 
 | |
| Transform iterator
 | |
| ------------------
 | |
| 
 | |
| .. include:: transform_iterator_abstract.rst
 | |
| 
 | |
| Class template ``transform_iterator``
 | |
| .....................................
 | |
| 
 | |
| .. include:: transform_iterator_ref.rst
 | |
| 
 | |
| 
 | |
| Filter iterator
 | |
| ---------------
 | |
| 
 | |
| .. include:: filter_iterator_abstract.rst
 | |
| 
 | |
| 
 | |
| Class template ``filter_iterator``
 | |
| ..................................
 | |
| 
 | |
| .. include:: filter_iterator_ref.rst
 | |
| 
 | |
| 
 | |
| Counting iterator
 | |
| -----------------
 | |
| 
 | |
| .. include:: counting_iterator_abstract.rst
 | |
| 
 | |
| Class template ``counting_iterator``
 | |
| ....................................
 | |
| 
 | |
| .. include:: counting_iterator_ref.rst
 | |
| 
 | |
| 
 | |
| Function output iterator
 | |
| ------------------------
 | |
| 
 | |
| .. include:: func_output_iter_abstract.rst
 | |
| 
 | |
| Class template ``function_output_iterator``
 | |
| ...........................................
 | |
| 
 | |
| .. include:: func_output_iter_ref.rst
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| .. LocalWords:  Abrahams Siek Witt istream ostream iter MTL strided interoperate
 | |
|    LocalWords:  CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
 | |
|    LocalWords:  GraphBase struct ptrdiff UnaryFunction const int typename bool pp
 | |
|    LocalWords:  lhs rhs SFINAE markup iff tmp OtherDerived OtherIterator DWA foo
 | |
|    LocalWords:  dereferenceable subobject AdaptableUnaryFunction impl pre ifdef'd
 | |
|    LocalWords:  OtherIncrementable Coplien
 |