<?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.3.8: http://docutils.sourceforge.net/" />
<title>The Cursor/Property Map Abstraction</title>
<meta name="author" content="Dietmar Kühl and David Abrahams" />
<meta name="date" content="April 14, 2005" />
<meta name="documentnumber" content="N1873=05-0133" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2004/06/23 13:31:26 $
:version: $Revision: 1.37 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/

.first {
  margin-top: 0 }

.last {
  margin-bottom: 0 }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

/* Uncomment (& remove this text!) to get bold-faced definition list terms
dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em }

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

dt {
  font-weight: bold }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {
  background-color: #eeeeee }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="the-cursor-property-map-abstraction">
<h1 class="title">The Cursor/Property Map Abstraction</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Doc.No:</th>
<td>N1873=05-0133</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2005-08-26</td></tr>
<tr><th class="docinfo-name">Project:</th>
<td>Programming Language C++</td></tr>
<tr><th class="docinfo-name">Reply To:</th>
<td>Dietmar Kühl &lt;dietmar_kuehl@yahoo.com&gt; and David Abrahams &lt;dave@boost-consulting.com&gt;</td></tr>
</tbody>
</table>
<div class="contents topic" id="index">
<p class="topic-title first"><a name="index">Index</a></p>
<ul class="simple">
<li><a class="reference" href="#authors-note" id="authnote" name="authnote">Author's Note</a></li>
<li><a class="reference" href="#problems-with-c-03-iterators" id="id3" name="id3">Problems with C++03 Iterators</a></li>
<li><a class="reference" href="#proposed-solution" id="id4" name="id4">Proposed Solution</a></li>
<li><a class="reference" href="#backward-compatibility" id="id5" name="id5">Backward Compatibility</a></li>
<li><a class="reference" href="#associated-types" id="id6" name="id6">Associated Types</a></li>
</ul>
</div>
<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">We propose a new formulation for the sequence traversal
and element access capabilities currently captured in the
standard iterator concepts.</td>
</tr>
</tbody>
</table>
<div class="section" id="authnote">
<h1><a class="toc-backref" href="#id3" name="authors-note">Author's Note</a></h1>
<p>This document is proposed as a basis for continuing work. None of the design
choices implied in this work is final. Better ideas, as well as comments and
critiques will be gratefully received. Also, there are other aspects of the
algorithm's interfaces which may be changed when addressing the concepts they
are built upon.
</p>
</div>
<div class="section" id="problems-with-c-03-iterators">
<h1><a class="toc-backref" href="#id3" name="problems-with-c-03-iterators">Problems with C++03 Iterators</a></h1>
<p>The C++03 iterator concepts couple access capabilities—such as
whether or not a dereferenced iterator must produce an lvalue—to
traversal capabilities such as whether the iterator can move
backwards.  Two of the problems caused by this coupling have been
extensively detailed in earlier work <a class="citation-reference" href="#asw04" id="id1" name="id1">[ASW04]</a>, namely:</p>
<ul class="simple">
<li>Algorithm requirements are more strict than necessary, because
they cannot separate the need for random access or bidirectional
traversal from the need for a true reference return type.</li>
<li>Iterators are often mis-categorized. Iterators that support
random access traversal but use “proxy references” are classic
examples.</li>
</ul>
<p>However, the need for proxy references themselves could be seen as
a design flaw in the iterator concepts: the syntax for writing into
a dereferenced pointer complicates any writable iterator that
cannot easily supply an in-memory instance of the type being
written (consider an iterator over a disk-based container).</p>
<p>Achieving interoperability between a container's <tt class="docutils literal"><span class="pre">iterator</span></tt> and
its <tt class="docutils literal"><span class="pre">const_iterator</span></tt> is a well-known trouble spot for
implementors, and it was wrong in many early STL implementations.
The need for separate <tt class="docutils literal"><span class="pre">iterator</span></tt> and <tt class="docutils literal"><span class="pre">const_iterator</span></tt> types,
and redundant boilerplate <tt class="docutils literal"><span class="pre">begin</span></tt>/<tt class="docutils literal"><span class="pre">end</span></tt>/<tt class="docutils literal"><span class="pre">rbegin</span></tt>/<tt class="docutils literal"><span class="pre">rend</span></tt> overloads in containers is another consequence of the
coupling described earlier.</p>
<p>Finally, there is the issue of converting constant iterators to
mutable ones.  Consider:</p>
<pre class="literal-block">
template &lt;SomeContainer&gt;
class encapsulated
{
 public:
    typedef typename SomeContainer::const_iterator iterator;

    iterator begin() const { return x.begin(); }
    iterator end() const { return x.end(); }

    void transmogrify(iterator start, iterator end);

 private:
    SomeContainer x;
};
</pre>
<p>An <tt class="docutils literal"><span class="pre">encapsulated&lt;list&lt;int&gt;</span> <span class="pre">&gt;</span></tt> passes out only
<tt class="docutils literal"><span class="pre">list&lt;int&gt;::const_iterator</span></tt> so that users don't make
invariant-breaking changes.  All mutation should happen within the
<tt class="docutils literal"><span class="pre">transmogrify</span></tt> member function, where <tt class="docutils literal"><span class="pre">encapsulated&lt;&gt;</span></tt> can
manage the changes.  But <tt class="docutils literal"><span class="pre">encapsulated</span></tt> will have trouble
implementing any mutations inside its <tt class="docutils literal"><span class="pre">transmogrify</span></tt> member
function because the iterators supplied by the user—which ought to
be nothing more than position indicators—actually regulate access.</p>
</div>
<div class="section" id="proposed-solution">
<h1><a class="toc-backref" href="#id4" name="proposed-solution">Proposed Solution</a></h1>
<p>We propose to solve these problems by dividing the responsibilities
of iterators into two objects: cursors, which traverse a sequence
of keys, and property maps, which associate those keys with values.
An ordinary iterator range is be represented by a property map and
two cursors.  The following table shows how some iterator
operations correspond to those on cursors and property maps:</p>
<blockquote>
<table border="1" class="docutils">
<colgroup>
<col width="27%" />
<col width="33%" />
<col width="41%" />
</colgroup>
<thead valign="bottom">
<tr><th>Operation</th>
<th>C++'98 approach</th>
<th>new approach</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>read</td>
<td><tt class="docutils literal"><span class="pre">val</span> <span class="pre">=</span> <span class="pre">*it</span></tt></td>
<td><tt class="docutils literal"><span class="pre">val</span> <span class="pre">=</span> <span class="pre">pm(*c)</span></tt></td>
</tr>
<tr><td>write</td>
<td><tt class="docutils literal"><span class="pre">*it</span> <span class="pre">=</span> <span class="pre">val</span></tt></td>
<td><tt class="docutils literal"><span class="pre">pm(*c,</span> <span class="pre">val)</span></tt></td>
</tr>
<tr><td>lvalue access</td>
<td><tt class="docutils literal"><span class="pre">X&amp;</span> <span class="pre">a</span> <span class="pre">=</span> <span class="pre">*it</span></tt></td>
<td><tt class="docutils literal"><span class="pre">X&amp;</span> <span class="pre">a</span> <span class="pre">=</span> <span class="pre">pm(*c)</span></tt></td>
</tr>
<tr><td>preincrement</td>
<td><tt class="docutils literal"><span class="pre">++it</span></tt></td>
<td><tt class="docutils literal"><span class="pre">++c</span></tt></td>
</tr>
<tr><td>random offset</td>
<td><tt class="docutils literal"><span class="pre">it</span> <span class="pre">+</span> <span class="pre">n</span></tt></td>
<td><tt class="docutils literal"><span class="pre">c</span> <span class="pre">+</span> <span class="pre">n</span></tt></td>
</tr>
<tr><td><em>...etc.</em></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
<p>In the table above, <tt class="docutils literal"><span class="pre">it</span></tt> is an iterator, and <tt class="docutils literal"><span class="pre">pm</span></tt> and <tt class="docutils literal"><span class="pre">c</span></tt> are
a corresponding property map and cursor.  <tt class="docutils literal"><span class="pre">X</span></tt> is the iterator's
map's value type and <tt class="docutils literal"><span class="pre">val</span></tt> is an object of type <tt class="docutils literal"><span class="pre">X</span></tt>.</p>
<p>Cursors are essentially input iterators, optionally
refined with bidirectional or random access traversal.  The cursor
concept is never refined to allow mutability or lvalue
access—those features are the sole domain of property maps—so
access is fully decoupled from traversal in the concept framework.</p>
<p>The presence of a dereference operator on cursors might seem
strange, since since the goal is to separate access from traversal.
For instance, the values of a property map could be read as
<tt class="docutils literal"><span class="pre">pm(c)</span></tt> instead of <tt class="docutils literal"><span class="pre">pm(*c)</span></tt>.  It turns out that the dereference
operation is required in order to reasonably support traversal
adapters.  If you have a property map that accepts <tt class="docutils literal"><span class="pre">foo_cursor</span></tt>
arguments, it may not be designed to accept a
<tt class="docutils literal"><span class="pre">reverse_cursor&lt;foo_cursor&gt;</span></tt> directly.  Like so many others, this
problem is solved by adding a level of indirection: dereferencing a
cursor yields an intermediate <em>key</em>, and the key type of a
traversal adapter is the same as that of its underlying iterator.</p>
</div>
<div class="section" id="backward-compatibility">
<h1><a class="toc-backref" href="#id5" name="backward-compatibility">Backward Compatibility</a></h1>
<p>Raw pointers and, indeed, all C++98 iterators have a natural place
in this scheme.  Combined with an <em>identity</em> property map, an
iterator can act as a cursor:</p>
<span class="target" id="identity-property-map"></span><pre class="literal-block">
// A property map whose keys and values are the same
struct identity_property_map
{
    // Readability
    template &lt;class K&gt;
    inline
    K&amp; operator()(K&amp; k) const
    {
        return k;
    }

    template &lt;class K&gt;
    inline
    K const&amp; operator()(K const&amp; k) const
    {
        return k;
    }

    // Writability
    template &lt;class K, class V&gt;
    inline
    void operator()(K&amp; k, V const&amp; v) const
    {
        return k = v;
    }

    // This one is needed to support proxies
    template &lt;class K, class V&gt;
    inline
    void operator()(K const&amp; k, V const&amp; v) const
    {
        return k = v;
    }
};
</pre>
<p>C++98 algorithms can be extended to accept optional property maps,
with instances of <tt class="docutils literal"><span class="pre">identity_property_map</span></tt> as the default.</p>
</div>
<div class="section" id="associated-types">
<h1><a class="toc-backref" href="#id6" name="associated-types">Associated Types</a></h1>
<p>To access the key type of a cursor (the type returned when it is
dereferenced), we can use the <tt class="docutils literal"><span class="pre">key_type</span></tt> metafunction:</p>
<pre class="literal-block">
typename key_type&lt;Cursor&gt;::type key = *c;
</pre>
<p>An obvious<a class="footnote-reference" href="#obvious" id="id2" name="id2">[1]</a> default implementation for <tt class="docutils literal"><span class="pre">key_type</span></tt> is:</p>
<pre class="literal-block">
template &lt;class Cursor&gt;
struct key_type
{
    typedef typename 
      std::iterator_traits&lt;Cursor&gt;::value_type type;
};
</pre>
<p>Property maps don't necessarily have a “value type.”  Indeed, the
<tt class="docutils literal"><span class="pre">identity_property_map</span></tt> shown above can read and write arbitrary
types.  To discover the type accessed by a given key type <tt class="docutils literal"><span class="pre">K</span></tt>
through a property map of type <tt class="docutils literal"><span class="pre">PropertyMap</span></tt>, we can write:</p>
<pre class="literal-block">
result_of&lt;PropertyMap(K)&gt;::type
</pre>
<p>In other words, due to its use of the function call interface, we
don't need to introduce a new trait metafunction to describe the
result of accessing a property map.</p>
<table class="docutils footnote" frame="void" id="obvious" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2" name="obvious">[1]</a></td><td><p class="first">It isn't clear yet whether it would be more useful to
know when the key type is a reference.  In that case,</p>
<pre class="literal-block">
template &lt;class Cursor&gt;
struct key_type
{
    typedef typename 
      std::iterator_traits&lt;Cursor&gt;::reference type;
};
</pre>
<p class="last">might be a more appropriate implementation.</p>
</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="asw04" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="asw04">[ASW04]</a></td><td>David Abrahams, Jeremy Siek, Thomas Witt, <cite>New Iterator
Concepts</cite>,
2004. <a class="reference" href="http://www.boost.org/libs/iterator/doc/new-iter-concepts.html">http://www.boost.org/libs/iterator/doc/new-iter-concepts.html</a></td></tr>
</tbody>
</table>
</div>
</div>
<hr class="docutils footer" />
<div class="footer">
Generated on: 2005-06-23 21:53 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>
