added more design rationale, and moved some text

[SVN r20158]
This commit is contained in:
Jeremy Siek
2003-09-22 16:28:27 +00:00
parent a3856b5c60
commit d85b8db0aa
2 changed files with 42 additions and 28 deletions

View File

@ -270,11 +270,11 @@ given in the following diagram.</p>
dispatching based on the traversal concepts. The tags are related via dispatching based on the traversal concepts. The tags are related via
inheritance so that a tag is convertible to another tag if the concept inheritance so that a tag is convertible to another tag if the concept
associated with the first tag is a refinement of the second tag. associated with the first tag is a refinement of the second tag.
Since the access concepts are not related via refinment, but instead Since the access concepts are not related via refinement, but instead
cover orthogonal issues, we do not use tags for the access concepts, cover orthogonal issues, we do not use tags for the access concepts,
but instead use the equivalent of a bitfield.</p> but instead use the equivalent of a bit field.</p>
<p>We provide an access mechanism for mapping iterator types to the new <p>We provide an access mechanism for mapping iterator types to the new
traversal tags and access bitfield. Our design reuses traversal tags and access bit field. Our design reuses
<tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> as the access <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> as the access
mechanism. To that end, the access and traversal information is mechanism. To that end, the access and traversal information is
bundled into a single type using the following <cite>iterator_tag</cite> class.</p> bundled into a single type using the following <cite>iterator_tag</cite> class.</p>
@ -284,17 +284,28 @@ enum iterator_access { readable_iterator = 1, writable_iterator = 2,
template &lt;unsigned int access_bits, class TraversalTag&gt; template &lt;unsigned int access_bits, class TraversalTag&gt;
struct iterator_tag : /* appropriate old category or categories */ { struct iterator_tag : /* appropriate old category or categories */ {
static const iterator_access access = (iterator_access)access_bits; static const iterator_access access =
(iterator_access)access_bits &amp;
(readable_iterator | writable_iterator | swappable_iterator);
typedef TraversalTag traversal; typedef TraversalTag traversal;
}; };
</pre> </pre>
<p>The <tt class="literal"><span class="pre">access_bits</span></tt> argument is declared to be <tt class="literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt>
instead of the enum <tt class="literal"><span class="pre">iterator_access</span></tt> for convenience of use. For
example, the expression <tt class="literal"><span class="pre">(readable_iterator</span> <span class="pre">|</span> <span class="pre">writable_iterator)</span></tt>
produces an unsigned int, not an <tt class="literal"><span class="pre">iterator_access</span></tt>. The purpose of
the <tt class="literal"><span class="pre">lvalue_iterator</span></tt> part of the <tt class="literal"><span class="pre">iterator_access</span></tt> enum is to
communicate to <tt class="literal"><span class="pre">iterator_tag</span></tt> whether the reference type is an
lvalue so that the appropriate old category can be chosen for the base
class. The <tt class="literal"><span class="pre">lvalue_iterator</span></tt> bit is not recorded in the
<tt class="literal"><span class="pre">iterator_tag::access</span></tt> data member.</p>
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is derived from the appropriate <p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is derived from the appropriate
iterator tag or tags from the old requirements based on the new-style iterator tag or tags from the old requirements based on the new-style
tags passed as template parameters. The algorithm for determining the tags passed as template parameters. The algorithm for determining the
old tag or tags from the new tags picks the least-refined old concepts old tag or tags from the new tags picks the least-refined old concepts
that include all of the requirements of the access and traversal that include all of the requirements of the access and traversal
concepts (that is, the closest fit), if any such category exists. For concepts (that is, the closest fit), if any such category exists. For
example, a the category tag for a Readable Single Pass Iterator will example, the category tag for a Readable Single Pass Iterator will
always be derived from <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, while the category tag always be derived from <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, while the category tag
for a Single Pass Iterator that is both Readable and Writable will be for a Single Pass Iterator that is both Readable and Writable will be
derived from both <tt class="literal"><span class="pre">input_iterator_tag</span></tt> and <tt class="literal"><span class="pre">output_iterator_tag</span></tt>.</p> derived from both <tt class="literal"><span class="pre">input_iterator_tag</span></tt> and <tt class="literal"><span class="pre">output_iterator_tag</span></tt>.</p>
@ -303,14 +314,12 @@ obtain the access and traversal characteristics of an iterator. These
helper classes work both for iterators whose <tt class="literal"><span class="pre">iterator_category</span></tt> is helper classes work both for iterators whose <tt class="literal"><span class="pre">iterator_category</span></tt> is
<tt class="literal"><span class="pre">iterator_tag</span></tt> and also for iterators using the original iterator <tt class="literal"><span class="pre">iterator_tag</span></tt> and also for iterators using the original iterator
categories.</p> categories.</p>
<dl> <pre class="literal-block">
<dt>::</dt> template &lt;class Iterator&gt; struct is_readable { typedef ... type; };
<dd><p class="last">template &lt;class Iterator&gt; struct is_readable { typedef ... type; };
template &lt;class Iterator&gt; struct is_writable { typedef ... type; }; template &lt;class Iterator&gt; struct is_writable { typedef ... type; };
template &lt;class Iterator&gt; struct is_swappable { typedef ... type; }; template &lt;class Iterator&gt; struct is_swappable { typedef ... type; };
template &lt;class Iterator&gt; struct traversal_category { typedef ... type; };</p> template &lt;class Iterator&gt; struct traversal_category { typedef ... type; };
</dd> </pre>
</dl>
<p>We do not include a helper class <tt class="literal"><span class="pre">is_lvalue_iterator</span></tt> because that <p>We do not include a helper class <tt class="literal"><span class="pre">is_lvalue_iterator</span></tt> because that
can easily be deduced by checking whether can easily be deduced by checking whether
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::reference</span></tt> is a real reference.</p> <tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::reference</span></tt> is a real reference.</p>
@ -860,12 +869,8 @@ inherit-category(access, traversal-tag) =
else else
return null_category_tag; return null_category_tag;
</pre> </pre>
<p>The access argument is declared to be <tt class="literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt> instead of the <p>If the argument for <tt class="literal"><span class="pre">TraversalTag</span></tt> is not convertible to
enum <tt class="literal"><span class="pre">iterator_access</span></tt> for convenience of use. For example, the <tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt> then the program is ill-formed.</p>
expression <tt class="literal"><span class="pre">(readable_iterator</span> <span class="pre">|</span> <span class="pre">writable_iterator)</span></tt> produces an
unsigned int, not <tt class="literal"><span class="pre">iterator_access</span></tt>. If the argument for
<tt class="literal"><span class="pre">TraversalTag</span></tt> is not convertible to <tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt>
then the programm is ill-formed.</p>
<p>The <tt class="literal"><span class="pre">is_readable</span></tt>, <tt class="literal"><span class="pre">is_writable</span></tt>, <tt class="literal"><span class="pre">is_swappable</span></tt>, and <p>The <tt class="literal"><span class="pre">is_readable</span></tt>, <tt class="literal"><span class="pre">is_writable</span></tt>, <tt class="literal"><span class="pre">is_swappable</span></tt>, and
<tt class="literal"><span class="pre">traversal_category</span></tt> class templates are traits classes. For <tt class="literal"><span class="pre">traversal_category</span></tt> class templates are traits classes. For
iterators whose <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> type is iterators whose <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> type is
@ -953,7 +958,7 @@ LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS --> LocalWords: TraversalTag typename lvalues DWA Hmm JGS mis enum -->
</div> </div>
</div> </div>
</div> </div>

View File

@ -251,10 +251,10 @@ inheritance so that a tag is convertible to another tag if the concept
associated with the first tag is a refinement of the second tag. associated with the first tag is a refinement of the second tag.
Since the access concepts are not related via refinement, but instead Since the access concepts are not related via refinement, but instead
cover orthogonal issues, we do not use tags for the access concepts, cover orthogonal issues, we do not use tags for the access concepts,
but instead use the equivalent of a bitfield. but instead use the equivalent of a bit field.
We provide an access mechanism for mapping iterator types to the new We provide an access mechanism for mapping iterator types to the new
traversal tags and access bitfield. Our design reuses traversal tags and access bit field. Our design reuses
``iterator_traits<Iter>::iterator_category`` as the access ``iterator_traits<Iter>::iterator_category`` as the access
mechanism. To that end, the access and traversal information is mechanism. To that end, the access and traversal information is
bundled into a single type using the following `iterator_tag` class. bundled into a single type using the following `iterator_tag` class.
@ -266,10 +266,22 @@ bundled into a single type using the following `iterator_tag` class.
template <unsigned int access_bits, class TraversalTag> template <unsigned int access_bits, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */ { struct iterator_tag : /* appropriate old category or categories */ {
static const iterator_access access = (iterator_access)access_bits; static const iterator_access access =
(iterator_access)access_bits &
(readable_iterator | writable_iterator | swappable_iterator);
typedef TraversalTag traversal; typedef TraversalTag traversal;
}; };
The ``access_bits`` argument is declared to be ``unsigned int``
instead of the enum ``iterator_access`` for convenience of use. For
example, the expression ``(readable_iterator | writable_iterator)``
produces an unsigned int, not an ``iterator_access``. The purpose of
the ``lvalue_iterator`` part of the ``iterator_access`` enum is to
communicate to ``iterator_tag`` whether the reference type is an
lvalue so that the appropriate old category can be chosen for the base
class. The ``lvalue_iterator`` bit is not recorded in the
``iterator_tag::access`` data member.
The ``iterator_tag`` class template is derived from the appropriate The ``iterator_tag`` class template is derived from the appropriate
iterator tag or tags from the old requirements based on the new-style iterator tag or tags from the old requirements based on the new-style
tags passed as template parameters. The algorithm for determining the tags passed as template parameters. The algorithm for determining the
@ -281,6 +293,7 @@ always be derived from ``input_iterator_tag``, while the category tag
for a Single Pass Iterator that is both Readable and Writable will be for a Single Pass Iterator that is both Readable and Writable will be
derived from both ``input_iterator_tag`` and ``output_iterator_tag``. derived from both ``input_iterator_tag`` and ``output_iterator_tag``.
We also provide several helper classes that make it convenient to We also provide several helper classes that make it convenient to
obtain the access and traversal characteristics of an iterator. These obtain the access and traversal characteristics of an iterator. These
helper classes work both for iterators whose ``iterator_category`` is helper classes work both for iterators whose ``iterator_category`` is
@ -698,12 +711,8 @@ pseudo-code.
else else
return null_category_tag; return null_category_tag;
The access argument is declared to be ``unsigned int`` instead of the If the argument for ``TraversalTag`` is not convertible to
enum ``iterator_access`` for convenience of use. For example, the ``incrementable_iterator_tag`` then the program is ill-formed.
expression ``(readable_iterator | writable_iterator)`` produces an
unsigned int, not ``iterator_access``. If the argument for
``TraversalTag`` is not convertible to ``incrementable_iterator_tag``
then the programm is ill-formed.
The ``is_readable``, ``is_writable``, ``is_swappable``, and The ``is_readable``, ``is_writable``, ``is_swappable``, and
``traversal_category`` class templates are traits classes. For ``traversal_category`` class templates are traits classes. For
@ -800,4 +809,4 @@ category tags for pointer types.
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS LocalWords: TraversalTag typename lvalues DWA Hmm JGS mis enum