UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

855 lines (837 loc) 76.9 kB
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" /> <title>Iterator Facade</title> <meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" /> <meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" /> <meta name="date" content="2006-09-11" /> <meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003." /> <link rel="stylesheet" href="../../../rst.css" type="text/css" /> </head> <body> <div class="document" id="iterator-facade"> <h1 class="title">Iterator Facade</h1> <table class="docinfo" frame="void" rules="none"> <col class="docinfo-name" /> <col class="docinfo-content" /> <tbody valign="top"> <tr><th class="docinfo-name">Author:</th> <td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr> <tr><th class="docinfo-name">Contact:</th> <td><a class="first reference external" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference external" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference external" href="mailto:witt&#64;ive.uni-hannover.de">witt&#64;ive.uni-hannover.de</a></td></tr> <tr><th class="docinfo-name">Organization:</th> <td><a class="first reference external" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference external" href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <a class="last reference external" href="http://www.ive.uni-hannover.de">Institute for Transport Railway Operation and Construction</a></td></tr> <tr><th class="docinfo-name">Date:</th> <td>2006-09-11</td></tr> <tr><th class="docinfo-name">Copyright:</th> <td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.</td></tr> </tbody> </table> <!-- 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) --> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">abstract:</th><td class="field-body"><!-- Copyright David Abrahams 2006. 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) --> <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> is a base class template that implements the interface of standard iterators in terms of a few core functions and associated types, to be supplied by a derived iterator class.</td> </tr> </tbody> </table> <div class="contents topic" id="table-of-contents"> <p class="topic-title first">Table of Contents</p> <ul class="simple"> <li><a class="reference internal" href="#overview" id="id23">Overview</a><ul> <li><a class="reference internal" href="#usage" id="id24">Usage</a></li> <li><a class="reference internal" href="#iterator-core-access" id="id25">Iterator Core Access</a></li> <li><a class="reference internal" href="#operator" id="id26"><tt class="docutils literal"><span class="pre">operator[]</span></tt></a></li> <li><a class="reference internal" href="#id2" id="id27"><tt class="docutils literal"><span class="pre">operator-&gt;</span></tt></a></li> </ul> </li> <li><a class="reference internal" href="#reference" id="id28">Reference</a><ul> <li><a class="reference internal" href="#iterator-facade-requirements" id="id29"><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> Requirements</a></li> <li><a class="reference internal" href="#iterator-facade-operations" id="id30"><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> operations</a></li> </ul> </li> <li><a class="reference internal" href="#tutorial-example" id="id31">Tutorial Example</a><ul> <li><a class="reference internal" href="#the-problem" id="id32">The Problem</a></li> <li><a class="reference internal" href="#a-basic-iterator-using-iterator-facade" id="id33">A Basic Iterator Using <tt class="docutils literal"><span class="pre">iterator_facade</span></tt></a><ul> <li><a class="reference internal" href="#template-arguments-for-iterator-facade" id="id34">Template Arguments for <tt class="docutils literal"><span class="pre">iterator_facade</span></tt></a><ul> <li><a class="reference internal" href="#derived" id="id35"><tt class="docutils literal"><span class="pre">Derived</span></tt></a></li> <li><a class="reference internal" href="#value" id="id36"><tt class="docutils literal"><span class="pre">Value</span></tt></a></li> <li><a class="reference internal" href="#categoryortraversal" id="id37"><tt class="docutils literal"><span class="pre">CategoryOrTraversal</span></tt></a></li> <li><a class="reference internal" href="#id12" id="id38"><tt class="docutils literal"><span class="pre">Reference</span></tt></a></li> <li><a class="reference internal" href="#difference" id="id39"><tt class="docutils literal"><span class="pre">Difference</span></tt></a></li> </ul> </li> <li><a class="reference internal" href="#constructors-and-data-members" id="id40">Constructors and Data Members</a></li> <li><a class="reference internal" href="#implementing-the-core-operations" id="id41">Implementing the Core Operations</a></li> </ul> </li> <li><a class="reference internal" href="#a-constant-node-iterator" id="id42">A constant <tt class="docutils literal"><span class="pre">node_iterator</span></tt></a></li> <li><a class="reference internal" href="#interoperability" id="id43">Interoperability</a></li> <li><a class="reference internal" href="#telling-the-truth" id="id44">Telling the Truth</a></li> <li><a class="reference internal" href="#wrap-up" id="id45">Wrap Up</a></li> </ul> </li> </ul> </div> <div class="section" id="overview"> <h1><a class="toc-backref" href="#id23">Overview</a></h1> <!-- 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) --> <!-- Version 1.1 of this ReStructuredText document corresponds to n1530_, the paper accepted by the LWG for TR1. --> <!-- Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. --> <p>While the iterator interface is rich, there is a core subset of the interface that is necessary for all the functionality. We have identified the following core behaviors for iterators:</p> <ul class="simple"> <li>dereferencing</li> <li>incrementing</li> <li>decrementing</li> <li>equality comparison</li> <li>random-access motion</li> <li>distance measurement</li> </ul> <p>In addition to the behaviors listed above, the core interface elements include the associated types exposed through iterator traits: <tt class="docutils literal"><span class="pre">value_type</span></tt>, <tt class="docutils literal"><span class="pre">reference</span></tt>, <tt class="docutils literal"><span class="pre">difference_type</span></tt>, and <tt class="docutils literal"><span class="pre">iterator_category</span></tt>.</p> <p>Iterator facade uses the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id1">[Cop95]</a> so that the user can specify the behavior of <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> in a derived class. Former designs used policy objects to specify the behavior, but that approach was discarded for several reasons:</p> <blockquote> <ol class="arabic simple"> <li>the creation and eventual copying of the policy object may create overhead that can be avoided with the current approach.</li> <li>The policy object approach does not allow for custom constructors on the created iterator types, an essential feature if <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> should be used in other library implementations.</li> <li>Without the use of CRTP, the standard requirement that an iterator's <tt class="docutils literal"><span class="pre">operator++</span></tt> returns the iterator type itself would mean that all iterators built with the library would have to be specializations of <tt class="docutils literal"><span class="pre">iterator_facade&lt;...&gt;</span></tt>, rather than something more descriptive like <tt class="docutils literal"><span class="pre">indirect_iterator&lt;T*&gt;</span></tt>. Cumbersome type generator metafunctions would be needed to build new parameterized iterators, and a separate <tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt> layer would be impossible.</li> </ol> </blockquote> <div class="section" id="usage"> <h2><a class="toc-backref" href="#id24">Usage</a></h2> <p>The user of <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> derives his iterator class from a specialization of <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> and passes the derived iterator class as <tt class="docutils literal"><span class="pre">iterator_facade</span></tt>'s first template parameter. The order of the other template parameters have been carefully chosen to take advantage of useful defaults. For example, when defining a constant lvalue iterator, the user can pass a const-qualified version of the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt> as <tt class="docutils literal"><span class="pre">iterator_facade</span></tt>'s <tt class="docutils literal"><span class="pre">Value</span></tt> parameter and omit the <tt class="docutils literal"><span class="pre">Reference</span></tt> parameter which follows.</p> <p>The derived iterator class must define member functions implementing the iterator's core behaviors. The following table describes expressions which are required to be valid depending on the category of the derived iterator type. These member functions are described briefly below and in more detail in the iterator facade requirements.</p> <blockquote> <table border="1" class="docutils"> <colgroup> <col width="44%" /> <col width="56%" /> </colgroup> <thead valign="bottom"> <tr><th class="head">Expression</th> <th class="head">Effects</th> </tr> </thead> <tbody valign="top"> <tr><td><tt class="docutils literal"><span class="pre">i.dereference()</span></tt></td> <td>Access the value referred to</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">i.equal(j)</span></tt></td> <td>Compare for equality with <tt class="docutils literal"><span class="pre">j</span></tt></td> </tr> <tr><td><tt class="docutils literal"><span class="pre">i.increment()</span></tt></td> <td>Advance by one position</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">i.decrement()</span></tt></td> <td>Retreat by one position</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">i.advance(n)</span></tt></td> <td>Advance by <tt class="docutils literal"><span class="pre">n</span></tt> positions</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">i.distance_to(j)</span></tt></td> <td>Measure the distance to <tt class="docutils literal"><span class="pre">j</span></tt></td> </tr> </tbody> </table> </blockquote> <!-- Should we add a comment that a zero overhead implementation of iterator_facade is possible with proper inlining? --> <p>In addition to implementing the core interface functions, an iterator derived from <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> typically defines several constructors. To model any of the standard iterator concepts, the iterator must at least have a copy constructor. Also, if the iterator type <tt class="docutils literal"><span class="pre">X</span></tt> is meant to be automatically interoperate with another iterator type <tt class="docutils literal"><span class="pre">Y</span></tt> (as with constant and mutable iterators) then there must be an implicit conversion from <tt class="docutils literal"><span class="pre">X</span></tt> to <tt class="docutils literal"><span class="pre">Y</span></tt> or from <tt class="docutils literal"><span class="pre">Y</span></tt> to <tt class="docutils literal"><span class="pre">X</span></tt> (but not both), typically implemented as a conversion constructor. Finally, if the iterator is to model Forward Traversal Iterator or a more-refined iterator concept, a default constructor is required.</p> </div> <div class="section" id="iterator-core-access"> <h2><a class="toc-backref" href="#id25">Iterator Core Access</a></h2> <p><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> and the operator implementations need to be able to access the core member functions in the derived class. Making the core member functions public would expose an implementation detail to the user. The design used here ensures that implementation details do not appear in the public interface of the derived iterator type.</p> <p>Preventing direct access to the core member functions has two advantages. First, there is no possibility for the user to accidently use a member function of the iterator when a member of the value_type was intended. This has been an issue with smart pointer implementations in the past. The second and main advantage is that library implementers can freely exchange a hand-rolled iterator implementation for one based on <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> without fear of breaking code that was accessing the public core member functions directly.</p> <p>In a naive implementation, keeping the derived class' core member functions private would require it to grant friendship to <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> and each of the seven operators. In order to reduce the burden of limiting access, <tt class="docutils literal"><span class="pre">iterator_core_access</span></tt> is provided, a class that acts as a gateway to the core member functions in the derived iterator class. The author of the derived class only needs to grant friendship to <tt class="docutils literal"><span class="pre">iterator_core_access</span></tt> to make his core member functions available to the library.</p> <!-- This is no long uptodate -thw --> <!-- Yes it is; I made sure of it! -DWA --> <p><tt class="docutils literal"><span class="pre">iterator_core_access</span></tt> will be typically implemented as an empty class containing only private static member functions which invoke the iterator core member functions. There is, however, no need to standardize the gateway protocol. Note that even if <tt class="docutils literal"><span class="pre">iterator_core_access</span></tt> used public member functions it would not open a safety loophole, as every core member function preserves the invariants of the iterator.</p> </div> <div class="section" id="operator"> <h2><a class="toc-backref" href="#id26"><tt class="docutils literal"><span class="pre">operator[]</span></tt></a></h2> <p>The indexing operator for a generalized iterator presents special challenges. A random access iterator's <tt class="docutils literal"><span class="pre">operator[]</span></tt> is only required to return something convertible to its <tt class="docutils literal"><span class="pre">value_type</span></tt>. Requiring that it return an lvalue would rule out currently-legal random-access iterators which hold the referenced value in a data member (e.g. <a class="reference external" href="counting_iterator.html"><tt class="docutils literal"><span class="pre">counting_iterator</span></tt></a>), because <tt class="docutils literal"><span class="pre">*(p+n)</span></tt> is a reference into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when <tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p> <p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and adopted by proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach will work properly for any random-access iterator regardless of the other details of its implementation. A user who knows more about the implementation of her iterator is free to implement an <tt class="docutils literal"><span class="pre">operator[]</span></tt> that returns an lvalue in the derived iterator class; it will hide the one supplied by <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> from clients of her iterator.</p> </div> <div class="section" id="id2"> <span id="operator-arrow"></span><h2><a class="toc-backref" href="#id27"><tt class="docutils literal"><span class="pre">operator-&gt;</span></tt></a></h2> <p>The <tt class="docutils literal"><span class="pre">reference</span></tt> type of a readable iterator (and today's input iterator) need not in fact be a reference, so long as it is convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>. When the <tt class="docutils literal"><span class="pre">value_type</span></tt> is a class, however, it must still be possible to access members through <tt class="docutils literal"><span class="pre">operator-&gt;</span></tt>. Therefore, an iterator whose <tt class="docutils literal"><span class="pre">reference</span></tt> type is not in fact a reference must return a proxy containing a copy of the referenced value from its <tt class="docutils literal"><span class="pre">operator-&gt;</span></tt>.</p> <p>The return types for <tt class="docutils literal"><span class="pre">iterator_facade</span></tt>'s <tt class="docutils literal"><span class="pre">operator-&gt;</span></tt> and <tt class="docutils literal"><span class="pre">operator[]</span></tt> are not explicitly specified. Instead, those types are described in terms of a set of requirements, which must be satisfied by the <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implementation.</p> <table class="docutils citation" frame="void" id="cop95" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label">[Cop95]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id10">2</a>)</em> [Coplien, 1995] Coplien, J., Curiously Recurring Template Patterns, C++ Report, February 1995, pp. 24-27.</td></tr> </tbody> </table> </div> </div> <div class="section" id="reference"> <h1><a class="toc-backref" href="#id28">Reference</a></h1> <!-- 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) --> <!-- Version 1.3 of this ReStructuredText document corresponds to n1530_, the paper accepted by the LWG for TR1. --> <!-- Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. --> <pre class="literal-block"> template &lt; class Derived , class Value , class CategoryOrTraversal , class Reference = Value&amp; , class Difference = ptrdiff_t &gt; class iterator_facade { public: typedef remove_const&lt;Value&gt;::type value_type; typedef Reference reference; typedef Value* pointer; typedef Difference difference_type; typedef /* see <a class="reference internal" href="#iterator-category">below</a> */ iterator_category; reference operator*() const; /* see <a class="reference internal" href="#operator-arrow">below</a> */ operator-&gt;() const; /* see <a class="reference internal" href="#brackets">below</a> */ operator[](difference_type n) const; Derived&amp; operator++(); Derived operator++(int); Derived&amp; operator--(); Derived operator--(int); Derived&amp; operator+=(difference_type n); Derived&amp; operator-=(difference_type n); Derived operator-(difference_type n) const; protected: typedef iterator_facade iterator_facade_; }; // Comparison operators template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type // exposition operator ==(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator !=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &lt;(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &lt;=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &gt;(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &gt;=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); // Iterator difference template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; /* see <a class="reference internal" href="#minus">below</a> */ operator-(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); // Iterator addition template &lt;class Dr, class V, class TC, class R, class D&gt; Derived operator+ (iterator_facade&lt;Dr,V,TC,R,D&gt; const&amp;, typename Derived::difference_type n); template &lt;class Dr, class V, class TC, class R, class D&gt; Derived operator+ (typename Derived::difference_type n, iterator_facade&lt;Dr,V,TC,R,D&gt; const&amp;); </pre> <p id="iterator-category">The <tt class="docutils literal"><span class="pre">iterator_category</span></tt> member of <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> is</p> <pre class="literal-block"> <em>iterator-category</em>(CategoryOrTraversal, value_type, reference) </pre> <p>where <em>iterator-category</em> is defined as follows:</p> <pre class="literal-block" id="id7"> <em>iterator-category</em>(C,R,V) := if (C is convertible to std::input_iterator_tag || C is convertible to std::output_iterator_tag ) return C else if (C is not convertible to incrementable_traversal_tag) <em>the program is ill-formed</em> else return a type X satisfying the following two constraints: 1. X is convertible to X1, and not to any more-derived type, where X1 is defined by: if (R is a reference type &amp;&amp; C is convertible to forward_traversal_tag) { if (C is convertible to random_access_traversal_tag) X1 = random_access_iterator_tag else if (C is convertible to bidirectional_traversal_tag) X1 = bidirectional_iterator_tag else X1 = forward_iterator_tag } else { if (C is convertible to single_pass_traversal_tag &amp;&amp; R is convertible to V) X1 = input_iterator_tag else X1 = C } 2. <a class="reference external" href="new-iter-concepts.html#category-to-traversal"><em>category-to-traversal</em></a>(X) is convertible to the most derived traversal tag type to which X is also convertible, and not to any more-derived traversal tag type. </pre> <p>[Note: the intention is to allow <tt class="docutils literal"><span class="pre">iterator_category</span></tt> to be one of the five original category tags when convertibility to one of the traversal tags would add no information]</p> <!-- Copyright David Abrahams 2004. Use, modification and distribution is --> <!-- subject to 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) --> <p>The <tt class="docutils literal"><span class="pre">enable_if_interoperable</span></tt> template used above is for exposition purposes. The member operators should only be in an overload set provided the derived types <tt class="docutils literal"><span class="pre">Dr1</span></tt> and <tt class="docutils literal"><span class="pre">Dr2</span></tt> are interoperable, meaning that at least one of the types is convertible to the other. The <tt class="docutils literal"><span class="pre">enable_if_interoperable</span></tt> approach uses SFINAE to take the operators out of the overload set when the types are not interoperable. The operators should behave <em>as-if</em> <tt class="docutils literal"><span class="pre">enable_if_interoperable</span></tt> were defined to be:</p> <pre class="literal-block"> template &lt;bool, typename&gt; enable_if_interoperable_impl {}; template &lt;typename T&gt; enable_if_interoperable_impl&lt;true,T&gt; { typedef T type; }; template&lt;typename Dr1, typename Dr2, typename T&gt; struct enable_if_interoperable : enable_if_interoperable_impl&lt; is_convertible&lt;Dr1,Dr2&gt;::value || is_convertible&lt;Dr2,Dr1&gt;::value , T &gt; {}; </pre> <div class="section" id="iterator-facade-requirements"> <h2><a class="toc-backref" href="#id29"><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> Requirements</a></h2> <p>The following table describes the typical valid expressions on <tt class="docutils literal"><span class="pre">iterator_facade</span></tt>'s <tt class="docutils literal"><span class="pre">Derived</span></tt> parameter, depending on the iterator concept(s) it will model. The operations in the first column must be made accessible to member functions of class <tt class="docutils literal"><span class="pre">iterator_core_access</span></tt>. In addition, <tt class="docutils literal"><span class="pre">static_cast&lt;Derived*&gt;(iterator_facade*)</span></tt> shall be well-formed.</p> <p>In the table below, <tt class="docutils literal"><span class="pre">F</span></tt> is <tt class="docutils literal"><span class="pre">iterator_facade&lt;X,V,C,R,D&gt;</span></tt>, <tt class="docutils literal"><span class="pre">a</span></tt> is an object of type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">b</span></tt> and <tt class="docutils literal"><span class="pre">c</span></tt> are objects of type <tt class="docutils literal"><span class="pre">const</span> <span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">n</span></tt> is an object of <tt class="docutils literal"><span class="pre">F::difference_type</span></tt>, <tt class="docutils literal"><span class="pre">y</span></tt> is a constant object of a single pass iterator type interoperable with <tt class="docutils literal"><span class="pre">X</span></tt>, and <tt class="docutils literal"><span class="pre">z</span></tt> is a constant object of a random access traversal iterator type interoperable with <tt class="docutils literal"><span class="pre">X</span></tt>.</p> <div class="topic" id="core-operations"> <p class="topic-title first"><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> Core Operations</p> <table border="1" class="docutils"> <colgroup> <col width="21%" /> <col width="23%" /> <col width="27%" /> <col width="29%" /> </colgroup> <thead valign="bottom"> <tr><th class="head">Expression</th> <th class="head">Return Type</th> <th class="head">Assertion/Note</th> <th class="head">Used to implement Iterator Concept(s)</th> </tr> </thead> <tbody valign="top"> <tr><td><tt class="docutils literal"><span class="pre">c.dereference()</span></tt></td> <td><tt class="docutils literal"><span class="pre">F::reference</span></tt></td> <td>&nbsp;</td> <td>Readable Iterator, Writable Iterator</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">c.equal(y)</span></tt></td> <td>convertible to bool</td> <td>true iff <tt class="docutils literal"><span class="pre">c</span></tt> and <tt class="docutils literal"><span class="pre">y</span></tt> refer to the same position.</td> <td>Single Pass Iterator</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">a.increment()</span></tt></td> <td>unused</td> <td>&nbsp;</td> <td>Incrementable Iterator</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">a.decrement()</span></tt></td> <td>unused</td> <td>&nbsp;</td> <td>Bidirectional Traversal Iterator</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">a.advance(n)</span></tt></td> <td>unused</td> <td>&nbsp;</td> <td>Random Access Traversal Iterator</td> </tr> <tr><td><tt class="docutils literal"><span class="pre">c.distance_to(z)</span></tt></td> <td>convertible to <tt class="docutils literal"><span class="pre">F::difference_type</span></tt></td> <td>equivalent to <tt class="docutils literal"><span class="pre">distance(c,</span> <span class="pre">X(z))</span></tt>.</td> <td>Random Access Traversal Iterator</td> </tr> </tbody> </table> </div> </div> <div class="section" id="iterator-facade-operations"> <h2><a class="toc-backref" href="#id30"><tt class="docutils literal"><span class="pre">iterator_facade</span></tt> operations</a></h2> <p>The operations in this section are described in terms of operations on the core interface of <tt class="docutils literal"><span class="pre">Derived</span></tt> which may be inaccessible (i.e. private). The implementation should access these operations through member functions of class <tt class="docutils literal"><span class="pre">iterator_core_access</span></tt>.</p> <p><tt class="docutils literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="docutils literal"><span class="pre">static_cast&lt;Derived</span> <span class="pre">const*&gt;(this)-&gt;dereference()</span></tt></td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">operator-&gt;()</span> <span class="pre">const;</span></tt> (see <a class="reference internal" href="#operator-arrow">below</a>)</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">If <tt class="docutils literal"><span class="pre">reference</span></tt> is a reference type, an object of type <tt class="docutils literal"><span class="pre">pointer</span></tt> equal to:</p> <pre class="literal-block"> &amp;static_cast&lt;Derived const*&gt;(this)-&gt;dereference() </pre> <p class="last">Otherwise returns an object of unspecified type such that, <tt class="docutils literal"><span class="pre">(*static_cast&lt;Derived</span> <span class="pre">const*&gt;(this))-&gt;m</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">(w</span> <span class="pre">=</span> <span class="pre">**static_cast&lt;Derived</span> <span class="pre">const*&gt;(this),</span> <span class="pre">w.m)</span></tt> for some temporary object <tt class="docutils literal"><span class="pre">w</span></tt> of type <tt class="docutils literal"><span class="pre">value_type</span></tt>.</p> </td> </tr> </tbody> </table> <p id="brackets"><em>unspecified</em> <tt class="docutils literal"><span class="pre">operator[](difference_type</span> <span class="pre">n)</span> <span class="pre">const;</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body">an object convertible to <tt class="docutils literal"><span class="pre">value_type</span></tt>. For constant objects <tt class="docutils literal"><span class="pre">v</span></tt> of type <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">n</span></tt> of type <tt class="docutils literal"><span class="pre">difference_type</span></tt>, <tt class="docutils literal"><span class="pre">(*this)[n]</span> <span class="pre">=</span> <span class="pre">v</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">*(*this</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">v</span></tt>, and <tt class="docutils literal"><span class="pre">static_cast&lt;value_type</span> <span class="pre">const&amp;&gt;((*this)[n])</span></tt> is equivalent to <tt class="docutils literal"><span class="pre">static_cast&lt;value_type</span> <span class="pre">const&amp;&gt;(*(*this</span> <span class="pre">+</span> <span class="pre">n))</span></tt></td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived&amp;</span> <span class="pre">operator++();</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> static_cast&lt;Derived*&gt;(this)-&gt;increment(); return *static_cast&lt;Derived*&gt;(this); </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived</span> <span class="pre">operator++(int);</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> Derived tmp(static_cast&lt;Derived const*&gt;(this)); ++*this; return tmp; </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived&amp;</span> <span class="pre">operator--();</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> static_cast&lt;Derived*&gt;(this)-&gt;decrement(); return *static_cast&lt;Derived*&gt;(this); </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived</span> <span class="pre">operator--(int);</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> Derived tmp(static_cast&lt;Derived const*&gt;(this)); --*this; return tmp; </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived&amp;</span> <span class="pre">operator+=(difference_type</span> <span class="pre">n);</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> static_cast&lt;Derived*&gt;(this)-&gt;advance(n); return *static_cast&lt;Derived*&gt;(this); </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived&amp;</span> <span class="pre">operator-=(difference_type</span> <span class="pre">n);</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> static_cast&lt;Derived*&gt;(this)-&gt;advance(-n); return *static_cast&lt;Derived*&gt;(this); </pre> </td> </tr> </tbody> </table> <p><tt class="docutils literal"><span class="pre">Derived</span> <span class="pre">operator-(difference_type</span> <span class="pre">n)</span> <span class="pre">const;</span></tt></p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> Derived tmp(static_cast&lt;Derived const*&gt;(this)); return tmp -= n; </pre> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr, class V, class TC, class R, class D&gt; Derived operator+ (iterator_facade&lt;Dr,V,TC,R,D&gt; const&amp;, typename Derived::difference_type n); template &lt;class Dr, class V, class TC, class R, class D&gt; Derived operator+ (typename Derived::difference_type n, iterator_facade&lt;Dr,V,TC,R,D&gt; const&amp;); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block"> Derived tmp(static_cast&lt;Derived const*&gt;(this)); return tmp += n; </pre> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator ==(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr1</span> <span class="pre">const&amp;)lhs).equal((Dr2</span> <span class="pre">const&amp;)rhs)</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).equal((Dr1</span> <span class="pre">const&amp;)lhs)</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator !=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">!((Dr1</span> <span class="pre">const&amp;)lhs).equal((Dr2</span> <span class="pre">const&amp;)rhs)</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">!((Dr2</span> <span class="pre">const&amp;)rhs).equal((Dr1</span> <span class="pre">const&amp;)lhs)</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &lt;(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr1</span> <span class="pre">const&amp;)lhs).distance_to((Dr2</span> <span class="pre">const&amp;)rhs)</span> <span class="pre">&lt;</span> <span class="pre">0</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).distance_to((Dr1</span> <span class="pre">const&amp;)lhs)</span> <span class="pre">&gt;</span> <span class="pre">0</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &lt;=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr1</span> <span class="pre">const&amp;)lhs).distance_to((Dr2</span> <span class="pre">const&amp;)rhs)</span> <span class="pre">&lt;=</span> <span class="pre">0</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).distance_to((Dr1</span> <span class="pre">const&amp;)lhs)</span> <span class="pre">&gt;=</span> <span class="pre">0</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &gt;(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr1</span> <span class="pre">const&amp;)lhs).distance_to((Dr2</span> <span class="pre">const&amp;)rhs)</span> <span class="pre">&gt;</span> <span class="pre">0</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).distance_to((Dr1</span> <span class="pre">const&amp;)lhs)</span> <span class="pre">&lt;</span> <span class="pre">0</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,bool&gt;::type operator &gt;=(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr1</span> <span class="pre">const&amp;)lhs).distance_to((Dr2</span> <span class="pre">const&amp;)rhs)</span> <span class="pre">&gt;=</span> <span class="pre">0</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).distance_to((Dr1</span> <span class="pre">const&amp;)lhs)</span> <span class="pre">&lt;=</span> <span class="pre">0</span></tt>.</p> </dd> </dl> </td> </tr> </tbody> </table> <pre class="literal-block" id="minus"> template &lt;class Dr1, class V1, class TC1, class R1, class D1, class Dr2, class V2, class TC2, class R2, class D2&gt; typename enable_if_interoperable&lt;Dr1,Dr2,difference&gt;::type operator -(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs, iterator_facade&lt;Dr2,V2,TC2,R2,D2&gt; const&amp; rhs); </pre> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Return Type:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <blockquote> <dl class="docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">difference</span></tt> shall be <tt class="docutils literal"><span class="pre">iterator_traits&lt;Dr1&gt;::difference_type</span></tt>.</p> </dd> <dt>Otherwise</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">difference</span></tt> shall be <tt class="docutils literal"><span class="pre">iterator_traits&lt;Dr2&gt;::difference_type</span></tt></p> </dd> </dl> </blockquote> </td> </tr> <tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">if <tt class="docutils literal"><span class="pre">is_convertible&lt;Dr2,Dr1&gt;::value</span></tt></p> <dl class="last docutils"> <dt>then</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">-((Dr1</span> <span class="pre">const&amp;)lhs).distance_to((Dr2</span> <span class="pre">const&amp;)rhs)</span></tt>.</p> </dd> <dt>Otherwise,</dt> <dd><p class="first last"><tt class="docutils literal"><span class="pre">((Dr2</span> <span class="pre">const&amp;)rhs).distance_to((Dr1</span> <span class="pre">const&amp;)lhs)</span></tt>.</p> </dd> </dl> <