    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Pairing Off Iterators</title>
        <link>https://members.accu.org/index.php/journals/381</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #51 - Oct 2002 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c194/">51</a>
                    (8)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c194-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c194+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Pairing Off Iterators</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 October 2002 22:58:12 +01:00 or Wed, 02 October 2002 22:58:12 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id=
"d0e18"></a>Introduction</h2>
</div>
<p>Recently, a colleague approached me with an interesting problem;
he had two containers with corresponding elements, so the n-th
entry of container A was related to the n-th entry of container B,
and he needed to sort these containers so the elements of A were
&quot;in order&quot;, without losing the correspondence property, as in the
figure below:</p>
<div class="c2"><img src=
"/var/uploads/journals/resources/williams-sorting_pairs_of_sequences.gif" align=
"middle"></div>
<p>There are several solutions to this, each of which has its
merits and disadvantages, such as:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Create a third container holding either the numeric index, or
some form of iterator or pointer into the containers. This
container can then be sorted using a special comparison function
that references the original containers. Code that processes the
data can then either use the new container to index into the
originals, or the original containers can be re-shuffled to match
the order specified in the new container.</p>
</li>
<li>
<p>Copy the values into a container of pairs and sort that,
possibly using the self-sorting property of the Standard
Associative Containers, if appropriate</p>
</li>
</ol>
</div>
<p>It was a third solution that really interested me - what my
colleague conceptually had was a container of pairs of values, even
if it was physically stored as a pair of containers of values; why
then couldn't we treat the data as a container of pairs? This would
allow sorting in place, and intuitive access to the data. The
answer is: we can - just write an iterator adaptor that iterates
through both containers simultaneously, and returns a pair when
dereferenced; the pair of containers can thus be viewed as a
sequence of pairs of values. The rest of this article covers the
complexities hidden in that &quot;just&quot;.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e35" id="d0e35"></a>Iterator
Categories</h2>
</div>
<p>To cover the original problem (sorting), we need only worry
about random access iterators, since std::sort requires random
access. However, the problem had me hooked, and I wanted a general
solution, with maximum flexibility, and all the complexities that
involved.</p>
<p>For maximum flexibility, we want our adapted iterator to be as
capable as possible, but no more - we cannot efficiently provide
more facilities than the underlying iterators. Therefore, we must
choose the most basic iterator category of the underlying
iterators. Since the iterator category tags other than <tt class=
"literal">output_iterator_tag</tt> form an inheritance hierarchy,
we can use the implicit conversions applied by the ternary
conditional operator <tt class="literal">?:</tt> to determine the
most basic category - the return type of a conditional expression
where the two result expressions are pointers is a pointer to the
common base class of the pointed-to classes, so the type of the
expression</p>
<pre class="programlisting">
false ? (std::forward_iterator_tag*)0 : (std::random_access_iterator_tag*)0
</pre>
<p>is <tt class="literal">std::forward_iterator_tag*</tt>, for
example. We can then code to handle output iterators separately -
if either of the iterators is an output iterator, the result is an
output iterator, unless the other is an input iterator, in which
case it is an error. This is all handled by the <tt class=
"literal">CommonCategory</tt> class template, shown in listing 1 -
the <tt class="literal">categoryCheck</tt> functions and <tt class=
"literal">CategoryMap</tt> class templates are shown in listing
2.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e64" id="d0e64"></a>Meeting the
Requirements</h2>
</div>
<p>Having chosen our iterator category, we need to implement the
appropriate operations to fulfil the Standard Iterator Requirements
from Section 24.1 of the C++ Standard [<a href=
"#ISOCpp">ISOCpp</a>]. Most operations can easily be implemented by
forwarding to the corresponding operations on the underlying
iterators - the pre-increment operator can be implemented by
incrementing the underlying iterators, for example. It is the
dereference operator <tt class="literal">(operator*)</tt> and the
choice of <tt class="literal">value_type</tt> which is complicated,
as it depends on the iterator category. Input Iterators may return
by value, so if either of the underlying iterators is an Input
Iterator, we need to copy the result of dereferencing the
underlying iterators. On the other hand, the only operation
permitted on the result of dereferencing an Output Iterator is to
assign to it, so we cannot store a copy - the dereference operator
must return something which, when assigned to, assigns to the
result of dereferencing the underlying iterators. Finally, for all
other iterators, we need to return a reference that can be used to
access and update the elements of the underlying sequences.</p>
<p>The <tt class="literal">ValueForCategory</tt> class template
assists us with our choice - the PairIt iterator template just
delegates to <tt class="literal">ValueForCategory</tt>, once the
appropriate <tt class="literal">iterator_category</tt> has been
determined, and this is specialized for Input Iterators and Output
Iterators, leaving the primary template to handle the other
cases.</p>
<p>Implementing the dereference operator for Input Iterators and
Output Iterators is actually quite straightforward. For Input
Iterators, the <tt class="literal">value_type</tt> can be a plain
pair of values, the elements of which are the <tt class=
"literal">value_types</tt> of the underlying iterators, and the
dereference operator can just copy the values from the underlying
iterators into a pair held within the iterator, and return a
reference to that pair.<sup>[<a name="d0e97" href="#ftn.d0e97" id=
"d0e97">1</a>]</sup> For Output Iterators, the <tt class=
"literal">value_type</tt> is <tt class="literal">void</tt>, but the
result of the dereference operator is something quite different -
an <tt class="literal">OutputPair</tt> that contains references to
the underlying iterators, and which dereferences and writes to the
iterators when assigned to. <tt class="literal">OutputPairs</tt>
cannot be copied, so our iterator's dereference operator should
return a reference to an internal instance of <tt class=
"literal">OutputPair</tt>. The definition of <tt class=
"literal">OutputPair</tt> is shown in listing 3.</p>
<p>Supporting Forward Iterators, Bidirectional Iterators and Random
Access Iterators is more complicated - the dereference operator
must return a reference to the <tt class="literal">value_type</tt>,
which must hold real references to the elements in the sequences
covered by the original iterators. Just to add complexity, we
really want the <tt class="literal">value_type</tt> to be
Copy-Constructible and Assignable, and to copy the values of the
elements, not the references, as users wouldn't expect modifying
copies of the values to affect the originals; this implies that
objects of the same class sometimes contain references to data held
elsewhere, and sometimes hold the data directly. For this purpose,
we define the <tt class="literal">OwningRefPair</tt> class, which
has references for its public data members, and contains an
internal buffer for the values - the references can either point to
external data, in which case the buffer is empty, or they can point
to the buffer, in which case the buffer contains instances of the
appropriate objects. The objects are stored in an internal buffer,
rather than on the heap, to avoid the overhead of dynamic memory
allocation; however, this does require care to ensure that the
objects are properly destructed, and to ensure that the buffer is
correctly aligned.</p>
<div class="sidebar">
<p class="title c3">Listing 1: The CommonCategory class
template</p>
<pre class="programlisting">
  template&lt;typename Cat1,typename Cat2&gt;
  struct CommonCategory {
  private:
      enum {categorySize=sizeof(helper::categoryCheck(false?(Cat1*)0:(Cat2*)0))};
  public:
      typedef typename
      CategoryMap&lt;categorySize&gt;::Type Type;
  };

  // specializations

  template&lt;typename Cat&gt;
  struct CommonCategory&lt;std::output_iterator_tag,Cat&gt; {
      typedef std::output_iterator_tag Type;
  };

  template&lt;typename Cat&gt;
  struct CommonCategory&lt;Cat,std::output_iterator_tag&gt; {
      typedef std::output_iterator_tag Type;
  };

  template&lt;&gt;
  struct CommonCategory&lt;std::output_iterator_tag, std::output_iterator_tag&gt; {
      typedef std::output_iterator_tag Type;
  };

  template&lt;&gt;
  struct CommonCategory&lt;std::input_iterator_tag, std::output_iterator_tag&gt; {
      // no Type, because error
  };

  template&lt;&gt;
  struct CommonCategory&lt;std::output_iterator_tag, std::input_iterator_tag&gt; {
      // no Type, because error
  };
</pre></div>
<div class="sidebar">
<p class="title c3">Listing 2: The categoryCheck overloaded
functions and CategoryMap specializations</p>
<pre class="programlisting">
  // Small, Medium, Large and Huge are types
  // with distinct sizes
  Small categoryCheck(std::input_iterator_tag*);
  Medium categoryCheck(std::forward_iterator_tag*);
  Large categoryCheck(std::bidirectional_iterator_tag*);
  Huge categoryCheck(std::random_access_iterator_tag*);
  
  template&lt;&gt;
  struct CategoryMap&lt;sizeof(Small)&gt; {
      typedef std::input_iterator_tag Type;
  };

  template&lt;&gt;
  struct CategoryMap&lt;sizeof(Medium)&gt; {
      typedef std::forward_iterator_tag Type;
  };

  // etc.
</pre></div>
<div class="sidebar">
<p class="title c3">Listing 3: The OutputPair class template</p>
<pre class="programlisting">
  template&lt;typename Iter1,typename Iter2&gt;
  struct OutputPair {
  private:
      Iter1&amp; firstIter;
      Iter2&amp; secondIter;
      OutputPair(const OutputPair&amp;); // can't be
                                     // copied
  public:

      OutputPair(Iter1&amp; firstIter_, Iter2&amp; secondIter_)
          : firstIter(firstIter_),
            secondIter(secondIter_) {}
      template&lt;typename SomePair&gt;

      OutputPair&amp; operator=(const SomePair&amp; other) {
          *firstIter=other.first;
          *secondIter=other.second;
      }
  };
</pre></div>
<div class="sidebar">
<p class="title c3">Listing 4: rawmem.hh (include guards
omitted)</p>
<pre class="programlisting">
  namespace utils {
      template&lt;typename T&gt;
      struct Struct {
          T t;
      };

      class Unknown;

      union align_t {
          bool b;
          char c;
          short s;
          int i;
          long l;
          wchar_t w;
          float f;
          double d;
          long double ld;
          void* vp;
          void (*fp)();
          void (Unknown::*mfp)();
          Unknown* (Unknown::*mdp);
          Struct&lt;bool&gt; sb;
          Struct&lt;char&gt; sc;
          Struct&lt;short&gt; ss;
          Struct&lt;int&gt; si;
          Struct&lt;long&gt; sl;
          Struct&lt;wchar_t&gt; sw;
          Struct&lt;float&gt; sf;
          Struct&lt;double&gt; sd;
          Struct&lt;long double&gt; sld;
          Struct&lt;void*&gt; svp;
          Struct&lt;void (*)()&gt; sfp;
          Struct&lt;void (Unknown::*)()&gt; smfp;
          Struct&lt;Unknown* (Unknown::*)&gt; smdp;
      };

      template&lt;typename T&gt;
      union RawMem {
          char data[sizeof(T)];
          align_t align;
      };
  }
</pre></div>
<p>For alignment, we use a union of an appropriately-sized array of
char, and an instance of <tt class="literal">align_t</tt>.
<tt class="literal">align_t</tt> is itself a union of all the
fundamental types, and structs containing them. On most platforms,
this will have the most rigorous alignment of any type, so (on most
platforms)<sup>[<a name="d0e162" href="#ftn.d0e162" id=
"d0e162">2</a>]</sup> the union of <tt class="literal">align_t</tt>
and the array of char is guaranteed to be correctly aligned for any
type that has a <tt class="literal">sizeof</tt> less than or equal
to the size of the array.<sup>[<a name="d0e175" href="#ftn.d0e175"
id="d0e175">3</a>]</sup> The <tt class="literal">RawMem</tt>
template union uses the <tt class="literal">sizeof</tt> the
template parameter as the size of the char array.</p>
<p>We can then cast the address of the char array in our RawMem
union to a pointer of the required type, and use it with placement
<tt class="literal">new</tt> to construct an instance of the
specified type. At the appropriate point, we can also manually
invoke the destructor to clean up the object - i.e. in the
destructor of our object, we check to see if the buffer contains an
object or not, and invoke the destructor if it does, since this is
a fixed property of the <tt class="literal">OwningRefPair</tt>
object - either it contains the referred-to objects in its buffer,
or it doesn't, this property doesn't change during its lifetime. In
this case, the owned object is an <tt class=
"literal">OwnedPair</tt>; the details are shown in listing 5. Since
our <tt class="literal">value_types</tt> are distinct, and have
different construction syntax, we delegate the actual task of
construction and destruction to the <tt class=
"literal">ValueForCategory</tt> template, to give a uniform
interface to <tt class="literal">PairIt</tt>.</p>
<div class="sidebar">
<p class="title c3">Listing 5: The OwningRefPair class template</p>
<pre class="programlisting">
  #include &lt;rawmem.hh&gt;

  template&lt;typename T,typename U&gt; struct OwningRefPair {

  public:

      T&amp; first;
      U&amp; second;
      typedef T first_type;
      typedef U second_type;

  private:

      struct OwnedPair {
          T first;
          U second;
          template&lt;typename Val1,typename Val2&gt; OwnedPair(Val1&amp; v1,Val2&amp; v2)
              : first(v1),second(v2) {}
      };

      utils::RawMem&lt;OwnedPair&gt; pairBuf;
      const bool ownsFlag;

      OwnedPair* getPairPtr() {
          return reinterpret_cast&lt;OwnedPair*&gt;(pairBuf.data);
      }

      template&lt;typename Val1,typename Val2&gt;
      void createCopy(Val1&amp; v1,Val2&amp; v2) {
          new(getPairPtr()) OwnedPair(v1,v2);
      }

  public:

      OwningRefPair(T&amp; first_, U&amp; second_, bool copy)
          : first(copy ? getPairPtr()-&gt;first : first_),
            second(copy ? getPairPtr()-&gt;second : second_),
            ownsFlag(copy) {
          if(ownsFlag) {
              createCopy(first_,second_);
          }
      }

      ~OwningRefPair() {
          if(ownsFlag) {
          getPairPtr()-&gt;~OwnedPair();
          }
      }
  };
</pre></div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e214" id="d0e214"></a>Putting
together the fundamentals</h2>
</div>
<p>Having pinned down the <tt class="literal">value_type</tt> for
our iterator, and what we get when we dereference it, we can put
together a basic version of our <tt class="literal">PairIt</tt>, as
in listing 6. This highlights a couple of issues. Firstly, we
delegate all the type selection to the <tt class=
"literal">PairItHelper</tt> template, so we can inherit from an
appropriate instance of <tt class=
"literal">std::iterator&lt;&gt;</tt> without having to specify all
the types explicitly. Secondly, even though <tt class=
"literal">std::iterator&lt;&gt;</tt> defines all the required
typedefs, we have to repeat them here, so we can use them within
the class definition; the base class is a dependent name, so it
isn't searched during resolution of unqualified names within the
class. This begs the question of whether or not we need to inherit
from <tt class="literal">std::iterator&lt;&gt;</tt> at all; some
existing code expects all iterators that aren't raw pointers to
inherit from <tt class="literal">std::iterator&lt;&gt;</tt>, and
doing so causes no harm. We also can reuse the memory management
from <tt class="literal">OwningRefPair</tt>, so we don't have to
rely on any particular properties of the <tt class=
"literal">value_types</tt> of the underlying iterators, except this
time we delegate the construction and destruction to <tt class=
"literal">PairItHelper</tt> as well. Note also that all the members
are mutable - this is because we don't want to pass on any
requirements that the encapsulated iterators be non-const for
specific operations, and the cache needs to be updated in response
to dereferencing the iterator, which is a const operation.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e249" id="d0e249"></a>Beyond the
basics</h2>
</div>
<p>Now that our iterator supports the basic operation of
dereferencing, we need to cover the remaining iterator requirements
from the C++ Standard. For Input Iterators, the relevant section is
24.1.1, and table 72. This requires that in addition to
dereferencing, we also require:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Copy-construction,</p>
</li>
<li>
<p>Assignment,</p>
</li>
<li>
<p>Equality and Inequality operators, and</p>
</li>
<li>
<p>Pre- and post-increment operators.</p>
</li>
</ul>
</div>
<p>These operations are also sufficient for Output Iterators, as
they cover all the requirements from section 24.1.2 and table
73.</p>
<p>In all cases, we can just defer to the underlying iterators, and
perform the operations on them. However, there is a consequence for
exception safety - since we know nothing about the effects of the
operations on the underlying iterators, including whether or not
they through exceptions, and whether or not the iterator types
support a non-throwing <tt class="literal">swap</tt> operation, we
have to add a disclaimer to the usage of our iterator - if an
operation on a <tt class="literal">PairIt</tt> throws an exception,
then the iterator is to be considered to have become invalid. If we
don't add this disclaimer, then it is possible that the state of
the iterator may become confused, as (for example) one of the
underlying iterators may have advanced, and the other one not.</p>
<p>Another point to make is that copy-construction and assignment
should only copy the iterators, not the cache. This is to avoid
unnecessary copying of the cached data, which would only provide an
additional source of exceptions for no gain - the cache must be
regenerated every time the iterators are dereferenced anyway to
support Input Iterators that automatically advance when read (which
may not actually be allowed anyway). When dealing with non-Input
Iterators, the cached value is only a couple of references, so this
should add little performance penalty. The alternative is to have
every function that modifies the underlying iterators call
<tt class="literal">emptyCache()</tt>, and only call <tt class=
"literal">initCache()</tt> if the cache is not initialised.</p>
<div class="sidebar">
<p class="title c3">Listing 6: A basic implementation of PairIt</p>
<pre class="programlisting">
  #include &lt;rawmem.hh&gt;

  template&lt;typename Iter1,typename Iter2&gt;
  class PairIt : public PairItHelper&lt;Iter1,Iter2&gt;::IteratorType {
  private:
      typedef PairItHelper&lt;Iter1,Iter2&gt; PairDefs;
      typedef typename
      PairDefs::ValueTypeDef ValueTypeDef;
  public:
      typedef typename PairDefs::iterator_category iterator_category;
      typedef typename PairDefs::value_type value_type;
      typedef typename PairDefs::difference_type difference_type;
      typedef typename PairDefs::reference reference;
      typedef typename PairDefs::pointer pointer;
  private:
      pointer getValuePtr() const {
          return reinterpret_cast&lt;pointer&gt;(dataCache.data);
      }

      void emptyCache() const {
          if(cacheInitialized) {
              ValueTypeDef::destruct(getValuePtr());
              cacheInitialized=false;
          }
      }

      void initCache() const {
          emptyCache();
          ValueTypeDef::construct(getValuePtr(),it1,it2);
          cacheInitialized=true;
      }

  public:
      PairIt(Iter1 it1_,Iter2 it2_)
          : it1(it1_),it2(it2_),cacheInitialized(false){}
      
      ~PairIt() { emptyCache(); }

      reference operator*() const {
          initCache();
          return *getValuePtr();
      }

      pointer operator-&gt;() const {
          initCache();
          return getValuePtr();
      }

  private:
      mutable Iter1 it1;
      mutable Iter2 it2;
      mutable utils::RawMem&lt;PairDefs::DeRefType&gt; dataCache;
      mutable bool cacheInitialized;
  };
</pre></div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e291" id="d0e291"></a>Moving
Forward</h2>
</div>
<p>For the cases where both the underlying iterators are at least
Forward Iterators, we need to meet additional requirements, for
PairIt to also work as a Forward Iterator. These are given by
section 24.1.3 and table 74 of the Standard, and are actually
mostly semantic constraints, rather than operational constraints,
so these are implemented automatically if the underlying iterators
are themselves Forward Iterators. The only additional operation
required is that PairIt must be Default-constructible, which is
trivially implemented.</p>
<p>If our underlying iterators are at least Bidirectional
Iterators, we should also implement the pre- and post-decrement
operators to maintain that level, as detailed in section 24.1.4 and
table 75 of the Standard. As for pre- and post-increment, these can
be implemented merely by forwarding to the underlying
iterators:</p>
<pre class="programlisting">
  PairIt&amp; operator-() {
      -it1;
      -it2;
      return *this;
  }
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e300" id="d0e300"></a>Dereferencing
at Random</h2>
</div>
<p>If our underlying iterators are both Random Access Iterators,
then we have a whole swathe of additional requirements to support,
as detailed in section 24.1.5 and table 76 of the Standard. These
are:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The arithmetic operators + and -,</p>
</li>
<li>
<p>The arithmetic assignment operators += and -=,</p>
</li>
<li>
<p>The comparison operators &lt;, &gt;, &lt;= and &gt;=, and</p>
</li>
<li>
<p>The subscripting operator [].</p>
</li>
</ul>
</div>
<p>The arithmetic operators are trivial - just forward to the
underlying iterators. The comparison operators require a bit more
thought - what do we do if the first iterator is less than its
partner, but the second isn't? - but the problems can be defined
out of existence; iterators can only be compared if they are in the
same range. This implies that one is reachable from the other. If
the first and second underlying iterators don't give the same
results when compared against their partners in the <tt class=
"literal">PairIt</tt> we are comparing against, then this can't be
the case, and the issue can be avoided - in fact, we could get away
with just comparing the first iterator in each pair, so the
comparison operators are also trivial. The subscripting operator is
easy, too - <tt class="literal">it[n]</tt> is just syntactic
shorthand for <tt class="literal">*(it+n)</tt>, so we can implement
it that way.</p>
<p>However, a bit more thought reveals that doing things the
&quot;simple&quot; way requires that all these operations are either member
functions or friends of PairIt, yet some could be implemented in
terms of others. For example, the idiomatic way of implementing
<tt class="literal">+</tt> is to use <tt class="literal">+=</tt> on
a copy, as follows:</p>
<pre class="programlisting">
  template&lt;typename I1,typename I2&gt;
  PairIt&lt;I1,I2&gt; operator+(PairIt&lt;I1,I2&gt; temp, std::ptrdiff_t n) {
      temp+=n;
      return temp;
  }
</pre>
<p>The same applies to the comparison operators - all the others
can be implemented in terms of <tt class=
"literal">operator&lt;</tt>. In fact, <tt class=
"literal">operator&lt;</tt> itself can then be implemented in terms
of subtraction, since these are Random Access Iterators, so the
list of friends and member functions is now down to:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><tt class="literal">operator+=</tt>,</p>
</li>
<li>
<p><tt class="literal">operator-=</tt>,</p>
</li>
<li>
<p><tt class="literal">operator-</tt> where both operands are
iterators, and</p>
</li>
<li>
<p><tt class="literal">operator[]</tt>, which is required to be a
member function.</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e368" id="d0e368"></a>Helper
functions</h2>
</div>
<p>Sometimes we don't want to have to specify the precise type of
our iterators explicitly, because we're creating a temporary object
to pass to an algorithm, and doing so requires excessive typing, if
it is possible at all. For this reason, we also provide a helper
template function <tt class="literal">makePairIterator</tt> that
takes two iterators as parameters, and returns a <tt class=
"literal">PairIt</tt> containing them. This simple function and its
use is shown in listing 7.</p>
<div class="sidebar">
<p class="title c3">Listing 7: The makePairIterator helper
function</p>
<pre class="programlisting">
  template&lt;typename Iter1,typename Iter2&gt;
  PairIt&lt;Iter1,Iter2&gt; makePairIterator(Iter1 it1, Iter2 it2) {
      return PairIt&lt;Iter1,Iter2&gt;(it1,it2);
  }

  // use of makePairIterator
  std::vector&lt;int&gt; src1;
  std::deque&lt;double&gt; src2;

  bool myPairComparisonFunc(const std::pair&lt;int,double&gt;&amp;,
                            const std::pair&lt;int,double&gt;&amp;);

std::sort(makePairIterator(src1.begin(),src2.begin()),
          makePairIterator(src1.end(),src2.end()),
          myPairComparisonFunc);
</pre></div>
<p>Of course, as written, this will copy the elements of the
containers to do the comparison, as the <tt class=
"literal">value_type</tt> of the pair iterators is a custom pair
type, as described above, so a temporary std::pair has to be
constructed. It is therefore more efficient to write functor class
with a template function call operator:</p>
<pre class="programlisting">
  struct MyPairComparisonFunctor {
      template&lt;typename PairType&gt; bool operator()(const PairType&amp;,
                                                  const PairType&amp;) const;
  };
</pre>
<p>You could, of course, write a comparison function to take the
precise custom pair type in question, but this varies depending on
the iterators, so is not as straightforward as it may seem.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e394" id=
"d0e394"></a>Conclusion</h2>
</div>
<p>Implementing an iterator adapter to treat a pair of sequences as
a sequence of pairs is not a trivial task, though some of the
individual parts are; the biggest headache is deciding the
<tt class="literal">value_type</tt> and the return type for the
dereference operator.</p>
<p>However, it provides a genuinely useful service, and in
combination with other iterator adapters and function objects, can
be used to access data in intuitive ways, however it is stored.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e404" id="d0e404"></a>References</h2>
</div>
<div class="bibliomixed"><a name="ISOCpp" id="ISOCpp"></a>
<p class="bibliomixed">[ISOCpp] ISO/IEC 14882, <span class=
"citetitle"><i class="citetitle">Programming Languages - C++.
International Standard</i></span>, September 1998.</p>
</div>
<div class="bibliomixed"><a name="Alex" id="Alex"></a>
<p class="bibliomixed">[Alex] Andrei Alexandrescu.
Generic&lt;Programming&gt;: Discriminated unions (II). <span class=
"citetitle"><i class="citetitle">C/C++ User's Journal</i></span>,
20(6), June 2002. Available online at <span class=
"bibliomisc"><a href="http://www.cuj.com/experts/2006/alexandr.htm"
target=
"_top">http://www.cuj.com/experts/2006/alexandr.htm</a></span>.</p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c4" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e97" href="#d0e97" id=
"ftn.d0e97">1</a>]</sup> We could return the pair by value, but for
uniformity with the other types of iterators, it makes sense to
return a reference to an internal object.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e162" href="#d0e162" id=
"ftn.d0e162">2</a>]</sup> Platforms <span class=
"emphasis"><em>may</em></span> arbitrarily choose to make the
alignment of one particular userdefined type distinct from that of
any other types.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e175" href="#d0e175" id=
"ftn.d0e175">3</a>]</sup> For an implementation that discards types
bigger than the type we need the alignment of, to avoid wasting
space, see [<a href="#Alex">Alex</a>]</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
