facade-and-adaptor.rst

来自「Boost provides free peer-reviewed portab」· RST 代码 · 共 439 行

RST
439
字号
.. 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: 2006-09-11 18:27:29 -0400 (Mon, 11 Sep 2006) $: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://anubis.dkuug.dk/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. Theiterator is the central abstraction of the algorithms of the StandardLibrary, allowing algorithms to be re-used in in a wide variety ofcontexts.  The C++ Standard Library contains a wide variety of usefuliterators. Every one of the standard containers comes with constantand mutable iterators [#mutable]_, and also reverse versions of thosesame 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, obviousand useful iterators are missing, and creating new iterator types isstill a common task for C++ programmers.  The literature documentsseveral of these, for example line_iterator [3] and Constant_iterator[9].  The iterator abstraction is so powerful that we expectprogrammers will always need to invent new iterator types.Although it is easy to create iterators that *almost* conform to thestandard, the iterator requirements contain subtleties which can makecreating an iterator which *actually* conforms quite difficult.Further, the iterator interface is rich, containing many operatorsthat are technically redundant and tedious to implement.  To automatethe repetitive work of constructing iterators, we propose``iterator_facade``, an iterator base class template which providesthe rich interface of standard iterators and delegates itsimplementation to member functions of the derived class.  In additionto 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 turnedinto compile-time errors because the derived class implementation mustmatch the expectations of the ``iterator_facade``.A common pattern of iterator construction is the adaptation of oneiterator to form a new one.  The functionality of an iterator iscomposed of four orthogonal aspects: traversal, indirection, equalitycomparison and distance measurement.  Adapting an old iterator tocreate a new one often saves work because one can reuse one aspect offunctionality while redefining the other.  For example, the Standardprovides ``reverse_iterator``, which adapts any Bidirectional Iteratorby inverting its direction of traversal.  As with plain iterators,iterator adaptors defined outside the Standard have become commonplacein 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 theunderlying iterator.  The user can selectively replace these featuresin the derived iterator class.  This proposal also includes a numberof more specialized adaptors, such as the ``transform_iterator`` thatapplies some user-specified function during the dereference of theiterator.======================== 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 NewIterator Concepts.======== Design========Iterator Concepts=================This proposal is formulated in terms of the new ``iterator concepts``as proposed in n1550_, since user-defined and especially adaptediterators suffer from the well known categorization problems that areinherent to the current iterator categories... _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.htmlThis proposal does not strictly depend on proposal n1550_, as thereis a direct mapping between new and old categories. This proposalcould be reformulated using this mapping if n1550_ was not accepted.Interoperability================The question of iterator interoperability is poorly addressed in thecurrent standard.  There are currently two defect reports that areconcerned with interoperability issues.Issue 179_ concerns the fact that mutable container iterator typesare only required to be convertible to the corresponding constantiterator types, but objects of these types are not required tointeroperate in comparison or subtraction expressions.  This situationis tedious in practice and out of line with the way built in typeswork.  This proposal implements the proposed resolution to issue179_, as most standard library implementations do nowadays. In otherwords, if an iterator type A has an implicit or user definedconversion to an iterator type B, the iterator types are interoperableand the usual set of operators are available.Issue 280_ concerns the current lack of interoperability betweenreverse iterator types. The proposed new reverse_iterator templatefixes the issues raised in 280. It provides the desiredinteroperability without introducing unwanted overloads... _179: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179.. _280: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280Iterator Facade===============.. include:: iterator_facade_body.rstIterator Adaptor================.. include:: iterator_adaptor_body.rstSpecialized Adaptors====================This proposal also contains several examples of specialized adaptorswhich 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 newadaptors, among them a permutation adaptor which applies somepermutation to a random access iterator, and a strided adaptor, whichadapts a random access iterator by multiplying its unit of motion by aconstant factor.  In addition, the Boost Graph Library (BGL) usesiterator 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.rstClass template ``iterator_facade``----------------------------------.. include:: iterator_facade_ref.rstIterator adaptor [lib.iterator.adaptor]=======================================.. include:: iterator_adaptor_abstract.rstClass template ``iterator_adaptor``-----------------------------------.. include:: iterator_adaptor_ref.rstSpecialized adaptors [lib.iterator.special.adaptors]====================================================The ``enable_if_convertible<X,Y>::type`` expression used inthis section is for exposition purposes. The converting constructorsfor specialized adaptors should be only be in an overload set providedthat an object of type ``X`` is implicitly convertible to an object oftype ``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 supplythe value of a function parameter whose type is written in termsof ``enable_if_convertible``, the program is ill-formed, nodiagnostic required.[*Note:* The ``enable_if_convertible`` approach uses SFINAE totake the constructor out of the overload set when the types are notimplicitly convertible.  ]Indirect iterator-----------------.. include:: indirect_iterator_abstract.rstClass template ``pointee``...................................... include:: pointee_ref.rstClass template ``indirect_reference``....................................... include:: indirect_reference_ref.rstClass template ``indirect_iterator``...................................... include:: indirect_iterator_ref.rstReverse iterator----------------.. include:: reverse_iterator_abstract.rstClass template ``reverse_iterator``..................................... include:: reverse_iterator_ref.rstTransform iterator------------------.. include:: transform_iterator_abstract.rstClass template ``transform_iterator``....................................... include:: transform_iterator_ref.rstFilter iterator---------------.. include:: filter_iterator_abstract.rstClass template ``filter_iterator``.................................... include:: filter_iterator_ref.rstCounting iterator-----------------.. include:: counting_iterator_abstract.rstClass template ``counting_iterator``...................................... include:: counting_iterator_ref.rstFunction output iterator------------------------.. include:: func_output_iter_abstract.rstClass 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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?