mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -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
 |