This commit was manufactured by cvs2svn to create branch 'simplify'.

[SVN r20118]
This commit is contained in:
nobody
2003-09-19 18:44:54 +00:00
parent 4968b50fc2
commit 77a89a0b89
69 changed files with 0 additions and 10510 deletions

View File

@ -1,159 +0,0 @@
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
#define BOOST_ITERATOR_CATEGORIES_HPP
#include <boost/config.hpp>
#include <boost/type_traits/conversion_traits.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/detail/iterator.hpp>
namespace boost {
// Return Type Categories
struct readable_iterator_tag { };
struct writable_iterator_tag { };
struct swappable_iterator_tag { };
struct mutable_lvalue_iterator_tag :
virtual public writable_iterator_tag,
virtual public readable_iterator_tag { };
struct constant_lvalue_iterator_tag :
virtual public readable_iterator_tag { };
// Traversal Categories
struct forward_traversal_tag { };
struct bidirectional_traversal_tag : public forward_traversal_tag { };
struct random_access_traversal_tag : public bidirectional_traversal_tag { };
struct error_iterator_tag { };
// Inherit from iterator_base if your iterator defines its own
// return_category and traversal_category. Otherwise, the "old style"
// iterator category will be mapped to the return_category and
// traversal_category.
struct new_iterator_base { };
namespace detail {
struct return_category_from_nested_type {
template <typename Iterator> struct bind {
typedef typename Iterator::return_category type;
};
};
struct traversal_category_from_nested_type {
template <typename Iterator> struct bind {
typedef typename Iterator::traversal_category type;
};
};
template <typename ValueType>
struct choose_lvalue_return {
typedef typename ct_if<is_const<ValueType>::value,
boost::constant_lvalue_iterator_tag,
boost::mutable_lvalue_iterator_tag>::type type;
};
template <typename Category, typename ValueType>
struct iter_category_to_return {
typedef typename ct_if<
is_convertible<Category*, std::forward_iterator_tag*>::value,
typename choose_lvalue_return<ValueType>::type,
typename ct_if<
is_convertible<Category*, std::input_iterator_tag*>::value,
boost::readable_iterator_tag,
typename ct_if<
is_convertible<Category*, std::output_iterator_tag*>::value,
boost::writable_iterator_tag,
boost::error_iterator_tag
>::type
>::type
>::type type;
};
template <typename Category>
struct iter_category_to_traversal {
typedef typename ct_if<
is_convertible<Category*, std::random_access_iterator_tag*>::value,
random_access_traversal_tag,
typename ct_if<
is_convertible<Category*, std::bidirectional_iterator_tag*>::value,
bidirectional_traversal_tag,
forward_traversal_tag
>::type
>::type type;
};
struct return_category_from_old_traits {
template <typename Iterator> class bind {
typedef boost::detail::iterator_traits<Iterator> OldTraits;
typedef typename OldTraits::iterator_category Cat;
typedef typename OldTraits::value_type value_type;
public:
typedef iter_category_to_return<Cat, value_type>::type type;
};
};
struct traversal_category_from_old_traits {
template <typename Iterator> class bind {
typedef boost::detail::iterator_traits<Iterator> OldTraits;
typedef typename OldTraits::iterator_category Cat;
public:
typedef iter_category_to_traversal<Cat>::type type;
};
};
template <typename Iterator>
class choose_return_category {
typedef typename ct_if<is_convertible<Iterator*,
new_iterator_base*>::value,
return_category_from_nested_type,
return_category_from_old_traits>::type Choice;
public:
typedef typename Choice:: template bind<Iterator>::type type;
};
template <typename Iterator>
class choose_traversal_category {
typedef typename ct_if<is_convertible<Iterator*,
new_iterator_base*>::value,
traversal_category_from_nested_type,
traversal_category_from_old_traits>::type Choice;
public:
typedef typename Choice:: template bind<Iterator>::type type;
};
} // namespace detail
template <class Iterator>
struct return_category {
typedef typename detail::choose_return_category<Iterator>::type type;
};
template <class Iterator>
struct traversal_category {
typedef typename detail::choose_traversal_category<Iterator>::type type;
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct return_category<T*>
{
typedef typename ct_if<is_const<T>::value,
constant_lvalue_iterator_tag,
mutable_lvalue_iterator_tag>::type type;
};
template <typename T>
struct traversal_category<T*>
{
typedef random_access_traversal_tag type;
};
#endif
} // namespace boost
#endif // BOOST_ITERATOR_CATEGORIES_HPP

View File

@ -1,172 +0,0 @@
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
#define BOOST_ITERATOR_CONCEPTS_HPP
#include <boost/concept_check.hpp>
#include <boost/iterator_categories.hpp>
#include <boost/type_traits/conversion_traits.hpp>
#include <boost/static_assert.hpp>
namespace boost_concepts {
// Used a different namespace here (instead of "boost") so that the
// concept descriptions do not take for granted the names in
// namespace boost.
//===========================================================================
// Iterator Access Concepts
template <typename Iterator>
class ReadableIteratorConcept {
public:
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename boost::return_category<Iterator>::type return_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
boost::readable_iterator_tag*>::value));
reference r = *i; // or perhaps read(x)
value_type v(r);
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
template <typename Iterator, typename ValueType>
class WritableIteratorConcept {
public:
typedef typename boost::return_category<Iterator>::type return_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
boost::writable_iterator_tag*>::value));
*i = v; // a good alternative could be something like write(x, v)
}
ValueType v;
Iterator i;
};
template <typename Iterator>
class ConstantLvalueIteratorConcept {
public:
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename boost::return_category<Iterator>::type return_category;
void constraints() {
boost::function_requires< ReadableIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
boost::constant_lvalue_iterator_tag*>::value));
BOOST_STATIC_ASSERT((boost::is_same<reference,
const value_type&>::value));
reference v = *i;
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
template <typename Iterator>
class MutableLvalueIteratorConcept {
public:
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename boost::return_category<Iterator>::type return_category;
void constraints() {
boost::function_requires< ReadableIteratorConcept<Iterator> >();
boost::function_requires<
WritableIteratorConcept<Iterator, value_type> >();
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
boost::mutable_lvalue_iterator_tag*>::value));
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
reference v = *i;
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
//===========================================================================
// Iterator Traversal Concepts
template <typename Iterator>
class ForwardIteratorConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
boost::forward_traversal_tag*>::value));
++i;
(void)i++;
}
Iterator i;
};
template <typename Iterator>
class BidirectionalIteratorConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
void constraints() {
boost::function_requires< ForwardIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
boost::bidirectional_traversal_tag*>::value));
--i;
(void)i--;
}
Iterator i;
};
template <typename Iterator>
class RandomAccessIteratorConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename std::iterator_traits<Iterator>::difference_type
difference_type;
void constraints() {
boost::function_requires< BidirectionalIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
boost::random_access_traversal_tag*>::value));
i += n;
i = i + n;
i = n + i;
i -= n;
i = i - n;
n = i - j;
}
difference_type n;
Iterator i, j;
};
} // namespace boost_concepts
#endif // BOOST_ITERATOR_CONCEPTS_HPP

View File

@ -1,73 +0,0 @@
#include <boost/iterator_concepts.hpp>
#include <boost/operators.hpp>
struct new_iterator
: public boost::iterator<std::random_access_iterator_tag, int>,
public boost::new_iterator_base
{
typedef boost::random_access_traversal_tag traversal_category;
typedef boost::mutable_lvalue_iterator_tag return_category;
int& operator*() const { return *m_x; }
new_iterator& operator++() { return *this; }
new_iterator operator++(int) { return *this; }
new_iterator& operator--() { return *this; }
new_iterator operator--(int) { return *this; }
new_iterator& operator+=(std::ptrdiff_t) { return *this; }
new_iterator operator+(std::ptrdiff_t) { return *this; }
new_iterator& operator-=(std::ptrdiff_t) { return *this; }
std::ptrdiff_t operator-(const new_iterator&) const { return 0; }
new_iterator operator-(std::ptrdiff_t) const { return *this; }
bool operator==(const new_iterator&) const { return false; }
bool operator!=(const new_iterator&) const { return false; }
bool operator<(const new_iterator&) const { return false; }
int* m_x;
};
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
struct old_iterator
: public boost::iterator<std::random_access_iterator_tag, int>
{
int& operator*() const { return *m_x; }
old_iterator& operator++() { return *this; }
old_iterator operator++(int) { return *this; }
old_iterator& operator--() { return *this; }
old_iterator operator--(int) { return *this; }
old_iterator& operator+=(std::ptrdiff_t) { return *this; }
old_iterator operator+(std::ptrdiff_t) { return *this; }
old_iterator& operator-=(std::ptrdiff_t) { return *this; }
old_iterator operator-(std::ptrdiff_t) const { return *this; }
std::ptrdiff_t operator-(const old_iterator&) const { return 0; }
bool operator==(const old_iterator&) const { return false; }
bool operator!=(const old_iterator&) const { return false; }
bool operator<(const old_iterator&) const { return false; }
int* m_x;
};
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
int
main()
{
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
boost::function_requires<
boost_concepts::MutableLvalueIteratorConcept<int*> >();
boost::function_requires<
boost_concepts::RandomAccessIteratorConcept<int*> >();
boost::function_requires<
boost_concepts::ConstantLvalueIteratorConcept<const int*> >();
boost::function_requires<
boost_concepts::RandomAccessIteratorConcept<const int*> >();
#endif
boost::function_requires<
boost_concepts::MutableLvalueIteratorConcept<new_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessIteratorConcept<new_iterator> >();
boost::function_requires<
boost_concepts::MutableLvalueIteratorConcept<old_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessIteratorConcept<old_iterator> >();
return 0;
}

View File

@ -1,160 +0,0 @@
<html>
<!--
-- Copyright (c) Jeremy Siek 2000,2001
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. I make no representations about the
-- suitability of this software for any purpose. It is provided "as is"
-- without express or implied warranty.
-->
<head>
<title>Boost Iterator Traits</title>
</head>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../../c++boost.gif"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<h1>Boost Iterator Category Traits</h1>
Header <tt><a href="../../boost/iterator_categories.hpp">boost/iterator_categories.hpp</a></tt>
<p>
The <tt>boost::traversal_category</tt> and
<tt>boost::return_category</tt> traits classes provides access to the
category tags for iterators that model the Boost <a
href="./iterator_concepts.htm">Iterator Concepts</a>, which are a
replacement for the iterator requirements in the C++ standard. The
other associated types of the Boost iterator concepts are accessed
through the <tt>std::iterator_traits</tt> class.
<ul>
<li><tt>traversal_category&lt;Iter&gt;::type</tt>&nbsp;&nbsp; Can the iterator go forward, backward, etc.?
<li><tt>return_category&lt;Iter&gt;::type</tt>&nbsp;&nbsp; Is the iterator read or write only?
Is the dereferenced type an lvalue?
</ul>
<p>
An important feature of the <tt>boost::traversal_category</tt> and
<tt>boost::return_category</tt> classes is that they are <b>backwards
compatible</b>, i.e., they automatically work for iterators for which
there are valid definitions of <tt>std::iterator_traits</tt>. The old
<tt>iterator_category</tt> is mapped to the appropriate traversal and
return categories.
<p>
When creating a new iterator type that is meant to work with
<tt>boost::traversal_category</tt> and
<tt>boost::return_category</tt>, you can either create a
specialization of these classes for your iterator type, or you can
provide all the necessary associated types as nested typedefs. In
this case, your iterator class will need to inherit from
<tt>new_iterator_base</tt> to let the category traits know
that it will be able to find typedefs for <tt>traversal_category</tt>
and <tt>return_category</tt> in you iterator class.
Each of the new iterator requirements will need a category tag.
<pre>
namespace boost {
// Return Type Categories
struct readable_iterator_tag { };
struct writable_iterator_tag { };
struct swappable_iterator_tag { };
struct mutable_lvalue_iterator_tag : virtual public writable_iterator_tag,
virtual public readable_iterator_tag { };
struct constant_lvalue_iterator_tag : public readable_iterator_tag { };
// Traversal Categories
struct forward_traversal_tag { };
struct bidirectional_traversal_tag : public forward_traversal_tag { };
struct random_access_traversal_tag : public bidirectional_traversal_tag { };
}
</pre>
<p>
The following is pseudo-code for the iterator category traits classes.
<pre>
namespace boost {
<i>// Inherit from iterator_base if your iterator defines its own
// return_category and traversal_category. Otherwise, the "old style"
// iterator category will be mapped to the return_category and
// traversal_category.</i>
struct new_iterator_base { };
template &lt;typename Iterator&gt;
struct return_category
{
<b><i>// Pseudo-code</i></b>
if (Iterator inherits from new_iterator_base) {
typedef typename Iterator::return_category type;
} else {
typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
typedef typename OldTraits::iterator_category Cat;
if (Cat inherits from std::forward_iterator_tag)
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag type;
else
typedef boost::mutable_lvalue_iterator_tag type;
else if (Cat inherits from std::input_iterator_tag)
typedef boost::readable_iterator_tag type;
else if (Cat inherits from std::output_iterator_tag)
typedef boost::writable_iterator_tag type;
}
};
template &lt;typename T&gt;
struct return_category&lt;T*&gt;
{
<b><i>// Pseudo-code</i></b>
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag type;
else
typedef boost::mutable_lvalue_iterator_tag type;
};
template &lt;typename Iterator&gt;
struct traversal_category
{
<b><i>// Pseudo-code</i></b>
if (Iterator inherits from new_iterator_base) {
typedef typename Iterator::traversal_category type;
} else {
typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
typedef typename OldTraits::iterator_category Cat;
if (Cat inherits from std::random_access_iterator_tag)
typedef boost::random_access_traversal_tag type;
else if (Cat inherits from std::bidirectional_iterator_tag)
typedef boost::bidirectional_traversal_tag type;
else if (Cat inherits from std::forward_iterator_tag)
typedef boost::forward_traversal_tag type;
}
};
template &lt;typename T&gt;
struct traversal_category&lt;T*&gt;
{
typedef boost::random_access_traversal_tag type;
};
}
</pre>
<hr>
<address><a href="mailto:jsiek@lsc.nd.edu">jeremy siek</a></address>
<!-- Created: Sun Mar 18 14:06:57 EST 2001 -->
<!-- hhmts start -->
Last modified: Mon Mar 19 12:59:30 EST 2001
<!-- hhmts end -->
</body>
</html>

View File

@ -1,37 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
6 150 2325 4275 4350
2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1725 4050 1725 3450
2 1 0 1 0 7 100 0 -1 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
1725 3150 1725 2550
4 0 0 100 0 19 18 0.0000 4 210 3180 375 2550 ForwardTraversalIterator\001
4 0 0 100 0 19 18 0.0000 4 210 3765 225 3450 BidirectionalTraversalIterator\001
4 0 0 100 0 19 18 0.0000 4 210 4125 150 4350 RandomAccessTraversalIterator\001
-6
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4800 3600 4800 2400
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6900 3000 5400 2400
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6900 3000 7500 2400
2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6900 3000 9075 2475
4 0 0 100 0 19 18 0.0000 4 210 2040 6600 2400 WritableIterator\001
4 0 0 100 0 19 18 0.0000 4 210 2145 3900 2400 ReadableIterator\001
4 0 0 50 0 19 18 0.0000 4 210 2835 5700 3300 MutableLvalueIterator\001
4 0 0 50 0 19 18 0.0000 4 270 2355 9075 2400 SwappableIterator\001
4 0 0 50 0 19 18 0.0000 4 210 2970 3825 3900 ConstantLvalueIterator\001

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,663 +0,0 @@
<HTML>
<!--
-- Copyright (c) Jeremy Siek 2000
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. I make no representations about the
-- suitability of this software for any purpose. It is provided "as is"
-- without express or implied warranty.
-->
<!--
-- Copyright (c) 1996-1999
-- Silicon Graphics Computer Systems, Inc.
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Silicon Graphics makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
--
-- Copyright (c) 1994
-- Hewlett-Packard Company
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Hewlett-Packard Company makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
--
-->
<Head>
<Title>Iterator Concepts</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../../c++boost.gif"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<h1>Iterator Concepts</h1>
<p>The standard iterator categories and requirements are flawed because
they use a single hierarchy of requirements to address two orthogonal
issues: <b><i>iterator traversal</i></b> and <b><i>dereference return
type</i></b>. The current iterator requirement hierarchy is mainly
geared towards iterator traversal (hence the category names), while
requirements that address dereference return type sneak in at various
places.
<p>
The iterator requirements should be separated into two hierarchies.
One set of concepts handles the return type semantics:
<ul>
<li><a href="#concept:ReadableIterator">Readable Iterator</a></li>
<li><a href="#concept:WritableIterator">Writable Iterator</a></li>
<li><a href="#concept:SwappableIterator">Swappable Iterator</a></li>
<li><a href="#concept:ConstantLvalueIterator">Constant Lvalue Iterator</a></li>
<li><a href="#concept:MutableLvalueIterator">Mutable Lvalue Iterator</a></li>
</ul>
The other set of concepts handles iterator traversal:
<ul>
<li><a href="#concept:ForwardTraversalIterator">Forward Traversal Iterator</a></li>
<li><a href="#concept:BidirectionalTraversalIterator">Bidirectional Traversal Iterator</a></li>
<li><a href="#concept:RandomAccessTraversalIterator">Random Access Traversal Iterator</a></li>
</ul>
The current Input Iterator and Output Iterator requirements will
continue to be used as is. Note that Input Iterator implies Readable
Iterator and Output Iterator implies Writable Iterator.
<p>
Note: we considered defining a Single-Pass Iterator, which could be
combined with Readable or Writable Iterator to replace the Input and
Output Iterator requirements. We rejected this idea because there are
some differences between Input and Output Iterators that make it hard
to merge them: for example Input Iterator requires Equality Comparable
while Output Iterator does not.
<p></p>
<DIV ALIGN="CENTER"><A NAME="fig:graph-concepts"></A></A>
<TABLE>
<CAPTION ALIGN="TOP"><STRONG>Figure 1:</STRONG>
The iterator concepts and refinement relationships.
</CAPTION>
<TR><TD><IMG SRC="./iterator_concepts.gif" ></TD></TR>
</TABLE>
</DIV>
<p></p>
<h2>Relationship with the standard iterator concepts</h2>
<p>
std::Input Iterator implies boost::ReadableIterator.
<p>
std::Output Iterator implies boost::Writable Iterator.
<p>
std::Forward Iterator refines boost::Forward Iterator and
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
<p>
std::Bidirectional Iterator refines boost::Bidirectional Iterator and
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
<p>
std::Random Access Iterator refines boost::Random Access Iterator and
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
<h3>Notation</h3>
<Table>
<tr>
<td><tt>X</tt></td>
<td>The iterator type.</td>
</tr>
<tr>
<td><tt>T</tt></td>
<td>The value type of <tt>X</tt>, i.e., <tt>std::iterator_traits&lt;X&gt;::value_type</tt>.</td>
</tr>
<tr>
<td><tt>x</tt>, <tt>y</tt></td>
<td>An object of type <tt>X</tt>.</td>
</tr>
<tr>
<td><tt>t</tt></td>
<td>An object of type <tt>T</tt>.</td>
</tr>
</table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:ReadableIterator"></A>
Readable Iterator
</H3>
A Readable Iterator is an iterator that dereferences to produce an
rvalue that is convertible to the <tt>value_type</tt> of the
iterator.
<h3>Associated Types</h3>
<Table border>
<tr>
<td>Value type</td>
<td><tt>std::iterator_traits&lt;X&gt;::value_type</tt></td>
<td>The type of the objects pointed to by the iterator.</td>
</tr>
<tr>
<td>Reference type</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
<td>
The return type of dereferencing the iterator. This
type must be convertible to <tt>T</tt>.
</td>
</tr>
<tr>
<td>Return Category</td>
<td><tt>std::return_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::readable_iterator_tag</tt>
</td>
</tr>
</Table>
<h3>Refinement of</h3>
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>
<h3>Valid expressions</h3>
<Table border>
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
<tr>
<td>Dereference</td>
<td><tt>*x</tt></td>
<td>&nbsp;</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
</tr>
<tr>
<td>Member access</td>
<td><tt>x-&gt;m</tt></td>
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
<td>
If <tt>m</tt> is a data member, the type of <tt>m</tt>.
If <tt>m</tt> is a member function, the return type of <tt>m</tt>.
</td>
</tr>
</table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:WritableIterator"></A>
Writable Iterator
</H3>
A Writable Iterator is an iterator that can be used to store a value
using the dereference-assignment expression.
<h3>Definitions</h3>
If <tt>x</tt> is an Writable Iterator of type <tt>X</tt>, then the
expression <tt>*x = a;</tt> stores the value <tt>a</tt> into
<tt>x</tt>. Note that <tt>operator=</tt>, like other C++ functions,
may be overloaded; it may, in fact, even be a template function. In
general, then, <tt>a</tt> may be any of several different types. A
type <tt>A</tt> belongs to the <i>set of value types</i> of <tt>X</tt>
if, for an object <tt>a</tt> of type <tt>A</tt>, <tt>*x = a;</tt> is
well-defined and does not require performing any non-trivial
conversions on <tt>a</tt>.
<h3>Associated Types</h3>
<Table border>
<tr>
<td>Return Category</td>
<td><tt>std::return_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::writable_iterator_tag</tt>
</td>
</tr>
</Table>
<h3>Refinement of</h3>
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>
<h3>Valid expressions</h3>
<Table border>
<tr>
<TH>Name</TH><TH>Expression</TH><TH>Return type</TH>
</tr>
<tr>
<td>Dereference assignment</td>
<td><tt>*x = a</tt></td>
<td>unspecified</td>
</tr>
</table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:SwappableIterator"></A>
Swappable Iterator
</H3>
A Swappable Iterator is an iterator whose dereferenced values can be
swapped.
<p>
Note: the requirements for Swappable Iterator are dependent on the
issues surrounding <tt>std::swap()</tt> being resolved. Here we assume
that the issue will be resolved by allowing the overload of
<tt>std::swap()</tt> for user-defined types.
<p>
Note: Readable Iterator and Writable Iterator combined implies
Swappable Iterator because of the fully templated
<tt>std::swap()</tt>. However, Swappable Iterator does not imply
Readable Iterator nor Writable Iterator.
<h3>Associated Types</h3>
<Table border>
<tr>
<td>Return Category</td>
<td><tt>std::return_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::swappable_iterator_tag</tt>
</td>
</tr>
</Table>
<h3>Valid expressions</h3>
Of the two valid expressions listed below, only one <b>OR</b> the
other is required. If <tt>std::iter_swap()</tt> is overloaded for
<tt>X</tt> then <tt>std::swap()</tt> is not required. If
<tt>std::iter_swap()</tt> is not overloaded for <tt>X</tt> then the
default (fully templated) version is used, which will call
<tt>std::swap()</tt> (this means changing the current requirements for
<tt>std::iter_swap()</tt>).
<p>
<Table border>
<tr>
<TH>Name</TH><TH>Expression</TH><TH>Return type</TH>
</tr>
<tr>
<td>Iterator Swap</td>
<td><tt>std::iter_swap(x, y)</tt></td>
<td>void</td>
</tr>
<tr>
<td>Dereference and Swap</td>
<td><tt>std::swap(*x, *y)</tt></td>
<td>void</td>
</tr>
</table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:ConstantLvalueIterator"></A>
Constant Lvalue Iterator
</H3>
A Constant Lvalue Iterator is an iterator that dereferences to produce a
const reference to the pointed-to object, i.e., the associated
<tt>reference</tt> type is <tt>const T&amp;</tt>. Changing the value
of or destroying an iterator that models Constant Lvalue Iterator does
not invalidate pointers and references previously obtained from that
iterator.
<h3>Refinement of</h3>
<a href="#concept:ReadableIterator">Readable Iterator</a>
<h3>Associated Types</h3>
<Table border>
<tr>
<td>Reference type</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
<td>
The return type of dereferencing the iterator, which must be
<tt>const T&amp;</tt>.
</td>
</tr>
<!-- I don't think this is needed
<tr>
<td>Pointer type</td>
<td><tt>std::iterator_traits&lt;X&gt;::pointer</tt></td>
<td>
The pointer to the value type, which must be <tt>const T*</tt>.
</td>
</tr>
-->
<tr>
<td>Return Category</td>
<td><tt>std::return_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::constant_lvalue_iterator_tag</tt>
</td>
</tr>
</table>
<!-- these are not necessary now that we use reference as operator* return type
<h3>Valid expressions</h3>
<Table border>
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
<tr>
<td>Dereference</td>
<td><tt>*x</tt></td>
<td>&nbsp;</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
</tr>
<tr>
<td>Member access</td>
<td><tt>x-&gt;m</tt></td>
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
<td>
&nbsp;
</td>
</tr>
</table>
-->
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:MutableLvalueIterator"></A>
Mutable Lvalue Iterator
</H3>
A Mutable Lvalue Iterator is an iterator that dereferences to produce a
reference to the pointed-to object. The associated <tt>reference</tt>
type is <tt>T&amp;</tt>. Changing the value of or destroying an
iterator that models Mutable Lvalue Iterator does not invalidate
pointers and references previously obtained from that iterator.
<h3>Refinement of</h3>
<a href="#concept:ReadableIterator">Readable Iterator</a>,
<a href="#concept:WritableIterator">Writable Iterator</a>,
and <a href="#concept:SwappableIterator">Swappable Iterator</a>.
<h3>Associated Types</h3>
<Table border>
<tr>
<td>Reference type</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
<td>The return type of dereferencing the iterator, which must be
<tt>T&amp;</tt>.</td>
</tr>
<!-- I don't think this is necessary
<tr>
<td>Pointer type</td>
<td><tt>std::iterator_traits&lt;X&gt;::pointer</tt></td>
<td>
The pointer to the value type, which is <tt>T*</tt>.
</td>
</tr>
-->
<tr>
<td>Return Category</td>
<td><tt>std::return_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::mutable_lvalue_iterator_tag</tt>
</td>
</tr>
</table>
<!-- no longer needed since the return type is specified as reference in the readable iterator
<h3>Valid expressions</h3>
<Table border>
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></tr>
<tr>
<td>Dereference</td>
<td><tt>*x</tt></td>
<td>&nbsp;</td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
</tr>
<tr>
<td>Member access</td>
<td><tt>x-&gt;m</tt></td>
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
<td>
&nbsp;
</td>
</tr>
</table>
-->
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:ForwardTraversalIterator"></A>
Forward Traversal Iterator
</H3>
The Forward Iterator is an iterator that can be incremented. Also, it
is permissible to make multiple passes through the iterator's range.
<h3>Refinement of</h3>
<A href="http://www.boost.org/libs/utility/CopyConstructible.html">Copy Constructible</A>,
<A href="http://www.boost.org/libs/utility/Assignable.html">Assignable</A>,
<A href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</A>, and
<A href="http://www.sgi.com/tech/stl/EqualityComparable.html">Equality Comparable</A>
<h3>Associated types</h3>
<Table border>
<tr>
<td>Difference Type</td>
<td><tt>std::iterator_traits&lt;X&gt;::difference_type</tt></td>
<td>
A signed integral type used for representing distances
between iterators that point into the same range.
</td>
</tr>
<tr>
<td>Traversal Category</td>
<td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::forward_traversal_tag</tt>
</td>
</tr>
</Table>
<h3>Valid expressions</h3>
<Table border>
<tr>
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
<TH>Return type</TH>
</tr>
<tr>
<td>Preincrement</td>
<td><tt>++i</tt></td><td>&nbsp;</td><td><tt>X&amp;</tt></td>
</tr>
<tr>
<td>Postincrement</td>
<td><tt>i++</tt></td><td>&nbsp;</td><td>convertible to <tt>const X&amp;</tt></td>
</tr>
</Table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:BidirectionalTraversalIterator"></A>
Bidirectional Traversal Iterator
</H3>
An iterator that can be incremented and decremented.
<h3>Refinement of</h3>
<a href="#concept:ForwardTraversalIterator">Forward Traversal Iterator</a>
<h3>Associated types</h3>
<Table border>
<tr>
<td>Traversal Category</td>
<td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::bidirectional_traversal_tag</tt>
</td>
</tr>
</Table>
<h3>Valid expressions</h3>
<Table border>
<tr>
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
<TH>Return type</TH>
</tr>
<tr><td>Predecrement</td>
<td><tt>--i</tt></td><td>&nbsp;</td><td><tt>X&amp;</tt></td>
</tr>
<tr><td>Postdecrement</td>
<td><tt>i--</tt></td><td>&nbsp;</td><td>convertible to <tt>const X&amp;</tt></td>
</tr>
</table>
<p>
<hr>
<!--------------------------------------------------------------------------->
<H3><A NAME="concept:RandomAccessTraversalIterator"></A>
Random Access Traversal Iterator
</H3>
An iterator that provides constant-time methods for moving forward and
backward in arbitrary-sized steps.
<h3>Refinement of</h3>
<a href="#concept:BidirectionalTraversalIterator">Bidirectional Traversal Iterator</a> and
<A href="http://www.sgi.com/tech/stl/LessThanComparable.html">Less Than Comparable</A> where <tt>&lt;</tt> is a total ordering
<h3>Associated types</h3>
<Table border>
<tr>
<td>Traversal Category</td>
<td><tt>std::traversal_category&lt;X&gt;::type</tt></td>
<td>
A type convertible to <tt>std::random_access_traversal_tag</tt>
</td>
</tr>
</Table>
<h3>Valid expressions</h3>
<Table border>
<tr><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
<TH>Return type</TH>
</tr>
<tr><td>Iterator addition</td>
<td><tt>i += n</tt></td><td>&nbsp;</td><td><tt>X&amp;</tt></td>
</tr>
<tr><td>Iterator addition</td>
<td><tt>i + n</tt> or <tt>n + i</tt></td><td>&nbsp;</td><td><tt>X</tt></td>
</tr>
<tr><td>Iterator subtraction</td>
<td><tt>i -= n</tt></td><td>&nbsp;</td><td><tt>X&amp;</tt></td>
</tr>
<tr><td>Iterator subtraction</td>
<td><tt>i - n</tt></td><td>&nbsp;</td><td><tt>X</tt></td>
</tr>
<tr><td>Difference</td>
<td><tt>i - j</tt></td><td>&nbsp;</td><td><tt>std::iterator_traits&lt;X&gt;::difference_type</tt></td>
</tr>
<tr><td>Element operator</td>
<td><tt>i[n]</tt></td>
<td><tt>X</tt> must also be a model of
<a href="#concept:ReadableIterator">Readable Iterator</a>. </td>
<td><tt>std::iterator_traits&lt;X&gt;::reference</tt></td>
</tr>
<tr><td>Element assignment</td>
<td><tt>i[n] = t</tt></td>
<td><tt>X</tt> must also be a model of
<a href="#concept:WritableIterator">Writable Iterator</a>.</td>
<td>unspecified</td>
</tr>
</table>
<p>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF="../../../../people/jeremy_siek.htm">Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
</TD></TR></TABLE>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,150 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Counting Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="counting-iterator">
<h1 class="title">Counting Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The counting iterator adaptor implements dereference by returning a
reference to the base object. The other operations are implemented by
the base <tt class="literal"><span class="pre">m_iterator</span></tt>, as per the inheritance from
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#counting-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#counting-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class Incrementable, class Category = use_default, class Difference = use_default&gt;
class counting_iterator
: public iterator_adaptor&lt;
counting_iterator&lt;Incrementable, Category, Difference&gt;
, Incrementable
, Incrementable
, /* see details for category */
, Incrementable const&amp;
, Incrementable const*
, /* distance = Difference or a signed integral type */&gt;
{
friend class iterator_core_access;
public:
counting_iterator();
counting_iterator(counting_iterator const&amp; rhs);
counting_iterator(Incrementable x);
private:
typename counting_iterator::reference dereference() const
{
return this-&gt;base_reference();
}
};
</pre>
<dl>
<dt>[<em>Note:</em> implementers are encouraged to provide an implementation of</dt>
<dd><tt class="literal"><span class="pre">distance_to</span></tt> and a <tt class="literal"><span class="pre">difference_type</span></tt> that avoids overflows in
the cases when the <tt class="literal"><span class="pre">Incrementable</span></tt> type is a numeric type.]</dd>
</dl>
<div class="section" id="counting-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="counting-iterator-requirements"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">Incrementable</span></tt> type must be Default Constructible, Copy
Constructible, and Assignable. The default distance is
an implementation defined signed integegral type.</p>
<p>The resulting <tt class="literal"><span class="pre">counting_iterator</span></tt> models Readable Lvalue Iterator.</p>
<p>Furthermore, if you wish to create a counting iterator that is a Forward
Traversal Iterator, then the following expressions must be valid:</p>
<pre class="literal-block">
Incrementable i, j;
++i // pre-increment
i == j // operator equal
</pre>
<p>If you wish to create a counting iterator that is a
Bidirectional Traversal Iterator, then pre-decrement is also required:</p>
<pre class="literal-block">
--i
</pre>
<p>If you wish to create a counting iterator that is a Random Access
Traversal Iterator, then these additional expressions are also
required:</p>
<pre class="literal-block">
counting_iterator::difference_type n;
i += n
n = i - j
i &lt; j
</pre>
</div>
<div class="section" id="counting-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="counting-iterator-operations"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">counting_iterator();</span></tt></p>
<table class="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">A default constructed instance of <tt class="literal"><span class="pre">counting_iterator</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator(counting_iterator</span> <span class="pre">const&amp;</span> <span class="pre">rhs);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">rhs</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator(Incrementable</span> <span class="pre">x);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> with its base
object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="counting_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,23 +0,0 @@
+++++++++++++++++++
Counting Iterator
+++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: counting_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: counting_iterator_ref.rst

View File

@ -1,5 +0,0 @@
The counting iterator adaptor implements dereference by returning a
reference to the base object. The other operations are implemented by
the base ``m_iterator``, as per the inheritance from
``iterator_adaptor``.

View File

@ -1,85 +0,0 @@
::
template <class Incrementable, class Category = use_default, class Difference = use_default>
class counting_iterator
: public iterator_adaptor<
counting_iterator<Incrementable, Category, Difference>
, Incrementable
, Incrementable
, /* see details for category */
, Incrementable const&
, Incrementable const*
, /* distance = Difference or a signed integral type */>
{
friend class iterator_core_access;
public:
counting_iterator();
counting_iterator(counting_iterator const& rhs);
counting_iterator(Incrementable x);
private:
typename counting_iterator::reference dereference() const
{
return this->base_reference();
}
};
[*Note:* implementers are encouraged to provide an implementation of
``distance_to`` and a ``difference_type`` that avoids overflows in
the cases when the ``Incrementable`` type is a numeric type.]
``counting_iterator`` requirements
----------------------------------
The ``Incrementable`` type must be Default Constructible, Copy
Constructible, and Assignable. The default distance is
an implementation defined signed integegral type.
The resulting ``counting_iterator`` models Readable Lvalue Iterator.
Furthermore, if you wish to create a counting iterator that is a Forward
Traversal Iterator, then the following expressions must be valid:
::
Incrementable i, j;
++i // pre-increment
i == j // operator equal
If you wish to create a counting iterator that is a
Bidirectional Traversal Iterator, then pre-decrement is also required:
::
--i
If you wish to create a counting iterator that is a Random Access
Traversal Iterator, then these additional expressions are also
required:
::
counting_iterator::difference_type n;
i += n
n = i - j
i < j
``counting_iterator`` operations
--------------------------------
``counting_iterator();``
:Returns: A default constructed instance of ``counting_iterator``.
``counting_iterator(counting_iterator const& rhs);``
:Returns: An instance of ``counting_iterator`` that is a copy of ``rhs``.
``counting_iterator(Incrementable x);``
:Returns: An instance of ``counting_iterator`` with its base
object copy constructed from ``x``.

View File

@ -1,188 +0,0 @@
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
: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 }
dd {
margin-bottom: 0.5em }
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 {
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 {
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.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.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
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-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 }
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 }

File diff suppressed because it is too large Load Diff

View File

@ -1,398 +0,0 @@
+++++++++++++++++++++++++++++
Iterator Facade and Adaptor
+++++++++++++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:Number: **This document is a revised version of the official** N1476=03-0059
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract: We propose a set of class templates that help programmers
build standard-conforming iterators, both from scratch and
by adapting other iterators.
.. contents:: Table of Contents
============
Motivation
============
Iterators play an important role in modern C++ programming. The
iterator is the central abstraction of the algorithms of the Standard
Library, allowing algorithms to be re-used in in a wide variety of
contexts. The C++ Standard Library contains a wide variety of useful
iterators. Every one of the standard containers comes with constant
and mutable iterators [#mutable]_, and also reverse versions of those
same iterators which traverse the container in the opposite direction.
The Standard also supplies ``istream_iterator`` and
``ostream_iterator`` for reading from and writing to streams,
``insert_iterator``, ``front_insert_iterator`` and
``back_insert_iterator`` for inserting elements into containers, and
``raw_storage_iterator`` for initializing raw memory [7].
Despite the many iterators supplied by the Standard Library, obvious
and useful iterators are missing, and creating new iterator types is
still a common task for C++ programmers. The literature documents
several of these, for example line_iterator [3] and Constant_iterator
[9]. The iterator abstraction is so powerful that we expect
programmers will always need to invent new iterator types.
Although it is easy to create iterators that *almost* conform to the
standard, the iterator requirements contain subtleties which can make
creating an iterator which *actually* conforms quite difficult.
Further, the iterator interface is rich, containing many operators
that are technically redundant and tedious to implement. To automate
the repetitive work of constructing iterators, we propose
``iterator_facade``, an iterator base class template which provides
the rich interface of standard iterators and delegates its
implementation to member functions of the derived class. In addition
to reducing the amount of code necessary to create an iterator, the
``iterator_facade`` also provides compile-time error detection.
Iterator implementation mistakes that often go unnoticed are turned
into compile-time errors because the derived class implementation must
match the expectations of the ``iterator_facade``.
A common pattern of iterator construction is the adaptation of one
iterator to form a new one. The functionality of an iterator is
composed of four orthogonal aspects: traversal, indirection, equality
comparison and distance measurement. Adapting an old iterator to
create a new one often saves work because one can reuse one aspect of
functionality while redefining the other. For example, the Standard
provides ``reverse_iterator``, which adapts any Bidirectional Iterator
by inverting its direction of traversal. As with plain iterators,
iterator adaptors defined outside the Standard have become commonplace
in the literature:
* Checked iter[13] adds bounds-checking to an existing iterator.
* The iterators of the View Template Library[14], which adapts
containers, are themselves adaptors over the underlying iterators.
* Smart iterators [5] adapt an iterator's dereferencing behavior by
applying a function object to the object being referenced and
returning the result.
* Custom iterators [4], in which a variety of adaptor types are enumerated.
* Compound iterators [1], which access a slice out of a container of containers.
* Several iterator adaptors from the MTL [12]. The MTL contains a
strided iterator, where each call to ``operator++()`` moves the
iterator ahead by some constant factor, and a scaled iterator, which
multiplies the dereferenced value by some constant.
.. [#concept] We use the term concept to mean a set of requirements
that a type must satisfy to be used with a particular template
parameter.
.. [#mutable] The term mutable iterator refers to iterators over objects that
can be changed by assigning to the dereferenced iterator, while
constant iterator refers to iterators over objects that cannot be
modified.
To fulfill the need for constructing adaptors, we propose the
``iterator_adaptor`` class template. Instantiations of
``iterator_adaptor`` serve as a base classes for new iterators,
providing the default behavior of forwarding all operations to the
underlying iterator. The user can selectively replace these features
in the derived iterator class. This proposal also includes a number
of more specialized adaptors, such as the ``transform_iterator`` that
applies some user-specified function during the dereference of the
iterator.
========================
Impact on the Standard
========================
This proposal is purely an addition to the C++ standard library.
However, note that this proposal relies on the proposal for New
Iterator Concepts.
========
Design
========
Iterator Concepts
=================
This proposal is formulated in terms of the new ``iterator concepts``
as proposed in `n1477`_, since user-defined and especially adapted
iterators suffer from the well known categorization problems that are
inherent to the current iterator categories.
.. _`n1477`: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html
This proposal does not strictly depend on proposal `n1477`_, as there
is a direct mapping between new and old categories. This proposal
could be reformulated using this mapping if `n1477`_ was not accepted.
Interoperability
================
The question of iterator interoperability is poorly addressed in the
current standard. There are currently two defect reports that are
concerned with interoperability issues.
Issue `179`_ concerns the fact that mutable container iterator types
are only required to be convertible to the corresponding constant
iterator types, but objects of these types are not required to
interoperate in comparison or subtraction expressions. This situation
is tedious in practice and out of line with the way built in types
work. This proposal implements the proposed resolution to issue
`179`_, as most standard library implementations do nowadays. In other
words, if an iterator type A has an implicit or user defined
conversion to an iterator type B, the iterator types are interoperable
and the usual set of operators are available.
Issue `280`_ concerns the current lack of interoperability between
reverse iterator types. The proposed new reverse_iterator template
fixes the issues raised in 280. It provides the desired
interoperability without introducing unwanted overloads.
.. _`179`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
.. _`280`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
Iterator Facade
===============
.. include:: iterator_facade_body.rst
Iterator Adaptor
================
.. include:: iterator_adaptor_body.rst
Specialized Adaptors
====================
This proposal also contains several examples of specialized adaptors
which were easily implemented using ``iterator_adaptor``:
* ``indirect_iterator``, which iterates over iterators, pointers,
or smart pointers and applies an extra level of dereferencing.
* A new ``reverse_iterator``, which inverts the direction of a Base
iterator's motion, while allowing adapted constant and mutable
iterators to interact in the expected ways (unlike those in most
implementations of C++98).
* ``transform_iterator``, which applies a user-defined function object
to the underlying values when dereferenced.
* ``projection_iterator``, which is similar to ``transform_iterator``
except that when dereferenced it returns a reference instead of
a value.
* ``filter_iterator``, which provides a view of an iterator range in
which some elements of the underlying range are skipped.
.. _counting_iterator:
* ``counting_iterator``, which adapts any incrementable type
(e.g. integers, iterators) so that incrementing/decrementing the
adapted iterator and dereferencing it produces successive values of
the Base type.
* ``function_output_iterator``, which makes it easier to create custom
output iterators.
Based on examples in the Boost library, users have generated many new
adaptors, among them a permutation adaptor which applies some
permutation to a random access iterator, and a strided adaptor, which
adapts a random access iterator by multiplying its unit of motion by a
constant factor. In addition, the Boost Graph Library (BGL) uses
iterator adaptors to adapt other graph libraries, such as LEDA [10]
and Stanford GraphBase [8], to the BGL interface (which requires C++
Standard compliant iterators).
===============
Proposed Text
===============
Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
=======================================================================
::
struct use_default;
struct iterator_core_access { /* implementation detail */ };
template <
class Derived
, class Value
, class AccessCategory
, class TraversalCategory
, class Reference = Value&
, class Difference = ptrdiff_t
>
class iterator_facade;
template <
class Derived
, class Base
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor;
template <
class Iterator
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
>
class indirect_iterator;
template <class Iterator>
class reverse_iterator;
template <
class UnaryFunction
, class Iterator
, class Reference = use_default
, class Value = use_default
>
class transform_iterator;
template <class Predicate, class Iterator>
class filter_iterator;
template <
class Incrementable
, class Category = use_default
, class Difference = use_default
>
class counting_iterator
template <class UnaryFunction>
class function_output_iterator;
Iterator facade [lib.iterator.facade]
=====================================
.. include:: iterator_facade_abstract.rst
Class template ``iterator_facade``
----------------------------------
.. include:: iterator_facade_ref.rst
Iterator adaptor [lib.iterator.adaptor]
=======================================
.. include:: iterator_adaptor_abstract.rst
Class template ``iterator_adaptor``
-----------------------------------
.. include:: iterator_adaptor_ref.rst
Specialized adaptors [lib.iterator.special.adaptors]
====================================================
.. The requirements for all of these need to be written *much* more
formally -DWA
[*Note:* The ``enable_if_convertible<X,Y>::type`` expression used in
this section is for exposition purposes. The converting constructors
for specialized adaptors should be only be in an overload set provided
that an object of type ``X`` is implicitly convertible to an object of
type ``Y``. The ``enable_if_convertible`` approach uses SFINAE to
take the constructor out of the overload set when the types are not
implicitly convertible.]
Indirect iterator
-----------------
.. include:: indirect_iterator_abstract.rst
Class template ``indirect_iterator``
....................................
.. include:: indirect_iterator_ref.rst
Reverse iterator
----------------
.. include:: reverse_iterator_abstract.rst
Class template ``reverse_iterator``
...................................
.. include:: reverse_iterator_ref.rst
Transform iterator
------------------
.. include:: transform_iterator_abstract.rst
Class template ``transform_iterator``
.....................................
.. include:: transform_iterator_ref.rst
Filter iterator
---------------
.. include:: filter_iterator_abstract.rst
Class template ``filter_iterator``
..................................
.. include:: filter_iterator_ref.rst
Counting iterator
-----------------
.. include:: counting_iterator_abstract.rst
Class template ``counting_iterator``
....................................
.. include:: counting_iterator_ref.rst
Function output iterator
------------------------
.. include:: function_output_iterator_abstract.rst
Class template ``function_output_iterator``
...........................................
.. include:: function_output_iterator_ref.rst
..
LocalWords: Abrahams Siek Witt istream ostream iter MTL strided interoperate
LocalWords: CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
LocalWords: GraphBase struct ptrdiff UnaryFunction const int typename bool pp
LocalWords: lhs rhs SFINAE markup iff tmp OtherDerived OtherIterator DWA foo
LocalWords: dereferenceable subobject AdaptableUnaryFunction impl pre ifdef'd
LocalWords: OtherIncrementable Coplien

View File

@ -1,196 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Filter Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="filter-iterator">
<h1 class="title">Filter Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped over. A predicate
function object controls which elements are skipped. When the
predicate is applied to an element, if it returns <tt class="literal"><span class="pre">true</span></tt> then the
element is retained and if it returns <tt class="literal"><span class="pre">false</span></tt> then the element is
skipped over. When skipping over elements, it is necessary for the
filter adaptor to know when to stop so as to avoid going past the end
of the underlying range. Therefore the constructor of the filter
iterator takes two iterator parameters: the position for the filtered
iterator and the end of the range.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#filter-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#filter-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class Predicate, class Iterator&gt;
class filter_iterator
: public iterator_adaptor&lt;
filter_iterator&lt;Predicate, Iterator&gt;, Iterator
, use_default
, /* see details */
&gt;
{
public:
filter_iterator();
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
filter_iterator(Iterator x, Iterator end = Iterator());
template&lt;class OtherIterator&gt;
filter_iterator(
filter_iterator&lt;Predicate, OtherIterator&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
Predicate predicate() const;
Iterator end() const;
private: // as-if specification
void increment()
{
++(this-&gt;base_reference());
satisfy_predicate();
}
void satisfy_predicate()
{
while (this-&gt;base() != this-&gt;m_end &amp;&amp; !this-&gt;m_predicate(*this-&gt;base()))
++(this-&gt;base_reference());
}
Predicate m_predicate;
Iterator m_end;
};
</pre>
<div class="section" id="filter-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="filter-iterator-requirements"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></h1>
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> parameter must be a model of Readable Iterator
and Single Pass Iterator. The resulting <tt class="literal"><span class="pre">filter_iterator</span></tt> will be a
model of Forward Traversal Iterator if <tt class="literal"><span class="pre">Iterator</span></tt> is, otherwise the
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be a model of Single Pass Iterator. The
access category of the <tt class="literal"><span class="pre">filter_iterator</span></tt> will be the most refined
standard access category that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<!-- Thomas is going to try implementing filter_iterator so that
it will be bidirectional if the underlying iterator is. -JGS -->
<p>The <tt class="literal"><span class="pre">Predicate</span></tt> must be Assignable, Copy Constructible, and the
expression <tt class="literal"><span class="pre">p(x)</span></tt> must be valid where <tt class="literal"><span class="pre">p</span></tt> is an object of type
<tt class="literal"><span class="pre">Predicate</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of type
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt>, and where the type of
<tt class="literal"><span class="pre">p(x)</span></tt> must be convertible to <tt class="literal"><span class="pre">bool</span></tt>.</p>
</div>
<div class="section" id="filter-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="filter-iterator-operations"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">filter_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> and <tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose
predicate is a default constructed <tt class="literal"><span class="pre">Predicate</span></tt> and
whose <tt class="literal"><span class="pre">end</span></tt> is a default constructed <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">filter_iterator(Predicate</span> <span class="pre">f,</span> <span class="pre">Iterator</span> <span class="pre">x,</span> <span class="pre">Iterator</span> <span class="pre">end</span> <span class="pre">=</span> <span class="pre">Iterator());</span></tt></p>
<table class="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">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters according
to predicate <tt class="literal"><span class="pre">f</span></tt> and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">filter_iterator(Iterator</span> <span class="pre">x,</span> <span class="pre">Iterator</span> <span class="pre">end</span> <span class="pre">=</span> <span class="pre">Iterator());</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters
according to a default constructed <tt class="literal"><span class="pre">Predicate</span></tt>
and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class OtherIterator&gt;
filter_iterator(
filter_iterator&lt;Predicate, OtherIterator&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);``
</pre>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of iterator <tt class="literal"><span class="pre">t</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Predicate</span> <span class="pre">predicate()</span> <span class="pre">const;</span></tt></p>
<table class="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">A copy of the predicate object used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">end()</span> <span class="pre">const;</span></tt></p>
<table class="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">The object <tt class="literal"><span class="pre">end</span></tt> used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="filter_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,23 +0,0 @@
+++++++++++++++++
Filter Iterator
+++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: filter_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: filter_iterator_ref.rst

View File

@ -1,10 +0,0 @@
The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped over. A predicate
function object controls which elements are skipped. When the
predicate is applied to an element, if it returns ``true`` then the
element is retained and if it returns ``false`` then the element is
skipped over. When skipping over elements, it is necessary for the
filter adaptor to know when to stop so as to avoid going past the end
of the underlying range. Therefore the constructor of the filter
iterator takes two iterator parameters: the position for the filtered
iterator and the end of the range.

View File

@ -1,108 +0,0 @@
::
template <class Predicate, class Iterator>
class filter_iterator
: public iterator_adaptor<
filter_iterator<Predicate, Iterator>, Iterator
, use_default
, /* see details */
>
{
public:
filter_iterator();
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
filter_iterator(Iterator x, Iterator end = Iterator());
template<class OtherIterator>
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
Predicate predicate() const;
Iterator end() const;
private: // as-if specification
void increment()
{
++(this->base_reference());
satisfy_predicate();
}
void satisfy_predicate()
{
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
++(this->base_reference());
}
Predicate m_predicate;
Iterator m_end;
};
``filter_iterator`` requirements
--------------------------------
The base ``Iterator`` parameter must be a model of Readable Iterator
and Single Pass Iterator. The resulting ``filter_iterator`` will be a
model of Forward Traversal Iterator if ``Iterator`` is, otherwise the
``filter_iterator`` will be a model of Single Pass Iterator. The
access category of the ``filter_iterator`` will be the most refined
standard access category that is modeled by ``Iterator``.
.. Thomas is going to try implementing filter_iterator so that
it will be bidirectional if the underlying iterator is. -JGS
The ``Predicate`` must be Assignable, Copy Constructible, and the
expression ``p(x)`` must be valid where ``p`` is an object of type
``Predicate``, ``x`` is an object of type
``iterator_traits<Iterator>::value_type``, and where the type of
``p(x)`` must be convertible to ``bool``.
``filter_iterator`` operations
------------------------------
``filter_iterator();``
:Requires: ``Predicate`` and ``Iterator`` must be Default Constructible.
:Returns: a ``filter_iterator`` whose
predicate is a default constructed ``Predicate`` and
whose ``end`` is a default constructed ``Iterator``.
``filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());``
:Returns: A ``filter_iterator`` at position ``x`` that filters according
to predicate ``f`` and that will not increment past ``end``.
``filter_iterator(Iterator x, Iterator end = Iterator());``
:Requires: ``Predicate`` must be Default Constructible.
:Returns: A ``filter_iterator`` at position ``x`` that filters
according to a default constructed ``Predicate``
and that will not increment past ``end``.
::
template <class OtherIterator>
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);``
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: A copy of iterator ``t``.
``Predicate predicate() const;``
:Returns: A copy of the predicate object used to construct ``*this``.
``Iterator end() const;``
:Returns: The object ``end`` used to construct ``*this``.

View File

@ -1,165 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Function Output Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="function-output-iterator">
<h1 class="title">Function Output Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The function output iterator adaptor makes it easier to create custom
output iterators. The adaptor takes a unary function and creates a
model of Output Iterator. Each item assigned to the output iterator is
passed as an argument to the unary function. The motivation for this
iterator is that creating a conforming output iterator is non-trivial,
particularly because the proper implementation usually requires a
proxy object.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#function-output-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#function-output-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#function-output-iterator-output-proxy-operations" id="id3" name="id3"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class UnaryFunction&gt;
class function_output_iterator {
public:
typedef iterator_tag&lt;
writable_iterator_tag
, incrementable_traversal_tag
&gt; iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator(const UnaryFunction&amp; f = UnaryFunction());
struct output_proxy {
output_proxy(UnaryFunction&amp; f);
template &lt;class T&gt; output_proxy&amp; operator=(const T&amp; value);
};
output_proxy operator*();
function_output_iterator&amp; operator++();
function_output_iterator&amp; operator++(int);
};
</pre>
<div class="section" id="function-output-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="function-output-iterator-requirements"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and the
expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid, where <tt class="literal"><span class="pre">f</span></tt> is an object of type
<tt class="literal"><span class="pre">UnaryFunction</span></tt> and <tt class="literal"><span class="pre">x</span></tt> is an object of a type accepted by <tt class="literal"><span class="pre">f</span></tt>.
The resulting <tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable
and Incrementable Iterator concepts.</p>
</div>
<div class="section" id="function-output-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="function-output-iterator-operations"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">function_output_iterator(const</span> <span class="pre">UnaryFunction&amp;</span> <span class="pre">f</span> <span class="pre">=</span> <span class="pre">UnaryFunction());</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">function_output_iterator</span></tt> with
<tt class="literal"><span class="pre">f</span></tt> stored as a data member.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">output_proxy</span> <span class="pre">operator*();</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">output_proxy</span></tt> constructed with
a copy of the unary function <tt class="literal"><span class="pre">f</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">function_output_iterator&amp;</span> <span class="pre">operator++();</span></tt></p>
<table class="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="literal"><span class="pre">*this</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">function_output_iterator&amp;</span> <span class="pre">operator++(int);</span></tt></p>
<table class="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="literal"><span class="pre">*this</span></tt></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="function-output-iterator-output-proxy-operations">
<h1><a class="toc-backref" href="#id3" name="function-output-iterator-output-proxy-operations"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">output_proxy(UnaryFunction&amp;</span> <span class="pre">f);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">output_proxy</span></tt> with <tt class="literal"><span class="pre">f</span></tt> stored as
a data member.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">template</span> <span class="pre">&lt;class</span> <span class="pre">T&gt;</span> <span class="pre">output_proxy&amp;</span> <span class="pre">operator=(const</span> <span class="pre">T&amp;</span> <span class="pre">value);</span></tt></p>
<table class="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">
m_f(value);
return *this;
</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="function_output_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,23 +0,0 @@
++++++++++++++++++++++++++
Function Output Iterator
++++++++++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: function_output_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: function_output_iterator_ref.rst

View File

@ -1,8 +0,0 @@
The function output iterator adaptor makes it easier to create custom
output iterators. The adaptor takes a unary function and creates a
model of Output Iterator. Each item assigned to the output iterator is
passed as an argument to the unary function. The motivation for this
iterator is that creating a conforming output iterator is non-trivial,
particularly because the proper implementation usually requires a
proxy object.

View File

@ -1,77 +0,0 @@
::
template <class UnaryFunction>
class function_output_iterator {
public:
typedef iterator_tag<
writable_iterator_tag
, incrementable_traversal_tag
> iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
struct output_proxy {
output_proxy(UnaryFunction& f);
template <class T> output_proxy& operator=(const T& value);
};
output_proxy operator*();
function_output_iterator& operator++();
function_output_iterator& operator++(int);
};
``function_output_iterator`` requirements
-----------------------------------------
The ``UnaryFunction`` must be Assignable, Copy Constructible, and the
expression ``f(x)`` must be valid, where ``f`` is an object of type
``UnaryFunction`` and ``x`` is an object of a type accepted by ``f``.
The resulting ``function_output_iterator`` is a model of the Writable
and Incrementable Iterator concepts.
``function_output_iterator`` operations
---------------------------------------
``explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());``
:Returns: An instance of ``function_output_iterator`` with
``f`` stored as a data member.
``output_proxy operator*();``
:Returns: An instance of ``output_proxy`` constructed with
a copy of the unary function ``f``.
``function_output_iterator& operator++();``
:Returns: ``*this``
``function_output_iterator& operator++(int);``
:Returns: ``*this``
``function_output_iterator::output_proxy`` operations
-----------------------------------------------------
``output_proxy(UnaryFunction& f);``
:Returns: An instance of ``output_proxy`` with ``f`` stored as
a data member.
``template <class T> output_proxy& operator=(const T& value);``
:Effects:
::
m_f(value);
return *this;

View File

@ -1,188 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>The Boost Iterator Library Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="the-boost-iterator-library-logo">
<h1 class="title">The Boost Iterator Library <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
<hr />
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Jeremy Siek, Thomas Witt</td>
</tr>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="reference" href="mailto:witt&#64;ive.uni-hannover.de">witt&#64;ive.uni-hannover.de</a></td>
</tr>
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="reference" href="http://www.ive.uni-hannover.de">Institute for Transport
Railway Operation and Construction</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. All rights reserved</td>
</tr>
</tbody>
</table>
<table class="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">The Boost Iterator Library contains two parts. The first
is a system of <a class="reference" href="../../../more/generic_programming.html#concept">concepts</a> which extend the C++ standard
iterator requirements. The second is a framework
of components for building iterators based on these
extended concepts and includes several useful iterator
adaptors. The extended iterator concepts have
been carefully designed so that new-style iterators will be
compatible with old-style algorithms, though algorithms may
need to be updated if they want to take full advantage of
the new-style iterators. Several components of this
library have been proposed for the C++ standard technical
report. The components of the Boost Iterator Library
replace the older Boost Iterator Adaptor Library.</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents"><strong>Table of Contents</strong></a></p>
<ul class="simple">
<li><a class="reference" href="#new-style-iterators" id="id5" name="id5">New-Style Iterators</a></li>
<li><a class="reference" href="#iterator-facade-and-adaptor" id="id6" name="id6">Iterator Facade and Adaptor</a></li>
<li><a class="reference" href="#specialized-adaptors" id="id7" name="id7">Specialized Adaptors</a></li>
<li><a class="reference" href="#iterator-utilities" id="id8" name="id8">Iterator Utilities</a><ul>
<li><a class="reference" href="#traits" id="id9" name="id9">Traits</a></li>
<li><a class="reference" href="#testing-and-concept-checking" id="id10" name="id10">Testing and Concept Checking</a></li>
</ul>
</li>
<li><a class="reference" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id11" name="id11">Upgrading from the old Boost Iterator Adaptor Library</a></li>
<li><a class="reference" href="#history" id="id12" name="id12">History</a></li>
</ul>
</div>
<hr />
<div class="section" id="new-style-iterators">
<h1><a class="toc-backref" href="#id5" name="new-style-iterators">New-Style Iterators</a></h1>
<p>The iterator categories defined in C++98 are extremely limiting
because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is
required to return a reference (and not a proxy) when dereferenced,
it is impossible to capture the capabilities of
<tt class="literal"><span class="pre">vector&lt;bool&gt;::iterator</span></tt> using the C++98 categories. This is the
infamous &quot;<tt class="literal"><span class="pre">vector&lt;bool&gt;</span></tt> is not a container, and its iterators
aren't random access iterators&quot;, debacle about which Herb Sutter
wrote two papers for the standards comittee (<a class="reference" href="http://www.gotw.ca/publications/N1185.pdf">n1185</a> and <a class="reference" href="http://www.gotw.ca/publications/N1211.pdf">n1211</a>),
and a <a class="reference" href="http://www.gotw.ca/gotw/050.htm">Guru of the Week</a>. New-style iterators go well beyond
patching up <tt class="literal"><span class="pre">vector&lt;bool&gt;</span></tt>, though: there are lots of other
iterators already in use which can't be adequately represented by
the existing concepts. For details about the new iterator
concepts, see our</p>
<blockquote>
<a class="reference" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a></blockquote>
</div>
<div class="section" id="iterator-facade-and-adaptor">
<h1><a class="toc-backref" href="#id6" name="iterator-facade-and-adaptor">Iterator Facade and Adaptor</a></h1>
<p>Writing standard-conforming iterators is tricky. In order to ease the
implementation of new iterators, the iterator library provides the
<a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> class template, which implements many useful
defaults and compile-time checks designed to help the author iterator
ensure that his iterator is correct. It is common to define a new
iterator which behaves like another iterator, but modifies some aspect
of its behavior. For that purpose, the library supplies the
<a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> class template, which is specially designed to
take advantage of as much of the underlying iterator's behavior as
possible.</p>
<p>Both <a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> and <a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> as well as many of
the <a class="reference" href="#specialized-adaptors">specialized adaptors</a> mentioned below have been proposed for
standardization; see our</p>
<blockquote>
<a class="reference" href="facade-and-adaptor.html">Standard Proposal For Iterator Facade and Adaptor</a></blockquote>
<p>for more details.</p>
</div>
<div class="section" id="specialized-adaptors">
<h1><a class="toc-backref" href="#id7" name="specialized-adaptors">Specialized Adaptors</a></h1>
<p>The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost <a class="reference" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
<ul class="simple">
<li><a class="reference" href="counting_iterator.html"><tt class="literal"><span class="pre">counting_iterator</span></tt></a>: an iterator over a sequence of consecutive values.
Implements a &quot;lazy sequence&quot;</li>
<li><a class="reference" href="filter_iterator.html"><tt class="literal"><span class="pre">filter_iterator</span></tt></a>: an iterator over the subset of elements of some
sequence which satisfy a given predicate</li>
<li><a class="reference" href="indirect_iterator.html"><tt class="literal"><span class="pre">indirect_iterator</span></tt></a>: an iterator over the objects <em>pointed-to</em> by the
elements of some sequence.</li>
<li><a class="reference" href="permutation_iterator.html"><tt class="literal"><span class="pre">permutation_iterator</span></tt></a>: an iterator over the elements of some random-access
sequence, rearranged according to some sequence of integer indices.</li>
<li><a class="reference" href="reverse_iterator.html"><tt class="literal"><span class="pre">reverse_iterator</span></tt></a>: an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's <tt class="literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
<li><a class="reference" href="transform_iterator.html"><tt class="literal"><span class="pre">transform_iterator</span></tt></a>: an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
<tt class="literal"><span class="pre">projection_iterator_adaptor</span></tt>.</li>
</ul>
</div>
<div class="section" id="iterator-utilities">
<h1><a class="toc-backref" href="#id8" name="iterator-utilities">Iterator Utilities</a></h1>
<div class="section" id="traits">
<h2><a class="toc-backref" href="#id9" name="traits">Traits</a></h2>
<ul class="simple">
<li><a class="reference" href="iterator_traits.html"><tt class="literal"><span class="pre">iterator_traits.hpp</span></tt></a>: Provides <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunctions which
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of <tt class="literal"><span class="pre">std::iterator_traits</span></tt>.</li>
<li><a class="reference" href="interoperable.html"><tt class="literal"><span class="pre">interoperable.hpp</span></tt></a>: Provides an <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunction for
testing iterator interoperability</li>
</ul>
</div>
<div class="section" id="testing-and-concept-checking">
<h2><a class="toc-backref" href="#id10" name="testing-and-concept-checking">Testing and Concept Checking</a></h2>
<ul class="simple">
<li><a class="reference" href="iterator_archetypes.html"><tt class="literal"><span class="pre">iterator_archetypes.hpp</span></tt></a>: Add summary here</li>
<li><a class="reference" href="iterator_concepts.html"><tt class="literal"><span class="pre">iterator_concepts.hpp</span></tt></a>: Add summary</li>
</ul>
</div>
</div>
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
<h1><a class="toc-backref" href="#id11" name="upgrading-from-the-old-boost-iterator-adaptor-library">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
<p>Turn your policy class into the body of the iterator</p>
<p>Use transform_iterator with a true reference type for
projection_iterator.</p>
</div>
<div class="section" id="history">
<h1><a class="toc-backref" href="#id12" name="history">History</a></h1>
<p>In 2000 Dave Abrahams was writing an iterator for a container of
pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to
generalize the idea and the Boost Iterator Adaptor library was born.
Dave was inspired by some writings of Andrei Alexandrescu and chose a
policy based design (though he probably didn't capture Andrei's idea
very well - there was only one policy class for all the iterator's
orthogonal properties). Soon Jeremy Siek realized he would need the
library and they worked together to produce a &quot;Boostified&quot; version,
which was reviewed and accepted into the library. They wrote a paper
and made several important revisions of the code.</p>
<p>Eventually, several shortcomings of the older library began to make
the need for a rewrite apparent. Dave and Jeremy started working at
the Santa Cruz C++ committee meeting in 2002, and had quickly
generated a working prototype. Thomas Witt expressed interest and
became the voice of compile-time checking for the project...</p>
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="index.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,226 +0,0 @@
+++++++++++++++++++++++++++++++++++++++++++++++++
The Boost Iterator Library |(logo)|__
+++++++++++++++++++++++++++++++++++++++++++++++++
.. |(logo)| image:: ../../../c++boost.gif
:alt: Boost
__ ../../../index.htm
-------------------------------------
:Authors: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organizations: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:Abstract: The Boost Iterator Library contains two parts. The first
is a system of concepts_ which extend the C++ standard
iterator requirements. The second is a framework
of components for building iterators based on these
extended concepts and includes several useful iterator
adaptors. The extended iterator concepts have
been carefully designed so that new-style iterators will be
compatible with old-style algorithms, though algorithms may
need to be updated if they want to take full advantage of
the new-style iterators. Several components of this
library have been proposed for the C++ standard technical
report. The components of the Boost Iterator Library
replace the older Boost Iterator Adaptor Library.
.. _concepts: ../../../more/generic_programming.html#concept
.. contents:: **Table of Contents**
-------------------------------------
=====================
New-Style Iterators
=====================
The iterator categories defined in C++98 are extremely limiting
because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is
required to return a reference (and not a proxy) when dereferenced,
it is impossible to capture the capabilities of
``vector<bool>::iterator`` using the C++98 categories. This is the
infamous "``vector<bool>`` is not a container, and its iterators
aren't random access iterators", debacle about which Herb Sutter
wrote two papers for the standards comittee (n1185_ and n1211_),
and a `Guru of the Week`__. New-style iterators go well beyond
patching up ``vector<bool>``, though: there are lots of other
iterators already in use which can't be adequately represented by
the existing concepts. For details about the new iterator
concepts, see our
.. _n1185: http://www.gotw.ca/publications/N1185.pdf
.. _n1211: http://www.gotw.ca/publications/N1211.pdf
__ http://www.gotw.ca/gotw/050.htm
`Standard Proposal For New-Style Iterators`__
__ new-iter-concepts.html
=============================
Iterator Facade and Adaptor
=============================
Writing standard-conforming iterators is tricky. In order to ease the
implementation of new iterators, the iterator library provides the
|facade|_ class template, which implements many useful
defaults and compile-time checks designed to help the author iterator
ensure that his iterator is correct. It is common to define a new
iterator which behaves like another iterator, but modifies some aspect
of its behavior. For that purpose, the library supplies the
|adaptor|_ class template, which is specially designed to
take advantage of as much of the underlying iterator's behavior as
possible.
.. |facade| replace:: ``iterator_facade``
.. _facade: iterator_facade.html
.. |adaptor| replace:: ``iterator_adaptor``
.. _adaptor: iterator_adaptor.html
Both |facade|_ and |adaptor|_ as well as many of
the `specialized adaptors`_ mentioned below have been proposed for
standardization; see our
`Standard Proposal For Iterator Facade and Adaptor`__
for more details.
__ facade-and-adaptor.html
======================
Specialized Adaptors
======================
The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost `iterator facade and adaptor`_.
* |counting|_: an iterator over a sequence of consecutive values.
Implements a "lazy sequence"
* |filter|_: an iterator over the subset of elements of some
sequence which satisfy a given predicate
* |indirect|_: an iterator over the objects *pointed-to* by the
elements of some sequence.
* |permutation|_: an iterator over the elements of some random-access
sequence, rearranged according to some sequence of integer indices.
* |reverse|_: an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's ``std::reverse_iterator``.
* |transform|_: an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
``projection_iterator_adaptor``.
.. |counting| replace:: ``counting_iterator``
.. _counting: counting_iterator.html
.. |filter| replace:: ``filter_iterator``
.. _filter: filter_iterator.html
.. |indirect| replace:: ``indirect_iterator``
.. _indirect: indirect_iterator.html
.. |permutation| replace:: ``permutation_iterator``
.. _permutation: permutation_iterator.html
.. |reverse| replace:: ``reverse_iterator``
.. _reverse: reverse_iterator.html
.. |transform| replace:: ``transform_iterator``
.. _transform: transform_iterator.html
====================
Iterator Utilities
====================
Traits
------
* |iterator_traits|_: Provides MPL_\ -compatible metafunctions which
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of ``std::iterator_traits``.
* |interoperable|_: Provides an MPL_\ -compatible metafunction for
testing iterator interoperability
.. |iterator_traits| replace:: ``iterator_traits.hpp``
.. _iterator_traits: iterator_traits.html
.. |interoperable| replace:: ``interoperable.hpp``
.. _interoperable: interoperable.html
.. _MPL: ../../mpl/doc/index.html
Testing and Concept Checking
----------------------------
* |iterator_archetypes|_: Add summary here
* |iterator_concepts|_: Add summary
.. |iterator_archetypes| replace:: ``iterator_archetypes.hpp``
.. _iterator_archetypes: iterator_archetypes.html
.. |iterator_concepts| replace:: ``iterator_concepts.hpp``
.. _iterator_concepts: iterator_concepts.html
=======================================================
Upgrading from the old Boost Iterator Adaptor Library
=======================================================
Turn your policy class into the body of the iterator
Use transform_iterator with a true reference type for
projection_iterator.
=========
History
=========
In 2000 Dave Abrahams was writing an iterator for a container of
pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to
generalize the idea and the Boost Iterator Adaptor library was born.
Dave was inspired by some writings of Andrei Alexandrescu and chose a
policy based design (though he probably didn't capture Andrei's idea
very well - there was only one policy class for all the iterator's
orthogonal properties). Soon Jeremy Siek realized he would need the
library and they worked together to produce a "Boostified" version,
which was reviewed and accepted into the library. They wrote a paper
and made several important revisions of the code.
Eventually, several shortcomings of the older library began to make
the need for a rewrite apparent. Dave and Jeremy started working at
the Santa Cruz C++ committee meeting in 2002, and had quickly
generated a working prototype. Thomas Witt expressed interest and
became the voice of compile-time checking for the project...
..
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS

View File

@ -1,169 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Indirect Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="indirect-iterator">
<h1 class="title">Indirect Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The indirect iterator adapts an iterator by applying an <em>extra</em>
dereference inside of <tt class="literal"><span class="pre">operator*()</span></tt>. For example, this iterator
adaptor makes it possible to view a container of pointers
(e.g. <tt class="literal"><span class="pre">list&lt;foo*&gt;</span></tt>) as if it were a container of the pointed-to type
(e.g. <tt class="literal"><span class="pre">list&lt;foo&gt;</span></tt>) .</p>
<!-- At some point we should add the capability to handle
iterators over smart pointers, which the impl handles. -JGS -->
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#indirect-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#indirect-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;
class Iterator
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
&gt;
class indirect_iterator
: public iterator_adaptor&lt;/* see discussion */&gt;
{
friend class iterator_core_access;
public:
indirect_iterator();
indirect_iterator(Iterator x);
template &lt;
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
&gt;
indirect_iterator(
indirect_iterator&lt;
Iterator2, Value2, Category2, Reference2, Difference2
&gt; const&amp; y
, typename enable_if_convertible&lt;Iterator2, Iterator&gt;::type* = 0 // exposition
);
private: // as-if specification
typename indirect_iterator::reference dereference() const
{
return **this-&gt;base();
}
};
</pre>
<div class="section" id="indirect-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="indirect-iterator-requirements"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of the <tt class="literal"><span class="pre">Iterator</span></tt> template parameter should
itself be dereferenceable. The return type of the <tt class="literal"><span class="pre">operator*</span></tt> for
the <tt class="literal"><span class="pre">value_type</span></tt> must be the same type as the <tt class="literal"><span class="pre">Reference</span></tt> template
parameter. The <tt class="literal"><span class="pre">Value</span></tt> template parameter will be the <tt class="literal"><span class="pre">value_type</span></tt>
for the <tt class="literal"><span class="pre">indirect_iterator</span></tt>, unless <tt class="literal"><span class="pre">Value</span></tt> is const. If <tt class="literal"><span class="pre">Value</span></tt>
is <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>, then <tt class="literal"><span class="pre">value_type</span></tt> will be <em>non-</em> <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>. The
default for <tt class="literal"><span class="pre">Value</span></tt> is</p>
<pre class="literal-block">
iterator_traits&lt; iterator_traits&lt;Iterator&gt;::value_type &gt;::value_type
</pre>
<p>If the default is used for <tt class="literal"><span class="pre">Value</span></tt>, then there must be a valid
specialization of <tt class="literal"><span class="pre">iterator_traits</span></tt> for the value type of the base
iterator.</p>
<p>The <tt class="literal"><span class="pre">Reference</span></tt> parameter will be the <tt class="literal"><span class="pre">reference</span></tt> type of the
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is <tt class="literal"><span class="pre">Value&amp;</span></tt>.</p>
<p>The <tt class="literal"><span class="pre">Category</span></tt> parameter is the <tt class="literal"><span class="pre">iterator_category</span></tt> type for the
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::iterator_category</span></tt>.</p>
<p>The indirect iterator will model the most refined standard traversal
concept that is modeled by the <tt class="literal"><span class="pre">Iterator</span></tt> type. The indirect
iterator will model the most refined standard access concept that is
modeled by the value type of <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
</div>
<div class="section" id="indirect-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="indirect-iterator-operations"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">indirect_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
a default constructed base object.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">indirect_iterator(Iterator</span> <span class="pre">x);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> subobject copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
&gt;
indirect_iterator(
indirect_iterator&lt;
Iterator2, Value2, Category2, Reference2, Difference2
&gt; const&amp; y
, typename enable_if_convertible&lt;Iterator2, Iterator&gt;::type* = 0 // exposition
);
</pre>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator2</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">y</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="indirect_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,23 +0,0 @@
+++++++++++++++++++
Indirect Iterator
+++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: indirect_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: indirect_iterator_ref.rst

View File

@ -1,8 +0,0 @@
The indirect iterator adapts an iterator by applying an *extra*
dereference inside of ``operator*()``. For example, this iterator
adaptor makes it possible to view a container of pointers
(e.g. ``list<foo*>``) as if it were a container of the pointed-to type
(e.g. ``list<foo>``) .
.. At some point we should add the capability to handle
iterators over smart pointers, which the impl handles. -JGS

View File

@ -1,96 +0,0 @@
::
template <
class Iterator
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
>
class indirect_iterator
: public iterator_adaptor</* see discussion */>
{
friend class iterator_core_access;
public:
indirect_iterator();
indirect_iterator(Iterator x);
template <
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
private: // as-if specification
typename indirect_iterator::reference dereference() const
{
return **this->base();
}
};
``indirect_iterator`` requirements
..................................
The ``value_type`` of the ``Iterator`` template parameter should
itself be dereferenceable. The return type of the ``operator*`` for
the ``value_type`` must be the same type as the ``Reference`` template
parameter. The ``Value`` template parameter will be the ``value_type``
for the ``indirect_iterator``, unless ``Value`` is const. If ``Value``
is ``const X``, then ``value_type`` will be *non-* ``const X``. The
default for ``Value`` is
::
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
If the default is used for ``Value``, then there must be a valid
specialization of ``iterator_traits`` for the value type of the base
iterator.
The ``Reference`` parameter will be the ``reference`` type of the
``indirect_iterator``. The default is ``Value&``.
The ``Category`` parameter is the ``iterator_category`` type for the
``indirect_iterator``. The default is
``iterator_traits<Iterator>::iterator_category``.
The indirect iterator will model the most refined standard traversal
concept that is modeled by the ``Iterator`` type. The indirect
iterator will model the most refined standard access concept that is
modeled by the value type of ``Iterator``.
``indirect_iterator`` operations
................................
``indirect_iterator();``
:Requires: ``Iterator`` must be Default Constructible.
:Returns: An instance of ``indirect_iterator`` with
a default constructed base object.
``indirect_iterator(Iterator x);``
:Returns: An instance of ``indirect_iterator`` with
the ``iterator_adaptor`` subobject copy constructed from ``x``.
::
template <
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
:Requires: ``Iterator2`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``indirect_iterator`` that is a copy of ``y``.

View File

@ -1,335 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Iterator Adaptor</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="iterator-adaptor">
<h1 class="title">Iterator Adaptor</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The <tt class="literal"><span class="pre">iterator_adaptor</span></tt> is a base class template derived from an
instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt>. The core interface functions
expected by <tt class="literal"><span class="pre">iterator_facade</span></tt> are implemented in terms of the
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">Base</span></tt> template parameter. A class derived
from <tt class="literal"><span class="pre">iterator_adaptor</span></tt> typically redefines some of the core
interface functions to adapt the behavior of the <tt class="literal"><span class="pre">Base</span></tt> type.
Whether the derived class models any of the standard iterator concepts
depends on the operations supported by the <tt class="literal"><span class="pre">Base</span></tt> type and which
core interface functions of <tt class="literal"><span class="pre">iterator_facade</span></tt> are redefined in the
<tt class="literal"><span class="pre">Derived</span></tt> class.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#introduction" id="id3" name="id3">Introduction</a></li>
<li><a class="reference" href="#reference" id="id4" name="id4">Reference</a><ul>
<li><a class="reference" href="#iterator-adaptor-requirements" id="id5" name="id5"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></li>
<li><a class="reference" href="#iterator-adaptor-public-operations" id="id6" name="id6"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></li>
<li><a class="reference" href="#iterator-adaptor-protected-member-functions" id="id7" name="id7"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></li>
<li><a class="reference" href="#iterator-adaptor-private-member-functions" id="id8" name="id8"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id3" name="introduction">Introduction</a></h1>
<p>The <tt class="literal"><span class="pre">iterator_adaptor</span></tt> class template adapts some <tt class="literal"><span class="pre">Base</span></tt> <a class="footnote-reference" href="#base" id="id1" name="id1"><sup>1</sup></a>
type to create a new iterator. Instantiations of <tt class="literal"><span class="pre">iterator_adaptor</span></tt>
are derived from a corresponding instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt>
and implement the core behaviors in terms of the <tt class="literal"><span class="pre">Base</span></tt> type. In
essence, <tt class="literal"><span class="pre">iterator_adaptor</span></tt> merely forwards all operations to an
instance of the <tt class="literal"><span class="pre">Base</span></tt> type, which it stores as a member.</p>
<table class="footnote" frame="void" id="base" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="base">[1]</a></td><td>The term &quot;Base&quot; here does not refer to a base class and is
not meant to imply the use of derivation. We have followed the lead
of the standard library, which provides a base() function to access
the underlying iterator object of a <tt class="literal"><span class="pre">reverse_iterator</span></tt> adaptor.</td></tr>
</tbody>
</table>
<p>The user of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> creates a class derived from an
instantiation of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> and then selectively
redefines some of the core member functions described in the table
above. The <tt class="literal"><span class="pre">Base</span></tt> type need not meet the full requirements for an
iterator. It need only support the operations used by the core
interface functions of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> that have not been
redefined in the user's derived class.</p>
<p>Several of the template parameters of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> default to
<tt class="literal"><span class="pre">use_default</span></tt>. This allows the user to make use of a default
parameter even when the user wants to specify a parameter later in the
parameter list. Also, the defaults for the corresponding associated
types are fairly complicated, so metaprogramming is required to
compute them, and <tt class="literal"><span class="pre">use_default</span></tt> can help to simplify the
implementation. Finally, <tt class="literal"><span class="pre">use_default</span></tt> is not left unspecified
because specification helps to highlight that the <tt class="literal"><span class="pre">Reference</span></tt>
template parameter may not always be identical to the iterator's
<tt class="literal"><span class="pre">reference</span></tt> type, and will keep users making mistakes based on that
assumption.</p>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id4" name="reference">Reference</a></h1>
<pre class="literal-block">
template &lt;
class Derived
, class Base
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
&gt;
class iterator_adaptor
: public iterator_facade&lt;Derived, /* see <a class="reference" href=":">details</a> ...*/&gt;
{
friend class iterator_core_access;
public:
iterator_adaptor();
explicit iterator_adaptor(Base iter);
Base base() const;
protected:
Base const&amp; base_reference() const;
Base&amp; base_reference();
private: // Core iterator interface for iterator_facade.
typename iterator_adaptor::reference dereference() const;
template &lt;
class OtherDerived, class OtherIterator, class V, class C, class R, class D
&gt;
bool equal(iterator_adaptor&lt;OtherDerived, OtherIterator, V, C, R, D&gt; const&amp; x) const;
void advance(typename iterator_adaptor::difference_type n);
void increment();
void decrement();
template &lt;
class OtherDerived, class OtherIterator, class V, class C, class R, class D
&gt;
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor&lt;OtherDerived, OtherIterator, V, C, R, D&gt; const&amp; y) const;
private:
Base m_iterator;
};
</pre>
<div class="section" id="iterator-adaptor-requirements">
<h2><a class="toc-backref" href="#id5" name="iterator-adaptor-requirements"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></h2>
<p>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a derived class of
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. The <tt class="literal"><span class="pre">Base</span></tt> type must implement the
expressions involving <tt class="literal"><span class="pre">m_iterator</span></tt> in the specifications of those
private member functions of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> that are not
redefined by the <tt class="literal"><span class="pre">Derived</span></tt> class and that are needed to model the
concept corresponding to the <tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">category</span></tt>
typedef according to the requirements of <tt class="literal"><span class="pre">iterator_facade</span></tt>. The
rest of the template parameters specify the types for the member
typedefs in <tt class="literal"><span class="pre">iterator_facade</span></tt>. The following pseudo-code
specifies the traits types for <tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</p>
<pre class="literal-block">
if (Value == use_default)
value_type = iterator_traits&lt;Base&gt;::value_type;
else
value_type = remove_cv&lt;Value&gt;::type;
if (Reference == use_default) {
if (Value == use_default)
reference = iterator_traits&lt;Base&gt;::reference;
else
reference = Value&amp;;
} else
reference = Reference;
if (Distance == use_default)
difference_type = iterator_traits&lt;Base&gt;::difference_type;
else
difference_type = Distance;
if (Category == use_default)
iterator_category = iterator_tag&lt;
access_category&lt; Base &gt;,
traversal_category&lt; Base &gt;
&gt;
else if (Category is an access tag)
iterator_category = iterator_tag&lt;
Category
...
else if (Category is a traversal tag)
...
else
iterator_category = Category;
// Actually the above is wrong. See the use of
// access_category_tag and
// new_category_to_access/iter_category_to_access.
</pre>
<!-- Replaced with new semantics - -thw
if (Category == use_default)
iterator_category = iterator_traits<Base>::iterator_category;
else
iterator_category = Category;
Fix this up!! -->
</div>
<div class="section" id="iterator-adaptor-public-operations">
<h2><a class="toc-backref" href="#id6" name="iterator-adaptor-public-operations"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></h2>
<p><tt class="literal"><span class="pre">iterator_adaptor();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body">The <tt class="literal"><span class="pre">Base</span></tt> type must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> with
<tt class="literal"><span class="pre">m_iterator</span></tt> default constructed.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">iterator_adaptor(Base</span> <span class="pre">iter);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> with
<tt class="literal"><span class="pre">m_iterator</span></tt> copy constructed from <tt class="literal"><span class="pre">iter</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
<table class="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="literal"><span class="pre">m_iterator</span></tt></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="iterator-adaptor-protected-member-functions">
<h2><a class="toc-backref" href="#id7" name="iterator-adaptor-protected-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></h2>
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">const&amp;</span> <span class="pre">base_reference()</span> <span class="pre">const;</span></tt></p>
<table class="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">A const reference to <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Base&amp;</span> <span class="pre">base_reference();</span></tt></p>
<table class="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">A non-const reference to <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="iterator-adaptor-private-member-functions">
<h2><a class="toc-backref" href="#id8" name="iterator-adaptor-private-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></h2>
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">iterator_adaptor::reference</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
<table class="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="literal"><span class="pre">*m_iterator</span></tt></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;
class OtherDerived, class OtherIterator, class V, class C, class R, class D
&gt;
bool equal(iterator_adaptor&lt;OtherDerived, OtherIterator, V, C, R, D&gt; const&amp; x) const;
</pre>
<table class="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="literal"><span class="pre">m_iterator</span> <span class="pre">==</span> <span class="pre">x.base()</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">void</span> <span class="pre">advance(typename</span> <span class="pre">iterator_adaptor::difference_type</span> <span class="pre">n);</span></tt></p>
<table class="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"><tt class="literal"><span class="pre">m_iterator</span> <span class="pre">+=</span> <span class="pre">n;</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">void</span> <span class="pre">increment();</span></tt></p>
<table class="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"><tt class="literal"><span class="pre">++m_iterator;</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">void</span> <span class="pre">decrement();</span></tt></p>
<table class="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"><tt class="literal"><span class="pre">--m_iterator;</span></tt></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;
class OtherDerived, class OtherIterator, class V, class C, class R, class D
&gt;
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor&lt;OtherDerived, OtherIterator, V, C, R, D&gt; const&amp; y) const;
</pre>
<table class="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="literal"><span class="pre">y.base()</span> <span class="pre">-</span> <span class="pre">m_iterator</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="iterator_adaptor.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,32 +0,0 @@
+++++++++++++++++
Iterator Adaptor
+++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: iterator_adaptor_abstract.rst
.. contents:: Table of Contents
Introduction
============
.. include:: iterator_adaptor_body.rst
Reference
=========
.. include:: iterator_adaptor_ref.rst

View File

@ -1,10 +0,0 @@
The ``iterator_adaptor`` is a base class template derived from an
instantiation of ``iterator_facade``. The core interface functions
expected by ``iterator_facade`` are implemented in terms of the
``iterator_adaptor``\ 's ``Base`` template parameter. A class derived
from ``iterator_adaptor`` typically redefines some of the core
interface functions to adapt the behavior of the ``Base`` type.
Whether the derived class models any of the standard iterator concepts
depends on the operations supported by the ``Base`` type and which
core interface functions of ``iterator_facade`` are redefined in the
``Derived`` class.

View File

@ -1,32 +0,0 @@
The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_
type to create a new iterator. Instantiations of ``iterator_adaptor``
are derived from a corresponding instantiation of ``iterator_facade``
and implement the core behaviors in terms of the ``Base`` type. In
essence, ``iterator_adaptor`` merely forwards all operations to an
instance of the ``Base`` type, which it stores as a member.
.. [#base] The term "Base" here does not refer to a base class and is
not meant to imply the use of derivation. We have followed the lead
of the standard library, which provides a base() function to access
the underlying iterator object of a ``reverse_iterator`` adaptor.
The user of ``iterator_adaptor`` creates a class derived from an
instantiation of ``iterator_adaptor`` and then selectively
redefines some of the core member functions described in the table
above. The ``Base`` type need not meet the full requirements for an
iterator. It need only support the operations used by the core
interface functions of ``iterator_adaptor`` that have not been
redefined in the user's derived class.
Several of the template parameters of ``iterator_adaptor`` default to
``use_default``. This allows the user to make use of a default
parameter even when the user wants to specify a parameter later in the
parameter list. Also, the defaults for the corresponding associated
types are fairly complicated, so metaprogramming is required to
compute them, and ``use_default`` can help to simplify the
implementation. Finally, ``use_default`` is not left unspecified
because specification helps to highlight that the ``Reference``
template parameter may not always be identical to the iterator's
``reference`` type, and will keep users making mistakes based on that
assumption.

View File

@ -1,178 +0,0 @@
.. parsed-literal::
template <
class Derived
, class Base
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
: public iterator_facade<Derived, /* see details__ ...\*/>
{
friend class iterator_core_access;
public:
iterator_adaptor();
explicit iterator_adaptor(Base iter);
Base base() const;
protected:
Base const& base_reference() const;
Base& base_reference();
private: // Core iterator interface for iterator_facade.
typename iterator_adaptor::reference dereference() const;
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
void advance(typename iterator_adaptor::difference_type n);
void increment();
void decrement();
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
private:
Base m_iterator;
};
__ :
``iterator_adaptor`` requirements
---------------------------------
The ``Derived`` template parameter must be a derived class of
``iterator_adaptor``. The ``Base`` type must implement the
expressions involving ``m_iterator`` in the specifications of those
private member functions of ``iterator_adaptor`` that are not
redefined by the ``Derived`` class and that are needed to model the
concept corresponding to the ``iterator_adaptor``\ 's ``category``
typedef according to the requirements of ``iterator_facade``. The
rest of the template parameters specify the types for the member
typedefs in ``iterator_facade``. The following pseudo-code
specifies the traits types for ``iterator_adaptor``.
::
if (Value == use_default)
value_type = iterator_traits<Base>::value_type;
else
value_type = remove_cv<Value>::type;
if (Reference == use_default) {
if (Value == use_default)
reference = iterator_traits<Base>::reference;
else
reference = Value&;
} else
reference = Reference;
if (Distance == use_default)
difference_type = iterator_traits<Base>::difference_type;
else
difference_type = Distance;
if (Category == use_default)
iterator_category = iterator_tag<
access_category< Base >,
traversal_category< Base >
>
else if (Category is an access tag)
iterator_category = iterator_tag<
Category
...
else if (Category is a traversal tag)
...
else
iterator_category = Category;
// Actually the above is wrong. See the use of
// access_category_tag and
// new_category_to_access/iter_category_to_access.
.. Replaced with new semantics --thw
if (Category == use_default)
iterator_category = iterator_traits<Base>::iterator_category;
else
iterator_category = Category;
Fix this up!!
``iterator_adaptor`` public operations
--------------------------------------
``iterator_adaptor();``
:Requires: The ``Base`` type must be Default Constructible.
:Returns: An instance of ``iterator_adaptor`` with
``m_iterator`` default constructed.
``explicit iterator_adaptor(Base iter);``
:Returns: An instance of ``iterator_adaptor`` with
``m_iterator`` copy constructed from ``iter``.
``Base base() const;``
:Returns: ``m_iterator``
``iterator_adaptor`` protected member functions
-----------------------------------------------
``Base const& base_reference() const;``
:Returns: A const reference to ``m_iterator``.
``Base& base_reference();``
:Returns: A non-const reference to ``m_iterator``.
``iterator_adaptor`` private member functions
---------------------------------------------
``typename iterator_adaptor::reference dereference() const;``
:Returns: ``*m_iterator``
::
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
:Returns: ``m_iterator == x.base()``
``void advance(typename iterator_adaptor::difference_type n);``
:Effects: ``m_iterator += n;``
``void increment();``
:Effects: ``++m_iterator;``
``void decrement();``
:Effects: ``--m_iterator;``
::
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
:Returns: ``y.base() - m_iterator``

View File

@ -1,580 +0,0 @@
<?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.1: 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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p><tt class="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.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#motivation" id="id10" name="id10">Motivation</a></li>
<li><a class="reference" href="#usage" id="id11" name="id11">Usage</a></li>
<li><a class="reference" href="#iterator-core-access" id="id12" name="id12">Iterator Core Access</a></li>
<li><a class="reference" href="#operator" id="id13" name="id13"><tt class="literal"><span class="pre">operator[]</span></tt></a></li>
<li><a class="reference" href="#id3" id="id14" name="id14"><tt class="literal"><span class="pre">operator-&gt;</span></tt></a></li>
<li><a class="reference" href="#reference" id="id15" name="id15">Reference</a><ul>
<li><a class="reference" href="#id8" id="id16" name="id16"><tt class="literal"><span class="pre">iterator_facade</span></tt> requirements</a></li>
<li><a class="reference" href="#iterator-facade-operations" id="id17" name="id17"><tt class="literal"><span class="pre">iterator_facade</span></tt> operations</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="motivation">
<h1><a class="toc-backref" href="#id10" name="motivation">Motivation</a></h1>
<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="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, <tt class="literal"><span class="pre">difference_type</span></tt>, and
<tt class="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" name="id1">[Cop95]</a> so that the user can specify the behavior of
<tt class="literal"><span class="pre">iterator_facade</span></tt> in a derived class. Former designs used policy
objects to specify the behavior. <tt class="literal"><span class="pre">iterator_facade</span></tt> does not use policy
objects 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="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="literal"><span class="pre">operator++</span></tt> returns the iterator type itself means
that all iterators generated by <tt class="literal"><span class="pre">iterator_facade</span></tt> would be
instantiations of <tt class="literal"><span class="pre">iterator_facade</span></tt>. Cumbersome type generator
metafunctions would be needed to build new parameterized
iterators, and a separate <tt class="literal"><span class="pre">iterator_adaptor</span></tt> layer would be
impossible.</li>
</ol>
</blockquote>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id11" name="usage">Usage</a></h1>
<p>The user of <tt class="literal"><span class="pre">iterator_facade</span></tt> derives his iterator class from an
instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt> which takes the derived iterator
class as the first template parameter. The order of the other
template parameters to <tt class="literal"><span class="pre">iterator_facade</span></tt> 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="literal"><span class="pre">value_type</span></tt> as <tt class="literal"><span class="pre">iterator_facade</span></tt>'s <tt class="literal"><span class="pre">Value</span></tt>
parameter and omit the <tt class="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 class="table">
<colgroup>
<col width="44%" />
<col width="56%" />
</colgroup>
<thead valign="bottom">
<tr><th>Expression</th>
<th>Effects</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">i.dereference()</span></tt></td>
<td>Access the value referred to</td>
</tr>
<tr><td><tt class="literal"><span class="pre">i.equal(j)</span></tt></td>
<td>Compare for equality with <tt class="literal"><span class="pre">j</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">i.increment()</span></tt></td>
<td>Advance by one position</td>
</tr>
<tr><td><tt class="literal"><span class="pre">i.decrement()</span></tt></td>
<td>Retreat by one position</td>
</tr>
<tr><td><tt class="literal"><span class="pre">i.advance(n)</span></tt></td>
<td>Advance by <tt class="literal"><span class="pre">n</span></tt> positions</td>
</tr>
<tr><td><tt class="literal"><span class="pre">i.distance_to(j)</span></tt></td>
<td>Measure the distance to <tt class="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="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="literal"><span class="pre">X</span></tt> is meant to be automatically interoperate with another
iterator type <tt class="literal"><span class="pre">Y</span></tt> (as with constant and mutable iterators) then
there must be an implicit conversion from <tt class="literal"><span class="pre">X</span></tt> to <tt class="literal"><span class="pre">Y</span></tt> or from <tt class="literal"><span class="pre">Y</span></tt>
to <tt class="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">
<h1><a class="toc-backref" href="#id12" name="iterator-core-access">Iterator Core Access</a></h1>
<p><tt class="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="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="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="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="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="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="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">
<h1><a class="toc-backref" href="#id13" name="operator"><tt class="literal"><span class="pre">operator[]</span></tt></a></h1>
<p>The indexing operator for a generalized iterator presents special
challenges. A random access iterator's <tt class="literal"><span class="pre">operator[]</span></tt> is only
required to return something convertible to its <tt class="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" href="counting_iterator.html">counting_iterator</a>), because <tt class="literal"><span class="pre">*(p+n)</span></tt> is a reference
into the temporary iterator <tt class="literal"><span class="pre">p+n</span></tt>, which is destroyed when
<tt class="literal"><span class="pre">operator[]</span></tt> returns.</p>
<p>Writable iterators built with <tt class="literal"><span class="pre">iterator_facade</span></tt> implement the
semantics required by the preferred resolution to <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
adopted by proposal <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html">n1477</a>: the result of <tt class="literal"><span class="pre">p[n]</span></tt> is a proxy object
containing a copy of <tt class="literal"><span class="pre">p+n</span></tt>, and <tt class="literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is equivalent to <tt class="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>. 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="literal"><span class="pre">operator[]</span></tt> which returns an lvalue in the derived
iterator class; it will hide the one supplied by <tt class="literal"><span class="pre">iterator_facade</span></tt>
from clients of her iterator.</p>
<a class="target" id="operator-arrow" name="operator-arrow"></a></div>
<div class="section" id="id3">
<h1><a class="toc-backref" href="#id14" name="id3"><tt class="literal"><span class="pre">operator-&gt;</span></tt></a></h1>
<p>The <tt class="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="literal"><span class="pre">value_type</span></tt>. When the <tt class="literal"><span class="pre">value_type</span></tt>
is a class, however, it must still be possible to access members
through <tt class="literal"><span class="pre">operator-&gt;</span></tt>. Therefore, an iterator whose <tt class="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="literal"><span class="pre">operator-&gt;</span></tt>.</p>
<p>The return type for <tt class="literal"><span class="pre">operator-&gt;</span></tt> and <tt class="literal"><span class="pre">operator[]</span></tt> is not
explicitly specified. Instead it requires each <tt class="literal"><span class="pre">iterator_facade</span></tt>
instantiation to meet the requirements of its <tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
<table class="citation" frame="void" id="cop95" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<col />
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="cop95">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
</tbody>
</table>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id15" name="reference">Reference</a></h1>
<pre class="literal-block">
template &lt;
class Derived
, class Value
, class AccessCategory
, class TraversalCategory
, class Reference = /* see <a class="reference" href="#iterator-facade-requirements">below</a> */
, class Difference = ptrdiff_t
&gt;
class iterator_facade {
public:
typedef remove_cv&lt;Value&gt;::type value_type;
typedef Reference reference;
typedef /* see <a class="reference" href="#operator-arrow">description of operator-&gt;</a> */ pointer;
typedef Difference difference_type;
typedef iterator_tag&lt;AccessCategory, TraversalCategory&gt; iterator_category;
reference operator*() const;
/* see <a class="reference" href="#operator-arrow">below</a> */ operator-&gt;() const;
/* see <a class="reference" 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;
};
// Comparison operators
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type // exposition
operator ==(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator !=(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator &lt;(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator &lt;=(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator &gt;(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator &gt;=(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator &gt;=(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
// Iterator difference
template &lt;class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2&gt;
typename enable_if_interoperable&lt;Dr1, Dr2, bool&gt;::type
operator -(iterator_facade&lt;Dr1, V1, AC1, TC1, R1, D1&gt; const&amp; lhs,
iterator_facade&lt;Dr2, V2, AC2, TC2, R2, D2&gt; const&amp; rhs);
// Iterator addition
template &lt;class Derived, class V, class AC, class TC, class R, class D&gt;
Derived operator+ (iterator_facade&lt;Derived, V, AC, TC, R, D&gt; const&amp;,
typename Derived::difference_type n)
</pre>
<p>[<em>Note:</em> The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt> template used above is for exposition
purposes. The member operators should be only be in an overload set
provided the derived types <tt class="literal"><span class="pre">Dr1</span></tt> and <tt class="literal"><span class="pre">Dr2</span></tt> are interoperable, by
which we mean they are convertible to each other. The
<tt class="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.]</p>
<!-- we need a new label here because the presence of markup in the
title prevents an automatic link from being generated -->
<a class="target" id="iterator-facade-requirements" name="iterator-facade-requirements"></a><div class="section" id="id8">
<h2><a class="toc-backref" href="#id16" name="id8"><tt class="literal"><span class="pre">iterator_facade</span></tt> requirements</a></h2>
<p>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a class derived from
<tt class="literal"><span class="pre">iterator_facade</span></tt>.</p>
<p>The default for the <tt class="literal"><span class="pre">Reference</span></tt> parameter is <tt class="literal"><span class="pre">Value&amp;</span></tt> if the
access category for <tt class="literal"><span class="pre">iterator_facade</span></tt> is implicitly convertible to
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt>, and <tt class="literal"><span class="pre">const</span> <span class="pre">Value&amp;</span></tt> otherwise.</p>
<p>The following table describes the other requirements on the
<tt class="literal"><span class="pre">Derived</span></tt> parameter. Depending on the resulting iterator's
<tt class="literal"><span class="pre">iterator_category</span></tt>, a subset of the expressions listed in the table
are required to be valid. The operations in the first column must be
accessible to member functions of class <tt class="literal"><span class="pre">iterator_core_access</span></tt>.</p>
<p>In the table below, <tt class="literal"><span class="pre">X</span></tt> is the derived iterator type, <tt class="literal"><span class="pre">a</span></tt> is an
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are objects of type <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>,
<tt class="literal"><span class="pre">n</span></tt> is an object of <tt class="literal"><span class="pre">X::difference_type</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is a constant
object of a single pass iterator type interoperable with X, and <tt class="literal"><span class="pre">z</span></tt>
is a constant object of a random access traversal iterator type
interoperable with <tt class="literal"><span class="pre">X</span></tt>.</p>
<table border class="table">
<colgroup>
<col width="19%" />
<col width="18%" />
<col width="36%" />
<col width="26%" />
</colgroup>
<thead valign="bottom">
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Note</th>
<th>Required to implement
Iterator Concept(s)</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">c.dereference()</span></tt></td>
<td><tt class="literal"><span class="pre">X::reference</span></tt></td>
<td>&nbsp;</td>
<td>Readable Iterator, Writable
Iterator</td>
</tr>
<tr><td><tt class="literal"><span class="pre">c.equal(b)</span></tt></td>
<td>convertible to bool</td>
<td>true iff <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are
equivalent.</td>
<td>Single Pass Iterator</td>
</tr>
<tr><td><tt class="literal"><span class="pre">c.equal(y)</span></tt></td>
<td>convertible to bool</td>
<td>true iff <tt class="literal"><span class="pre">c</span></tt> and <tt class="literal"><span class="pre">y</span></tt> refer to the
same position. Implements <tt class="literal"><span class="pre">c</span> <span class="pre">==</span> <span class="pre">y</span></tt>
and <tt class="literal"><span class="pre">c</span> <span class="pre">!=</span> <span class="pre">y</span></tt>.</td>
<td>Single Pass Iterator</td>
</tr>
<tr><td><tt class="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="literal"><span class="pre">a.increment()</span></tt></td>
<td>unused</td>
<td>&nbsp;</td>
<td>Incrementable Iterator</td>
</tr>
<tr><td><tt class="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="literal"><span class="pre">c.distance_to(b)</span></tt></td>
<td>convertible to
X::difference_type</td>
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">b)</span></tt></td>
<td>Random Access Traversal
Iterator</td>
</tr>
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
<td>convertible to
X::difference_type</td>
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">z)</span></tt>.
Implements <tt class="literal"><span class="pre">c</span> <span class="pre">-</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre">&lt;</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span>
<span class="pre">&lt;=</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre">&gt;</span> <span class="pre">z</span></tt>, and <tt class="literal"><span class="pre">c</span> <span class="pre">&gt;=</span> <span class="pre">c</span></tt>.</td>
<td>Random Access Traversal
Iterator</td>
</tr>
</tbody>
</table>
<!-- We should explain more about how the
functions in the interface of iterator_facade
are there conditionally. -JGS -->
</div>
<div class="section" id="iterator-facade-operations">
<h2><a class="toc-backref" href="#id17" name="iterator-facade-operations"><tt class="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="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="literal"><span class="pre">iterator_core_access</span></tt>.</p>
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
<table class="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="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="literal"><span class="pre">operator-&gt;()</span> <span class="pre">const;</span></tt> (see <a class="reference" href="#operator-arrow">below</a>)</p>
<table class="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="literal"><span class="pre">X::reference</span></tt> is a reference type, returns an object
of type <tt class="literal"><span class="pre">X::pointer</span></tt> equal to:</p>
<pre class="literal-block">
&amp;static_cast&lt;Derived const*&gt;(this)-&gt;dereference()
</pre>
<p>Otherwise returns an object of unspecified type such that, given an
object <tt class="literal"><span class="pre">a</span></tt> of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">a-&gt;m</span></tt> is equivalent to <tt class="literal"><span class="pre">(w</span> <span class="pre">=</span> <span class="pre">*a,</span>
<span class="pre">w.m)</span></tt> for some temporary object <tt class="literal"><span class="pre">w</span></tt> of type <tt class="literal"><span class="pre">X::value_type</span></tt>.</p>
<p class="last">The type <tt class="literal"><span class="pre">X::pointer</span></tt> is <tt class="literal"><span class="pre">Value*</span></tt> if the access category for
<tt class="literal"><span class="pre">X</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">writable_iterator_tag</span></tt>, and
<tt class="literal"><span class="pre">Value</span> <span class="pre">const*</span></tt> otherwise.</p>
</td>
</tr>
</tbody>
</table>
<a class="target" id="brackets" name="brackets"></a><p><em>unspecified</em> <tt class="literal"><span class="pre">operator[](difference_type</span> <span class="pre">n)</span> <span class="pre">const;</span></tt></p>
<table class="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="literal"><span class="pre">X::reference</span></tt> and holding a copy
<em>p</em> of <tt class="literal"><span class="pre">a+n</span></tt> such that, for a constant object <tt class="literal"><span class="pre">v</span></tt> of type
<tt class="literal"><span class="pre">X::value_type</span></tt>, <tt class="literal"><span class="pre">X::reference(a[n]</span> <span class="pre">=</span> <span class="pre">v)</span></tt> is equivalent
to <tt class="literal"><span class="pre">p</span> <span class="pre">=</span> <span class="pre">v</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Derived&amp;</span> <span class="pre">operator++();</span></tt></p>
<table class="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 *this;
</pre>
</td>
</tr>
</tbody>
</table>
<!-- I realize that the committee is moving away from specifying things
like this in terms of code, but I worried about the imprecision of
saying that a core interface function is invoked without describing
the downcast. An alternative to what I did would be to mention it
above where we talk about accessibility. -->
<p><tt class="literal"><span class="pre">Derived</span> <span class="pre">operator++(int);</span></tt></p>
<table class="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="literal"><span class="pre">Derived&amp;</span> <span class="pre">operator--();</span></tt></p>
<table class="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 *this;
</pre>
</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Derived</span> <span class="pre">operator--(int);</span></tt></p>
<table class="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="literal"><span class="pre">Derived&amp;</span> <span class="pre">operator+=(difference_type</span> <span class="pre">n);</span></tt></p>
<table class="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 *this;
</pre>
</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Derived&amp;</span> <span class="pre">operator-=(difference_type</span> <span class="pre">n);</span></tt></p>
<table class="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 *this;
</pre>
</td>
</tr>
</tbody>
</table>
<p><tt class="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="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">Derived tmp(static_cast&lt;Derived const*&gt;(this));
return tmp -= n;</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">static_cast&lt;Derived</span> <span class="pre">const*&gt;(this)-&gt;advance(-n);</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="iterator_facade.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,33 +0,0 @@
++++++++++++++++
Iterator Facade
++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: iterator_facade_abstract.rst
.. contents:: Table of Contents
Motivation
----------
.. include:: iterator_facade_body.rst
Reference
---------
.. include:: iterator_facade_ref.rst

View File

@ -1,4 +0,0 @@
``iterator_facade`` 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.

View File

@ -1,180 +0,0 @@
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:
* dereferencing
* incrementing
* decrementing
* equality comparison
* random-access motion
* distance measurement
In addition to the behaviors listed above, the core interface elements
include the associated types exposed through iterator traits:
``value_type``, ``reference``, ``difference_type``, and
``iterator_category``.
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
[Cop95]_ so that the user can specify the behavior of
``iterator_facade`` in a derived class. Former designs used policy
objects to specify the behavior. ``iterator_facade`` does not use policy
objects for several reasons:
1. the creation and eventual copying of the policy object may create
overhead that can be avoided with the current approach.
2. The policy object approach does not allow for custom constructors
on the created iterator types, an essential feature if
``iterator_facade`` should be used in other library
implementations.
3. Without the use of CRTP, the standard requirement that an
iterator's ``operator++`` returns the iterator type itself means
that all iterators generated by ``iterator_facade`` would be
instantiations of ``iterator_facade``. Cumbersome type generator
metafunctions would be needed to build new parameterized
iterators, and a separate ``iterator_adaptor`` layer would be
impossible.
Usage
-----
The user of ``iterator_facade`` derives his iterator class from an
instantiation of ``iterator_facade`` which takes the derived iterator
class as the first template parameter. The order of the other
template parameters to ``iterator_facade`` 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 ``value_type`` as ``iterator_facade``\ 's ``Value``
parameter and omit the ``Reference`` parameter which follows.
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.
+------------------------+-------------------------------+
|Expression |Effects |
+========================+===============================+
|``i.dereference()`` |Access the value referred to |
+------------------------+-------------------------------+
|``i.equal(j)`` |Compare for equality with ``j``|
+------------------------+-------------------------------+
|``i.increment()`` |Advance by one position |
+------------------------+-------------------------------+
|``i.decrement()`` |Retreat by one position |
+------------------------+-------------------------------+
|``i.advance(n)`` |Advance by ``n`` positions |
+------------------------+-------------------------------+
|``i.distance_to(j)`` |Measure the distance to ``j`` |
+------------------------+-------------------------------+
.. Should we add a comment that a zero overhead implementation of iterator_facade
is possible with proper inlining?
In addition to implementing the core interface functions, an iterator
derived from ``iterator_facade`` 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 ``X`` is meant to be automatically interoperate with another
iterator type ``Y`` (as with constant and mutable iterators) then
there must be an implicit conversion from ``X`` to ``Y`` or from ``Y``
to ``X`` (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.
Iterator Core Access
--------------------
``iterator_facade`` 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.
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 ``iterator_facade`` without fear of
breaking code that was accessing the public core member functions
directly.
In a naive implementation, keeping the derived class' core member
functions private would require it to grant friendship to
``iterator_facade`` and each of the seven operators. In order to
reduce the burden of limiting access, ``iterator_core_access`` 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 ``iterator_core_access`` to make his core
member functions available to the library.
.. This is no long uptodate -thw
.. Yes it is; I made sure of it! -DWA
``iterator_core_access`` 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
``iterator_core_access`` used public member functions it would not
open a safety loophole, as every core member function preserves the
invariants of the iterator.
``operator[]``
--------------
The indexing operator for a generalized iterator presents special
challenges. A random access iterator's ``operator[]`` is only
required to return something convertible to its ``value_type``.
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. `counting_iterator`__), because ``*(p+n)`` is a reference
into the temporary iterator ``p+n``, which is destroyed when
``operator[]`` returns.
__ counting_iterator.html
Writable iterators built with ``iterator_facade`` implement the
semantics required by the preferred resolution to `issue 299`_ and
adopted by proposal `n1477`_: the result of ``p[n]`` is a proxy object
containing a copy of ``p+n``, and ``p[n] = x`` is equivalent to ``*(p
+ n) = x``. 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 ``operator[]`` which returns an lvalue in the derived
iterator class; it will hide the one supplied by ``iterator_facade``
from clients of her iterator.
.. _`n1477`: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html
.. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`operator arrow`:
``operator->``
--------------
The ``reference`` 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 ``value_type``. When the ``value_type``
is a class, however, it must still be possible to access members
through ``operator->``. Therefore, an iterator whose ``reference``
type is not in fact a reference must return a proxy containing a copy
of the referenced value from its ``operator->``.
The return type for ``operator->`` and ``operator[]`` is not
explicitly specified. Instead it requires each ``iterator_facade``
instantiation to meet the requirements of its ``iterator_category``.
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.

View File

@ -1,284 +0,0 @@
.. parsed-literal::
template <
class Derived
, class Value
, class AccessCategory
, class TraversalCategory
, class Reference = /* see below__ \*/
, class Difference = ptrdiff_t
>
class iterator_facade {
public:
typedef remove_cv<Value>::type value_type;
typedef Reference reference;
typedef /* see `description of operator->`__ \*/ pointer;
typedef Difference difference_type;
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
reference operator\*() const;
/* see below__ \*/ operator->() const;
/* see below__ \*/ operator[](difference_type n) const;
Derived& operator++();
Derived operator++(int);
Derived& operator--();
Derived operator--(int);
Derived& operator+=(difference_type n);
Derived& operator-=(difference_type n);
Derived operator-(difference_type n) const;
};
// Comparison operators
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
// Iterator difference
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
// Iterator addition
template <class Derived, class V, class AC, class TC, class R, class D>
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
typename Derived::difference_type n)
__ `iterator facade requirements`_
__ `operator arrow`_
__ `operator arrow`_
__ brackets_
[*Note:* The ``enable_if_interoperable`` template used above is for exposition
purposes. The member operators should be only be in an overload set
provided the derived types ``Dr1`` and ``Dr2`` are interoperable, by
which we mean they are convertible to each other. The
``enable_if_interoperable`` approach uses SFINAE to take the operators
out of the overload set when the types are not interoperable.]
.. we need a new label here because the presence of markup in the
title prevents an automatic link from being generated
.. _iterator facade requirements:
``iterator_facade`` requirements
................................
The ``Derived`` template parameter must be a class derived from
``iterator_facade``.
The default for the ``Reference`` parameter is ``Value&`` if the
access category for ``iterator_facade`` is implicitly convertible to
``writable_iterator_tag``, and ``const Value&`` otherwise.
The following table describes the other requirements on the
``Derived`` parameter. Depending on the resulting iterator's
``iterator_category``, a subset of the expressions listed in the table
are required to be valid. The operations in the first column must be
accessible to member functions of class ``iterator_core_access``.
In the table below, ``X`` is the derived iterator type, ``a`` is an
object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
``n`` is an object of ``X::difference_type``, ``y`` is a constant
object of a single pass iterator type interoperable with X, and ``z``
is a constant object of a random access traversal iterator type
interoperable with ``X``.
+--------------------+-------------------+-------------------------------------+---------------------------+
|Expression |Return Type |Assertion/Note |Required to implement |
| | | |Iterator Concept(s) |
+====================+===================+=====================================+===========================+
|``c.dereference()`` |``X::reference`` | |Readable Iterator, Writable|
| | | |Iterator |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``c.equal(b)`` |convertible to bool|true iff ``b`` and ``c`` are |Single Pass Iterator |
| | |equivalent. | |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``c.equal(y)`` |convertible to bool|true iff ``c`` and ``y`` refer to the|Single Pass Iterator |
| | |same position. Implements ``c == y``| |
| | |and ``c != y``. | |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``a.advance(n)`` |unused | |Random Access Traversal |
| | | |Iterator |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``a.increment()`` |unused | |Incrementable Iterator |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``a.decrement()`` |unused | |Bidirectional Traversal |
| | | |Iterator |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal |
| |X::difference_type | |Iterator |
+--------------------+-------------------+-------------------------------------+---------------------------+
|``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal |
| |X::difference_type |Implements ``c - z``, ``c < z``, ``c |Iterator |
| | |<= z``, ``c > z``, and ``c >= c``. | |
+--------------------+-------------------+-------------------------------------+---------------------------+
.. We should explain more about how the
functions in the interface of iterator_facade
are there conditionally. -JGS
``iterator_facade`` operations
..............................
The operations in this section are described in terms of operations on
the core interface of ``Derived`` which may be inaccessible
(i.e. private). The implementation should access these operations
through member functions of class ``iterator_core_access``.
``reference operator*() const;``
:Returns: ``static_cast<Derived const*>(this)->dereference()``
``operator->() const;`` (see below__)
__ `operator arrow`_
:Returns: If ``X::reference`` is a reference type, returns an object
of type ``X::pointer`` equal to::
&static_cast<Derived const*>(this)->dereference()
Otherwise returns an object of unspecified type such that, given an
object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
w.m)`` for some temporary object ``w`` of type ``X::value_type``.
The type ``X::pointer`` is ``Value*`` if the access category for
``X`` is implicitly convertible to ``writable_iterator_tag``, and
``Value const*`` otherwise.
.. _brackets:
*unspecified* ``operator[](difference_type n) const;``
:Returns: an object convertible to ``X::reference`` and holding a copy
*p* of ``a+n`` such that, for a constant object ``v`` of type
``X::value_type``, ``X::reference(a[n] = v)`` is equivalent
to ``p = v``.
``Derived& operator++();``
:Effects:
::
static_cast<Derived*>(this)->increment();
return *this;
.. I realize that the committee is moving away from specifying things
like this in terms of code, but I worried about the imprecision of
saying that a core interface function is invoked without describing
the downcast. An alternative to what I did would be to mention it
above where we talk about accessibility.
``Derived operator++(int);``
:Effects:
::
Derived tmp(static_cast<Derived const*>(this));
++*this;
return tmp;
``Derived& operator--();``
:Effects:
::
static_cast<Derived*>(this)->decrement();
return *this;
``Derived operator--(int);``
:Effects:
::
Derived tmp(static_cast<Derived const*>(this));
--*this;
return tmp;
``Derived& operator+=(difference_type n);``
:Effects:
::
static_cast<Derived*>(this)->advance(n);
return *this;
``Derived& operator-=(difference_type n);``
:Effects:
::
static_cast<Derived*>(this)->advance(-n);
return *this;
``Derived operator-(difference_type n) const;``
:Effects:
Derived tmp(static_cast<Derived const*>(this));
return tmp -= n;
:Returns: ``static_cast<Derived const*>(this)->advance(-n);``

View File

@ -1,952 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>New Iterator Concepts</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="2003-08-14" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="new-iterator-concepts">
<h1 class="title">New Iterator Concepts</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <a class="last reference" 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>2003-08-14</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</td>
</tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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 system of iterator concepts that treat
access and positioning independently. This allows the
concepts to more closely match the requirements
of algorithms and provides better categorizations
of iterators that are used in practice. This proposal
is a revision of paper <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>.</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#motivation" id="id1" name="id1">Motivation</a></li>
<li><a class="reference" href="#impact-on-the-standard" id="id2" name="id2">Impact on the Standard</a></li>
<li><a class="reference" href="#design" id="id3" name="id3">Design</a></li>
<li><a class="reference" href="#proposed-text" id="id4" name="id4">Proposed Text</a><ul>
<li><a class="reference" href="#addition-to-lib-iterator-requirements" id="id5" name="id5">Addition to [lib.iterator.requirements]</a><ul>
<li><a class="reference" href="#iterator-value-access-concepts-lib-iterator-value-access" id="id6" name="id6">Iterator Value Access Concepts [lib.iterator.value.access]</a><ul>
<li><a class="reference" href="#readable-iterators-lib-readable-iterators" id="id7" name="id7">Readable Iterators [lib.readable.iterators]</a></li>
<li><a class="reference" href="#writable-iterators-lib-writable-iterators" id="id8" name="id8">Writable Iterators [lib.writable.iterators]</a></li>
<li><a class="reference" href="#swappable-iterators-lib-swappable-iterators" id="id9" name="id9">Swappable Iterators [lib.swappable.iterators]</a></li>
<li><a class="reference" href="#readable-lvalue-iterators-lib-readable-lvalue-iterators" id="id10" name="id10">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></li>
<li><a class="reference" href="#writable-lvalue-iterators-lib-writable-lvalue-iterators" id="id11" name="id11">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></li>
</ul>
</li>
<li><a class="reference" href="#iterator-traversal-concepts-lib-iterator-traversal" id="id12" name="id12">Iterator Traversal Concepts [lib.iterator.traversal]</a><ul>
<li><a class="reference" href="#incrementable-iterators-lib-incrementable-iterators" id="id13" name="id13">Incrementable Iterators [lib.incrementable.iterators]</a></li>
<li><a class="reference" href="#single-pass-iterators-lib-single-pass-iterators" id="id14" name="id14">Single Pass Iterators [lib.single.pass.iterators]</a></li>
<li><a class="reference" href="#forward-traversal-iterators-lib-forward-traversal-iterators" id="id15" name="id15">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></li>
<li><a class="reference" href="#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators" id="id16" name="id16">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></li>
<li><a class="reference" href="#random-access-traversal-iterators-lib-random-access-traversal-iterators" id="id17" name="id17">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#addition-to-lib-iterator-synopsis" id="id18" name="id18">Addition to [lib.iterator.synopsis]</a></li>
<li><a class="reference" href="#addition-to-lib-iterator-traits" id="id19" name="id19">Addition to [lib.iterator.traits]</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="motivation">
<h1><a class="toc-backref" href="#id1" name="motivation">Motivation</a></h1>
<p>The standard iterator categories and requirements are flawed because
they use a single hierarchy of concepts to address two orthogonal
issues: <em>iterator traversal</em> and <em>value access</em>. As a result, many
algorithms with requirements expressed in terms of the iterator
categories are too strict. Also, many real-world iterators can not be
accurately categorized. A proxy-based iterator with random-access
traversal, for example, may only legally have a category of &quot;input
iterator&quot;, so generic algorithms are unable to take advantage of its
random-access capabilities. The current iterator concept hierarchy is
geared towards iterator traversal (hence the category names), while
requirements that address value access sneak in at various places. The
following table gives a summary of the current value access
requirements in the iterator categories.</p>
<table border class="table">
<colgroup>
<col width="31%" />
<col width="69%" />
</colgroup>
<tbody valign="top">
<tr><td>Output Iterator</td>
<td><tt class="literal"><span class="pre">*i</span> <span class="pre">=</span> <span class="pre">a</span></tt></td>
</tr>
<tr><td>Input Iterator</td>
<td><tt class="literal"><span class="pre">*i</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt></td>
</tr>
<tr><td>Forward Iterator</td>
<td><tt class="literal"><span class="pre">*i</span></tt> is <tt class="literal"><span class="pre">T&amp;</span></tt> (or <tt class="literal"><span class="pre">const</span> <span class="pre">T&amp;</span></tt> once <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
is resolved)</td>
</tr>
<tr><td>Random Access Iterator</td>
<td><tt class="literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt> (also <tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
is required for mutable iterators once <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
is resolved)</td>
</tr>
</tbody>
</table>
<p>Because iterator traversal and value access are mixed together in a
single hierarchy, many useful iterators can not be appropriately
categorized. For example, <tt class="literal"><span class="pre">vector&lt;bool&gt;::iterator</span></tt> is almost a
random access iterator, but the return type is not <tt class="literal"><span class="pre">bool&amp;</span></tt> (see
<a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
N1185). Therefore, the iterators of <tt class="literal"><span class="pre">vector&lt;bool&gt;</span></tt> only meet the
requirements of input iterator and output iterator. This is so
nonintuitive that at least one implementation erroneously assigns
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt> as its <tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
<p>Another difficult-to-categorize iterator is the transform iterator, an
adaptor which applies a unary function object to the dereferenced
value of the some underlying iterator (see <a class="reference" href="http://www.boost.org/libs/utility/transform_iterator.htm">transform_iterator</a>).
For unary functions such as <tt class="literal"><span class="pre">times</span></tt>, the return type of
<tt class="literal"><span class="pre">operator*</span></tt> clearly needs to be the <tt class="literal"><span class="pre">result_type</span></tt> of the function
object, which is typically not a reference. Because random access
iterators are required to return lvalues from <tt class="literal"><span class="pre">operator*</span></tt>, if you
wrap <tt class="literal"><span class="pre">int*</span></tt> with a transform iterator, you do not get a random
access iterator as might be expected, but an input iterator.</p>
<p>A third example is found in the vertex and edge iterators of the
<a class="reference" href="http://www.boost.org/libs/graph/doc/table_of_contents.html">Boost Graph Library</a>. These iterators return vertex and edge
descriptors, which are lightweight handles created on-the-fly. They
must be returned by-value. As a result, their current standard
iterator category is <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, which means that,
strictly speaking, you could not use these iterators with algorithms
like <tt class="literal"><span class="pre">min_element()</span></tt>. As a temporary solution, the concept
<a class="reference" href="http://www.boost.org/libs/utility/MultiPassInputIterator.html">Multi-Pass Input Iterator</a> was introduced to describe the vertex and
edge descriptors, but as the design notes for the concept suggest, a
better solution is needed.</p>
<p>In short, there are many useful iterators that do not fit into the
current standard iterator categories. As a result, the following bad
things happen:</p>
<ul class="simple">
<li>Iterators are often mis-categorized.</li>
<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>
</ul>
</div>
<div class="section" id="impact-on-the-standard">
<h1><a class="toc-backref" href="#id2" name="impact-on-the-standard">Impact on the Standard</a></h1>
<p>The new iterator concepts are backward-compatible with the old
iterator requirements, and old iterators are forward-compatible with
the new iterator concepts. That is to say, iterators that satisfy the
old requirements also satisfy appropriate concepts in the new system,
and iterators modeling the new concepts will automatically satisfy the
appropriate old requirements.</p>
<!-- I think we need to say something about the resolution to allow
convertibility to any of the old-style tags as a TR issue (hope it
made it). -DWA -->
<!-- Hmm, not sure I understand. Are you talking about whether a
standards conforming input iterator is allowed to have
a tag that is not input_iterator_tag but that
is convertible to input_iterator_tag? -JGS -->
<p>The algorithms in the standard library benefit from the new iterator
concepts because the new concepts provide a more accurate way to
express their type requirements. The result is algorithms that are
usable in more situations and have fewer type requirements. The
following lists the proposed changes to the type requirements of
algorithms.</p>
<p>Forward Iterator -&gt; Forward Traversal Iterator and Readable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">find_end,</span> <span class="pre">adjacent_find,</span> <span class="pre">search,</span> <span class="pre">search_n,</span> <span class="pre">rotate_copy,</span> <span class="pre">lower_bound,</span> <span class="pre">upper_bound,</span> <span class="pre">equal_range,</span> <span class="pre">binary_search,</span> <span class="pre">min_element,</span> <span class="pre">max_element</span></tt></blockquote>
<p>Forward Iterator (1) -&gt; Single Pass Iterator and Readable Iterator
Forward Iterator (2) -&gt; Forward Traversal Iterator and Readable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">find_first_of</span></tt></blockquote>
<p>Forward Iterator -&gt; Readable Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">iter_swap</span></tt></blockquote>
<p>Forward Iterator -&gt; Single Pass Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">fill,</span> <span class="pre">generate</span></tt></blockquote>
<p>Forward Iterator -&gt; Forward Traversal Iterator and Swappable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">rotate</span></tt></blockquote>
<p>Forward Iterator (1) -&gt; Swappable Iterator and Single Pass Iterator
Forward Iterator (2) -&gt; Swappable Iterator and Incrementable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">swap_ranges</span></tt></blockquote>
<dl>
<dt>Forward Iterator -&gt; Forward Traversal Iterator and Readable Iterator and Writable Iterator</dt>
<dd><tt class="literal"><span class="pre">remove,</span> <span class="pre">remove_if,</span> <span class="pre">unique</span></tt></dd>
</dl>
<p>Forward Iterator -&gt; Single Pass Iterator and Readable Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">replace,</span> <span class="pre">replace_if</span></tt></blockquote>
<dl>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">reverse</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">partition</span></tt></dd>
</dl>
<p>Bidirectional Iterator (1) -&gt; Bidirectional Traversal Iterator and Readable Iterator,
Bidirectional Iterator (2) -&gt; Bidirectional Traversal Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">copy_backwards</span></tt></blockquote>
<dl>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Swappable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">next_permutation,</span> <span class="pre">prev_permutation</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable Iterator and Writable Iterator</dt>
<dd><tt class="literal"><span class="pre">stable_partition,</span> <span class="pre">inplace_merge</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">reverse_copy</span></tt></dd>
<dt>Random Access Iterator -&gt; Random Access Traversal Iterator and Readable and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">random_shuffle,</span> <span class="pre">sort,</span> <span class="pre">stable_sort,</span> <span class="pre">partial_sort,</span> <span class="pre">nth_element,</span> <span class="pre">push_heap,</span> <span class="pre">pop_heap</span>
<span class="pre">make_heap,</span> <span class="pre">sort_heap</span></tt></dd>
<dt>Input Iterator (2) -&gt; Incrementable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">equal</span></tt></dd>
<dt>Input Iterator (2) -&gt; Incrementable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">transform</span></tt></dd>
</dl>
</div>
<div class="section" id="design">
<h1><a class="toc-backref" href="#id3" name="design">Design</a></h1>
<p>The iterator requirements are be separated into two hierarchies. One
set of concepts handles the syntax and semantics of value access:</p>
<ul class="simple">
<li>Readable Iterator</li>
<li>Writable Iterator</li>
<li>Swappable Iterator</li>
<li>Readable Lvalue Iterator</li>
<li>Writable Lvalue Iterator</li>
</ul>
<p>The refinement relationships among these iterator concepts are given
in the following diagram.</p>
<p><img alt="access.png" src="access.png" /></p>
<p>The access concepts describe requirements related to <tt class="literal"><span class="pre">operator*</span></tt> and
<tt class="literal"><span class="pre">operator-&gt;</span></tt>, including the <tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, and
<tt class="literal"><span class="pre">pointer</span></tt> associated types.</p>
<p>The other set of concepts handles traversal:</p>
<ul class="simple">
<li>Incrementable Iterator</li>
<li>Single Pass Iterator</li>
<li>Forward Traversal Iterator</li>
<li>Bidirectional Traversal Iterator</li>
<li>Random Access Traversal Iterator</li>
</ul>
<p>The refinement relationships for the traversal concepts are in the
following diagram.</p>
<p><img alt="traversal.png" src="traversal.png" /></p>
<p>In addition to the iterator movement operators, such as
<tt class="literal"><span class="pre">operator++</span></tt>, the traversal concepts also include requirements on
position comparison such as <tt class="literal"><span class="pre">operator==</span></tt> and <tt class="literal"><span class="pre">operator&lt;</span></tt>. The
reason for the fine grain slicing of the concepts into the
Incrementable and Single Pass is to provide concepts that are exact
matches with the original input and output iterator requirements.</p>
<p>The relationship between the new iterator concepts and the old are
given in the following diagram.</p>
<p><img alt="oldeqnew.png" src="oldeqnew.png" /></p>
<p>Like the old iterator requirements, we provide tags for purposes of
dispatching. There are two hierarchies of tags, one for the access
concepts and one for the traversal concepts. We provide an access
mechanism for mapping iterator types to these new tags. Our design
reuses <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> as the access
mechanism. To enable this, a pair of access and traversal tags are
combined into a single type using the following <cite>iterator_tag</cite> class.</p>
<pre class="literal-block">
template &lt;class AccessTag, class TraversalTag&gt;
struct iterator_tag : /* appropriate old category or categories */
{
typedef AccessTag access;
typedef TraversalTag traversal;
};
</pre>
<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
tags passed as template parameters. The algorithm for determining the
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
concepts (that is, the closest fit), if any such category exists. For
example, a 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
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>
<p>We also provide two helper classes that make it convenient to obtain
the access and traversal tags of an iterator. These 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
categories.</p>
<pre class="literal-block">
template &lt;class Iterator&gt; struct access_category { typedef ... type; };
template &lt;class Iterator&gt; struct traversal_category { typedef ... type; };
</pre>
<p>The most difficult design decision concerned the <tt class="literal"><span class="pre">operator[]</span></tt>. The
direct approach for specifying <tt class="literal"><span class="pre">operator[]</span></tt> would have a return type
of <tt class="literal"><span class="pre">reference</span></tt>; the same as <tt class="literal"><span class="pre">operator*</span></tt>. However, going in this
direction would mean that an iterator satisfying the old Random Access
Iterator requirements would not necessarily be a model of Readable or
Writable Lvalue Iterator. Instead we have chosen a design that
matches the preferred resolution of <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="literal"><span class="pre">operator[]</span></tt> is
only required to return something convertible to the <tt class="literal"><span class="pre">value_type</span></tt>
(for a Readable Iterator), and is required to support assignment
<tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
</div>
<div class="section" id="proposed-text">
<h1><a class="toc-backref" href="#id4" name="proposed-text">Proposed Text</a></h1>
<div class="section" id="addition-to-lib-iterator-requirements">
<h2><a class="toc-backref" href="#id5" name="addition-to-lib-iterator-requirements">Addition to [lib.iterator.requirements]</a></h2>
<div class="section" id="iterator-value-access-concepts-lib-iterator-value-access">
<h3><a class="toc-backref" href="#id6" name="iterator-value-access-concepts-lib-iterator-value-access">Iterator Value Access Concepts [lib.iterator.value.access]</a></h3>
<p>In the tables below, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> is a constant
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is
<tt class="literal"><span class="pre">std::iterator_traits&lt;X&gt;::value_type</span></tt>, and <tt class="literal"><span class="pre">v</span></tt> is a constant
object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<a class="target" id="readable-iterator" name="readable-iterator"></a><div class="section" id="readable-iterators-lib-readable-iterators">
<h4><a class="toc-backref" href="#id7" name="readable-iterators-lib-readable-iterators">Readable Iterators [lib.readable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Readable Iterator</em> concept
for the value type <tt class="literal"><span class="pre">T</span></tt> if the following expressions are valid and
respect the stated semantics. <tt class="literal"><span class="pre">U</span></tt> is the type of any specified
member of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="34%" />
<col width="30%" />
<col width="36%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Readable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Note/Precondition/Postcondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt></td>
<td><tt class="literal"><span class="pre">T</span></tt></td>
<td>Any non-reference, non-cv-qualified type</td>
</tr>
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">readable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
<td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">a</span></tt> is dereferenceable. If <tt class="literal"><span class="pre">a</span> <span class="pre">==</span>
<span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt> is equivalent to <tt class="literal"><span class="pre">*b</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a-&gt;m</span></tt></td>
<td><tt class="literal"><span class="pre">U&amp;</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">(*a).m</span></tt> is well-defined.
Equivalent to <tt class="literal"><span class="pre">(*a).m</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
<a class="target" id="writable-iterator" name="writable-iterator"></a></div>
<div class="section" id="writable-iterators-lib-writable-iterators">
<h4><a class="toc-backref" href="#id8" name="writable-iterators-lib-writable-iterators">Writable Iterators [lib.writable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Writable Iterator</em> concept
if the following expressions are valid and respect the stated
semantics. In addition, a model of <em>Writable Iterator</em> must include
in its documentation the <em>set of value types</em> that it allows for
output.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="42%" />
<col width="27%" />
<col width="31%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Writable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Precondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">*a</span> <span class="pre">=</span> <span class="pre">o</span></tt></td>
<td>&nbsp;</td>
<td>pre: The type of <tt class="literal"><span class="pre">o</span></tt>
is in the set of
value types of <tt class="literal"><span class="pre">X</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="swappable-iterators-lib-swappable-iterators">
<h4><a class="toc-backref" href="#id9" name="swappable-iterators-lib-swappable-iterators">Swappable Iterators [lib.swappable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Swappable Iterator</em> concept
if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="38%" />
<col width="14%" />
<col width="48%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Swappable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Postcondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iter_swap(a,</span> <span class="pre">b)</span></tt></td>
<td><tt class="literal"><span class="pre">void</span></tt></td>
<td>post: the pointed to values are exchanged</td>
</tr>
</tbody>
</table>
</blockquote>
<dl>
<dt>[<em>Note:</em> An iterator that is a model of the <em>Readable</em> and <em>Writable Iterator</em> concepts</dt>
<dd>is also a model of <em>Swappable Iterator</em>. <em>--end note</em>]</dd>
</dl>
</div>
<div class="section" id="readable-lvalue-iterators-lib-readable-lvalue-iterators">
<h4><a class="toc-backref" href="#id10" name="readable-lvalue-iterators-lib-readable-lvalue-iterators">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></h4>
<p>The <em>Readable Lvalue Iterator</em> concept adds the requirement that the
<tt class="literal"><span class="pre">reference</span></tt> type be a reference to the value type of the iterator.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="35%" />
<col width="32%" />
<col width="34%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Readable Lvalue Iterator Requirements (in addition to Readable Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td><tt class="literal"><span class="pre">T&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">T</span></tt> is <em>cv</em>
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt>
where <em>cv</em> is an optional
cv-qualification</td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">readable_lvalue_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="writable-lvalue-iterators-lib-writable-lvalue-iterators">
<h4><a class="toc-backref" href="#id11" name="writable-lvalue-iterators-lib-writable-lvalue-iterators">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></h4>
<p>The <em>Writable Lvalue Iterator</em> concept adds the requirement that the
<tt class="literal"><span class="pre">reference</span></tt> type be a non-const reference to the value type of the
iterator.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="45%" />
<col width="55%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="2">Writable Lvalue Iterator Requirements (in addition to Readable Lvalue Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type&amp;</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">writable_lvalue_iterator_tag</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div>
<div class="section" id="iterator-traversal-concepts-lib-iterator-traversal">
<h3><a class="toc-backref" href="#id12" name="iterator-traversal-concepts-lib-iterator-traversal">Iterator Traversal Concepts [lib.iterator.traversal]</a></h3>
<p>In the tables below, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> and <tt class="literal"><span class="pre">b</span></tt> are
constant objects of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">r</span></tt> and <tt class="literal"><span class="pre">s</span></tt> are mutable objects of
type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is <tt class="literal"><span class="pre">std::iterator_traits&lt;X&gt;::value_type</span></tt>, and
<tt class="literal"><span class="pre">v</span></tt> is a constant object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<div class="section" id="incrementable-iterators-lib-incrementable-iterators">
<h4><a class="toc-backref" href="#id13" name="incrementable-iterators-lib-incrementable-iterators">Incrementable Iterators [lib.incrementable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Incrementable Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="27%" />
<col width="38%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">&amp;r</span> <span class="pre">==</span> <span class="pre">&amp;++r</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">r++</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">++r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="single-pass-iterators-lib-single-pass-iterators">
<h4><a class="toc-backref" href="#id14" name="single-pass-iterators-lib-single-pass-iterators">Single Pass Iterators [lib.single.pass.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Single Pass Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="33%" />
<col width="27%" />
<col width="39%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics/Pre-/Post-condition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">r</span></tt> is dereferenceable; post:
<tt class="literal"><span class="pre">r</span></tt> is dereferenceable or <tt class="literal"><span class="pre">r</span></tt> is
past-the-end</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">==</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">==</span></tt> is an equivalence relation over
its domain</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">!=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">==</span> <span class="pre">b)</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">single_pass_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="forward-traversal-iterators-lib-forward-traversal-iterators">
<h4><a class="toc-backref" href="#id15" name="forward-traversal-iterators-lib-forward-traversal-iterators">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Forward Traversal Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="39%" />
<col width="37%" />
<col width="24%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Forward Traversal Iterator Requirements (in addition to Single Pass Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Note</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">X</span> <span class="pre">u;</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">note:</span> <span class="pre">u</span> <span class="pre">may</span> <span class="pre">have</span> <span class="pre">a</span>
<span class="pre">singular</span> <span class="pre">value.</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt> and <tt class="literal"><span class="pre">r</span></tt> is
dereferenceable implies
<tt class="literal"><span class="pre">++r</span> <span class="pre">==</span> <span class="pre">++s.</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt></td>
<td>A signed integral type representing
the distance between iterators</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">forward_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">
<h4><a class="toc-backref" href="#id16" name="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Bidirectional Traversal
Iterator</em> concept if the following expressions are valid and respect
the stated semantics.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="28%" />
<col width="36%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics/Pre-/Post-condition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">--r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td>pre: there exists <tt class="literal"><span class="pre">s</span></tt> such that <tt class="literal"><span class="pre">r</span>
<span class="pre">==</span> <span class="pre">++s</span></tt>. post: <tt class="literal"><span class="pre">s</span></tt> is
dereferenceable. <tt class="literal"><span class="pre">--(++r)</span> <span class="pre">==</span> <span class="pre">r</span></tt>.
<tt class="literal"><span class="pre">--r</span> <span class="pre">==</span> <span class="pre">--s</span></tt> implies <tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt>. <tt class="literal"><span class="pre">&amp;r</span>
<span class="pre">==</span> <span class="pre">&amp;--r</span></tt>.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">r--</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">const</span> <span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">--r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">bidirectional_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="random-access-traversal-iterators-lib-random-access-traversal-iterators">
<h4><a class="toc-backref" href="#id17" name="random-access-traversal-iterators-lib-random-access-traversal-iterators">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Random Access Traversal
Iterator</em> concept if the following expressions are valid and respect
the stated semantics. In the table below, <tt class="literal"><span class="pre">Distance</span></tt> is
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt> and <tt class="literal"><span class="pre">n</span></tt> represents a
constant object of type <tt class="literal"><span class="pre">Distance</span></tt>.</p>
<blockquote>
<table border class="table">
<colgroup>
<col width="26%" />
<col width="33%" />
<col width="18%" />
<col width="24%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="4">Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Operational Semantics</th>
<th>Assertion/Precondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">+=</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><pre class="first last literal-block">
{
Distance m = n;
if (m &gt;= 0)
while (m--)
++r;
else
while (m++)
--r;
return r;
}
</pre>
</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span></tt>, <tt class="literal"><span class="pre">n</span> <span class="pre">+</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
<span class="pre">tmp</span> <span class="pre">+=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">-=</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">return</span> <span class="pre">r</span> <span class="pre">+=</span> <span class="pre">-n</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">-</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
<span class="pre">tmp</span> <span class="pre">-=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
<td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span> <span class="pre">?</span>
<span class="pre">distance(a,b)</span> <span class="pre">:</span>
<span class="pre">-distance(b,a)</span></tt></td>
<td>pre: there exists a value
<tt class="literal"><span class="pre">n</span></tt> of <tt class="literal"><span class="pre">Distance</span></tt> such
that <tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">b</span></tt>. <tt class="literal"><span class="pre">b</span> <span class="pre">==</span>
<span class="pre">a</span> <span class="pre">+</span> <span class="pre">(b</span> <span class="pre">-</span> <span class="pre">a)</span></tt>.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a[n]</span></tt></td>
<td>convertible to T</td>
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span></tt></td>
<td>pre: a is a <a class="reference" href="#readable-iterator">readable
iterator</a></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a[n]</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
<td>convertible to T</td>
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
<td>pre: a is a <a class="reference" href="#writable-iterator">writable
iterator</a></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">0</span></tt></td>
<td><tt class="literal"><span class="pre">&lt;</span></tt> is a total ordering
relation</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">b</span> <span class="pre">&lt;</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">&gt;</span></tt> is a total ordering
relation</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&gt;=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">&lt;</span> <span class="pre">b)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">&gt;</span> <span class="pre">b)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">random_access_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div>
</div>
<div class="section" id="addition-to-lib-iterator-synopsis">
<h2><a class="toc-backref" href="#id18" name="addition-to-lib-iterator-synopsis">Addition to [lib.iterator.synopsis]</a></h2>
<pre class="literal-block">
// lib.iterator.traits, traits and tags
template &lt;class Iterator&gt; struct access_category;
template &lt;class Iterator&gt; struct traversal_category;
template &lt;class AccessTag, class TraversalTag&gt;
struct iterator_tag : /* appropriate old category or categories */ {
typedef AccessTag access;
typedef TraversalTag traversal;
};
struct readable_iterator_tag { };
struct writable_iterator_tag { };
struct swappable_iterator_tag { };
struct readable_writable_iterator_tag
: virtual readable_iterator_tag
, virtual writable_iterator_tag
, virtual swappable_iterator_tag { };
struct readable_lvalue_iterator_tag { };
struct writable_lvalue_iterator_tag
: virtual public readable_writable_iterator_tag
, virtual public readable_lvalue_iterator_tag { };
struct incrementable_iterator_tag { };
struct single_pass_iterator_tag : incrementable_iterator_tag { };
struct forward_traversal_tag : single_pass_iterator_tag { };
struct bidirectional_traversal_tag : forward_traversal_tag { };
struct random_access_traversal_tag : bidirectional_traversal_tag { };
struct null_category_tag { };
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
</pre>
</div>
<div class="section" id="addition-to-lib-iterator-traits">
<h2><a class="toc-backref" href="#id19" name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is an iterator category tag that
encodes the access and traversal tags in addition to being compatible
with the original iterator tags. The <tt class="literal"><span class="pre">iterator_tag</span></tt> class inherits
from one of the original iterator tags according to the following
pseudo-code.</p>
<pre class="literal-block">
inherit-category(access-tag, traversal-tag) =
if (access-tag is convertible to readable_lvalue_iterator_tag) {
if (traversal-tag is convertible to random_access_traversal_tag)
return random_access_iterator_tag;
else if (traversal-tag is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag;
else if (traversal-tag is convertible to forward_traversal_tag)
return forward_iterator_tag;
else if (traversal-tag is convertible to single_pass_traversal_tag)
if (access-tag is convertible to writable_iterator_tag)
return input_output_iterator_tag;
else
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
} else if (access-tag is convertible to readable_writable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_output_iterator_tag;
else if (access-tag is convertible to readable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag
and traversal-tag is convertible to incrementable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
</pre>
<p>The <tt class="literal"><span class="pre">access_category</span></tt> and <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 <tt class="literal"><span class="pre">iterator_tag</span></tt>,
the <tt class="literal"><span class="pre">access_category</span></tt> and <tt class="literal"><span class="pre">traversal_category</span></tt> traits access the
<tt class="literal"><span class="pre">access</span></tt> and <tt class="literal"><span class="pre">traversal</span></tt> member types within <tt class="literal"><span class="pre">iterator_tag</span></tt>.
For iterators whose <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> type
is not <tt class="literal"><span class="pre">iterator_tag</span></tt> and instead is a tag convertible to one of the
original tags, the appropriate traversal and access tags is deduced.
The following pseudo-code describes the algorithm.</p>
<pre class="literal-block">
access-category(Iterator) =
cat = iterator_traits&lt;Iterator&gt;::iterator_category;
if (cat == iterator_tag&lt;Access,Traversal&gt;)
return Access;
else if (cat is convertible to forward_iterator_tag) {
if (iterator_traits&lt;Iterator&gt;::reference is a const reference)
return readable_lvalue_iterator_tag;
else
return writable_lvalue_iterator_tag;
} else if (cat is convertible to input_iterator_tag)
return readable_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return writable_iterator_tag;
else
return null_category_tag;
traversal-category(Iterator) =
cat = iterator_traits&lt;Iterator&gt;::iterator_category;
if (cat == iterator_tag&lt;Access,Traversal&gt;)
return Traversal;
else if (cat is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
else if (cat is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
else if (cat is convertible to forward_iterator_tag)
return forward_traversal_tag;
else if (cat is convertible to input_iterator_tag)
return single_pass_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return incrementable_iterator_tag;
else
return null_category_tag;
</pre>
<p>The following specializations provide the access and traversal
category tags for pointer types.</p>
<pre class="literal-block">
template &lt;typename T&gt;
struct access_category&lt;const T*&gt;
{
typedef readable_lvalue_iterator_tag type;
};
template &lt;typename T&gt;
struct access_category&lt;T*&gt;
{
typedef writable_lvalue_iterator_tag type;
};
template &lt;typename T&gt;
struct traversal_category&lt;T*&gt;
{
typedef random_access_traversal_tag type;
};
</pre>
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
</div>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="new-iter-concepts.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,760 +0,0 @@
++++++++++++++++++++++
New Iterator Concepts
++++++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems Lab`_, University of Hanover `Institute for Transport Railway Operation and Construction`_
:date: $Date$
:Number: **This document is a revised version of the official** N1477=03-0060
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:Abstract: We propose a new system of iterator concepts that treat
access and positioning independently. This allows the
concepts to more closely match the requirements
of algorithms and provides better categorizations
of iterators that are used in practice. This proposal
is a revision of paper n1297_.
.. contents:: Table of Contents
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
============
Motivation
============
The standard iterator categories and requirements are flawed because
they use a single hierarchy of concepts to address two orthogonal
issues: *iterator traversal* and *value access*. As a result, many
algorithms with requirements expressed in terms of the iterator
categories are too strict. Also, many real-world iterators can not be
accurately categorized. A proxy-based iterator with random-access
traversal, for example, may only legally have a category of "input
iterator", so generic algorithms are unable to take advantage of its
random-access capabilities. The current iterator concept hierarchy is
geared towards iterator traversal (hence the category names), while
requirements that address value access sneak in at various places. The
following table gives a summary of the current value access
requirements in the iterator categories.
+------------------------+-----------------------------------------------------+
|Output Iterator |``*i = a`` |
+------------------------+-----------------------------------------------------+
|Input Iterator |``*i`` is convertible to ``T`` |
+------------------------+-----------------------------------------------------+
|Forward Iterator |``*i`` is ``T&`` (or ``const T&`` once `issue 200`_ |
| |is resolved) |
+------------------------+-----------------------------------------------------+
|Random Access Iterator |``i[n]`` is convertible to ``T`` (also ``i[n] = t`` |
| |is required for mutable iterators once `issue 299`_ |
| |is resolved) |
+------------------------+-----------------------------------------------------+
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
.. _issue 299: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299
Because iterator traversal and value access are mixed together in a
single hierarchy, many useful iterators can not be appropriately
categorized. For example, ``vector<bool>::iterator`` is almost a
random access iterator, but the return type is not ``bool&`` (see
`issue 96`_ and Herb Sutter's paper J16/99-0008 = WG21
N1185). Therefore, the iterators of ``vector<bool>`` only meet the
requirements of input iterator and output iterator. This is so
nonintuitive that at least one implementation erroneously assigns
``random_access_iterator_tag`` as its ``iterator_category``.
.. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96
Another difficult-to-categorize iterator is the transform iterator, an
adaptor which applies a unary function object to the dereferenced
value of the some underlying iterator (see `transform_iterator`_).
For unary functions such as ``times``, the return type of
``operator*`` clearly needs to be the ``result_type`` of the function
object, which is typically not a reference. Because random access
iterators are required to return lvalues from ``operator*``, if you
wrap ``int*`` with a transform iterator, you do not get a random
access iterator as might be expected, but an input iterator.
.. _`transform_iterator`: http://www.boost.org/libs/utility/transform_iterator.htm
A third example is found in the vertex and edge iterators of the
`Boost Graph Library`_. These iterators return vertex and edge
descriptors, which are lightweight handles created on-the-fly. They
must be returned by-value. As a result, their current standard
iterator category is ``input_iterator_tag``, which means that,
strictly speaking, you could not use these iterators with algorithms
like ``min_element()``. As a temporary solution, the concept
`Multi-Pass Input Iterator`_ was introduced to describe the vertex and
edge descriptors, but as the design notes for the concept suggest, a
better solution is needed.
.. _Boost Graph Library: http://www.boost.org/libs/graph/doc/table_of_contents.html
.. _Multi-Pass Input Iterator: http://www.boost.org/libs/utility/MultiPassInputIterator.html
In short, there are many useful iterators that do not fit into the
current standard iterator categories. As a result, the following bad
things happen:
- Iterators are often mis-categorized.
- 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.
========================
Impact on the Standard
========================
The new iterator concepts are backward-compatible with the old
iterator requirements, and old iterators are forward-compatible with
the new iterator concepts. That is to say, iterators that satisfy the
old requirements also satisfy appropriate concepts in the new system,
and iterators modeling the new concepts will automatically satisfy the
appropriate old requirements.
.. I think we need to say something about the resolution to allow
convertibility to any of the old-style tags as a TR issue (hope it
made it). -DWA
.. Hmm, not sure I understand. Are you talking about whether a
standards conforming input iterator is allowed to have
a tag that is not input_iterator_tag but that
is convertible to input_iterator_tag? -JGS
The algorithms in the standard library benefit from the new iterator
concepts because the new concepts provide a more accurate way to
express their type requirements. The result is algorithms that are
usable in more situations and have fewer type requirements. The
following lists the proposed changes to the type requirements of
algorithms.
Forward Iterator -> Forward Traversal Iterator and Readable Iterator
``find_end, adjacent_find, search, search_n, rotate_copy, lower_bound, upper_bound, equal_range, binary_search, min_element, max_element``
Forward Iterator (1) -> Single Pass Iterator and Readable Iterator
Forward Iterator (2) -> Forward Traversal Iterator and Readable Iterator
``find_first_of``
Forward Iterator -> Readable Iterator and Writable Iterator
``iter_swap``
Forward Iterator -> Single Pass Iterator and Writable Iterator
``fill, generate``
Forward Iterator -> Forward Traversal Iterator and Swappable Iterator
``rotate``
Forward Iterator (1) -> Swappable Iterator and Single Pass Iterator
Forward Iterator (2) -> Swappable Iterator and Incrementable Iterator
``swap_ranges``
Forward Iterator -> Forward Traversal Iterator and Readable Iterator and Writable Iterator
``remove, remove_if, unique``
Forward Iterator -> Single Pass Iterator and Readable Iterator and Writable Iterator
``replace, replace_if``
Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator
``reverse``
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable and Swappable Iterator
``partition``
Bidirectional Iterator (1) -> Bidirectional Traversal Iterator and Readable Iterator,
Bidirectional Iterator (2) -> Bidirectional Traversal Iterator and Writable Iterator
``copy_backwards``
Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator and Readable Iterator
``next_permutation, prev_permutation``
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator and Writable Iterator
``stable_partition, inplace_merge``
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator
``reverse_copy``
Random Access Iterator -> Random Access Traversal Iterator and Readable and Swappable Iterator
``random_shuffle, sort, stable_sort, partial_sort, nth_element, push_heap, pop_heap
make_heap, sort_heap``
Input Iterator (2) -> Incrementable Iterator and Readable Iterator
``equal``
Input Iterator (2) -> Incrementable Iterator and Readable Iterator
``transform``
========
Design
========
The iterator requirements are be separated into two hierarchies. One
set of concepts handles the syntax and semantics of value access:
- Readable Iterator
- Writable Iterator
- Swappable Iterator
- Readable Lvalue Iterator
- Writable Lvalue Iterator
The refinement relationships among these iterator concepts are given
in the following diagram.
.. image:: access.png
The access concepts describe requirements related to ``operator*`` and
``operator->``, including the ``value_type``, ``reference``, and
``pointer`` associated types.
The other set of concepts handles traversal:
- Incrementable Iterator
- Single Pass Iterator
- Forward Traversal Iterator
- Bidirectional Traversal Iterator
- Random Access Traversal Iterator
The refinement relationships for the traversal concepts are in the
following diagram.
.. image:: traversal.png
In addition to the iterator movement operators, such as
``operator++``, the traversal concepts also include requirements on
position comparison such as ``operator==`` and ``operator<``. The
reason for the fine grain slicing of the concepts into the
Incrementable and Single Pass is to provide concepts that are exact
matches with the original input and output iterator requirements.
The relationship between the new iterator concepts and the old are
given in the following diagram.
.. image:: oldeqnew.png
Like the old iterator requirements, we provide tags for purposes of
dispatching. There are two hierarchies of tags, one for the access
concepts and one for the traversal concepts. We provide an access
mechanism for mapping iterator types to these new tags. Our design
reuses ``iterator_traits<Iter>::iterator_category`` as the access
mechanism. To enable this, a pair of access and traversal tags are
combined into a single type using the following `iterator_tag` class.
::
template <class AccessTag, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */
{
typedef AccessTag access;
typedef TraversalTag traversal;
};
The ``iterator_tag`` class template is derived from the appropriate
iterator tag or tags from the old requirements based on the new-style
tags passed as template parameters. The algorithm for determining the
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
concepts (that is, the closest fit), if any such category exists. For
example, a the category tag for a Readable Single Pass Iterator will
always be derived from ``input_iterator_tag``, while the category tag
for a Single Pass Iterator that is both Readable and Writable will be
derived from both ``input_iterator_tag`` and ``output_iterator_tag``.
We also provide two helper classes that make it convenient to obtain
the access and traversal tags of an iterator. These helper classes
work both for iterators whose ``iterator_category`` is
``iterator_tag`` and also for iterators using the original iterator
categories.
::
template <class Iterator> struct access_category { typedef ... type; };
template <class Iterator> struct traversal_category { typedef ... type; };
The most difficult design decision concerned the ``operator[]``. The
direct approach for specifying ``operator[]`` would have a return type
of ``reference``; the same as ``operator*``. However, going in this
direction would mean that an iterator satisfying the old Random Access
Iterator requirements would not necessarily be a model of Readable or
Writable Lvalue Iterator. Instead we have chosen a design that
matches the preferred resolution of `issue 299`_: ``operator[]`` is
only required to return something convertible to the ``value_type``
(for a Readable Iterator), and is required to support assignment
``i[n] = t`` (for a Writable Iterator).
===============
Proposed Text
===============
Addition to [lib.iterator.requirements]
=======================================
Iterator Value Access Concepts [lib.iterator.value.access]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
In the tables below, ``X`` is an iterator type, ``a`` is a constant
object of type ``X``, ``T`` is
``std::iterator_traits<X>::value_type``, and ``v`` is a constant
object of type ``T``.
.. _Readable Iterator:
Readable Iterators [lib.readable.iterators]
-------------------------------------------
A class or built-in type ``X`` models the *Readable Iterator* concept
for the value type ``T`` if the following expressions are valid and
respect the stated semantics. ``U`` is the type of any specified
member of type ``T``.
+-------------------------------------------------------------------------------------------------------------------+
|Readable Iterator Requirements (in addition to CopyConstructible) |
+--------------------------------------+----------------------------------+-----------------------------------------+
|Expression |Return Type |Assertion/Note/Precondition/Postcondition|
+======================================+==================================+=========================================+
|``iterator_traits<X>::value_type`` |``T`` |Any non-reference, non-cv-qualified type |
+--------------------------------------+----------------------------------+-----------------------------------------+
|``iterator_traits<X>::reference`` |Convertible to | |
| |``iterator_traits<X>::value_type``| |
+--------------------------------------+----------------------------------+-----------------------------------------+
|``access_category<X>::type`` |Convertible to | |
| |``readable_iterator_tag`` | |
+--------------------------------------+----------------------------------+-----------------------------------------+
|``*a`` |``iterator_traits<X>::reference`` |pre: ``a`` is dereferenceable. If ``a == |
| | |b`` then ``*a`` is equivalent to ``*b`` |
+--------------------------------------+----------------------------------+-----------------------------------------+
|``a->m`` |``U&`` |pre: ``(*a).m`` is well-defined. |
| | |Equivalent to ``(*a).m`` |
+--------------------------------------+----------------------------------+-----------------------------------------+
.. _Writable Iterator:
Writable Iterators [lib.writable.iterators]
-------------------------------------------
A class or built-in type ``X`` models the *Writable Iterator* concept
if the following expressions are valid and respect the stated
semantics. In addition, a model of *Writable Iterator* must include
in its documentation the *set of value types* that it allows for
output.
+---------------------------------------------------------------------------------------------+
|Writable Iterator Requirements (in addition to CopyConstructible) |
+--------------------------------------+-------------------------+----------------------------+
|Expression |Return Type |Precondition |
+======================================+=========================+============================+
|``access_category<X>::type`` |Convertible to | |
| |``writable_iterator_tag``| |
+--------------------------------------+-------------------------+----------------------------+
|``*a = o`` | | pre: The type of ``o`` |
| | | is in the set of |
| | | value types of ``X`` |
+--------------------------------------+-------------------------+----------------------------+
Swappable Iterators [lib.swappable.iterators]
---------------------------------------------
A class or built-in type ``X`` models the *Swappable Iterator* concept
if the following expressions are valid and respect the stated
semantics.
+------------------------------------------------------------------------------------------------+
|Swappable Iterator Requirements (in addition to CopyConstructible) |
+------------------------------------+-------------+---------------------------------------------+
|Expression |Return Type |Postcondition |
+====================================+=============+=============================================+
|``iter_swap(a, b)`` |``void`` |post: the pointed to values are exchanged |
+------------------------------------+-------------+---------------------------------------------+
[*Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
is also a model of *Swappable Iterator*. *--end note*]
Readable Lvalue Iterators [lib.readable.lvalue.iterators]
---------------------------------------------------------
The *Readable Lvalue Iterator* concept adds the requirement that the
``reference`` type be a reference to the value type of the iterator.
+----------------------------------------------------------------------------------------------------------+
|Readable Lvalue Iterator Requirements (in addition to Readable Iterator) |
+------------------------------------+---------------------------------+-----------------------------------+
|Expression |Return Type |Assertion |
+====================================+=================================+===================================+
|``iterator_traits<X>::reference`` |``T&`` |``T`` is *cv* |
| | |``iterator_traits<X>::value_type`` |
| | |where *cv* is an optional |
| | |cv-qualification |
+------------------------------------+---------------------------------+-----------------------------------+
|``access_category<X>::type`` |Convertible to | |
| |``readable_lvalue_iterator_tag`` | |
+------------------------------------+---------------------------------+-----------------------------------+
Writable Lvalue Iterators [lib.writable.lvalue.iterators]
---------------------------------------------------------
The *Writable Lvalue Iterator* concept adds the requirement that the
``reference`` type be a non-const reference to the value type of the
iterator.
+--------------------------------------------------------------------------------------+
| Writable Lvalue Iterator Requirements (in addition to Readable Lvalue Iterator) |
+--------------------------------------+-----------------------------------------------+
| Expression | Return Type |
+======================================+===============================================+
|``iterator_traits<X>::reference`` |``iterator_traits<X>::value_type&`` |
+--------------------------------------+-----------------------------------------------+
|``access_category<X>::type`` |Convertible to ``writable_lvalue_iterator_tag``|
| | |
+--------------------------------------+-----------------------------------------------+
Iterator Traversal Concepts [lib.iterator.traversal]
++++++++++++++++++++++++++++++++++++++++++++++++++++
In the tables below, ``X`` is an iterator type, ``a`` and ``b`` are
constant objects of type ``X``, ``r`` and ``s`` are mutable objects of
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``, and
``v`` is a constant object of type ``T``.
Incrementable Iterators [lib.incrementable.iterators]
-----------------------------------------------------
A class or built-in type ``X`` models the *Incrementable Iterator*
concept if the following expressions are valid and respect the stated
semantics.
+-------------------------------------------------------------------------------------------------------------------------+
|Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible) |
+--------------------------------+---------------------------------------------+------------------------------------------+
|Expression |Return Type |Assertion/Semantics |
+================================+=============================================+==========================================+
|``++r`` |``X&`` |``&r == &++r`` |
+--------------------------------+---------------------------------------------+------------------------------------------+
|``r++`` |``X`` |``{ X tmp = r; ++r; return tmp; }`` |
+--------------------------------+---------------------------------------------+------------------------------------------+
|``traversal_category<X>::type`` |Convertible to ``incrementable_iterator_tag``| |
+--------------------------------+---------------------------------------------+------------------------------------------+
Single Pass Iterators [lib.single.pass.iterators]
-------------------------------------------------
A class or built-in type ``X`` models the *Single Pass Iterator*
concept if the following expressions are valid and respect the stated
semantics.
+--------------------------------------------------------------------------------------------------------+
|Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable) |
+----------------------------------+----------------------------+----------------------------------------+
|Expression |Return Type |Assertion/Semantics/Pre-/Post-condition |
+==================================+============================+========================================+
|``++r`` |``X&`` |pre: ``r`` is dereferenceable; post: |
| | |``r`` is dereferenceable or ``r`` is |
| | |past-the-end |
+----------------------------------+----------------------------+----------------------------------------+
|``a == b`` |convertible to ``bool`` |``==`` is an equivalence relation over |
| | |its domain |
+----------------------------------+----------------------------+----------------------------------------+
|``a != b`` |convertible to ``bool`` |``!(a == b)`` |
+----------------------------------+----------------------------+----------------------------------------+
|``traversal_category<X>::type`` |Convertible to | |
| |``single_pass_iterator_tag``| |
+----------------------------------+----------------------------+----------------------------------------+
Forward Traversal Iterators [lib.forward.traversal.iterators]
-------------------------------------------------------------
A class or built-in type ``X`` models the *Forward Traversal Iterator*
concept if the following expressions are valid and respect the stated
semantics.
+------------------------------------------------------------------------------------------------------+
|Forward Traversal Iterator Requirements (in addition to Single Pass Iterator) |
+---------------------------------------+-------------------------------------+------------------------+
|Expression |Return Type |Assertion/Note |
+=======================================+=====================================+========================+
|``X u;`` |``X&`` |``note: u may have a |
| | |singular value.`` |
+---------------------------------------+-------------------------------------+------------------------+
|``++r`` |``X&`` |``r == s`` and ``r`` is |
| | |dereferenceable implies |
| | |``++r == ++s.`` |
+---------------------------------------+-------------------------------------+------------------------+
|``iterator_traits<X>::difference_type``|A signed integral type representing | |
| |the distance between iterators | |
+---------------------------------------+-------------------------------------+------------------------+
|``traversal_category<X>::type`` |Convertible to | |
| |``forward_traversal_iterator_tag`` | |
+---------------------------------------+-------------------------------------+------------------------+
Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]
-------------------------------------------------------------------------
A class or built-in type ``X`` models the *Bidirectional Traversal
Iterator* concept if the following expressions are valid and respect
the stated semantics.
+----------------------------------------------------------------------------------------------------------------+
|Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator) |
+-------------------------------+----------------------------------------+---------------------------------------+
|Expression |Return Type |Assertion/Semantics/Pre-/Post-condition|
+===============================+========================================+=======================================+
|``--r`` |``X&`` |pre: there exists ``s`` such that ``r |
| | |== ++s``. post: ``s`` is |
| | |dereferenceable. ``--(++r) == r``. |
| | |``--r == --s`` implies ``r == s``. ``&r|
| | |== &--r``. |
+-------------------------------+----------------------------------------+---------------------------------------+
|``r--`` |convertible to ``const X&`` |``{ X tmp = r; --r; return tmp; }`` |
| | | |
| | | |
+-------------------------------+----------------------------------------+---------------------------------------+
|``traversal_category<X>::type``|Convertible to | |
| |``bidirectional_traversal_iterator_tag``| |
| | | |
+-------------------------------+----------------------------------------+---------------------------------------+
Random Access Traversal Iterators [lib.random.access.traversal.iterators]
-------------------------------------------------------------------------
A class or built-in type ``X`` models the *Random Access Traversal
Iterator* concept if the following expressions are valid and respect
the stated semantics. In the table below, ``Distance`` is
``iterator_traits<X>::difference_type`` and ``n`` represents a
constant object of type ``Distance``.
+------------------------------------------------------------------------------------------------------------------------------+
|Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator) |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
| Expression |Return Type | Operational Semantics| Assertion/Precondition |
+================================+========================================+======================+=============================+
|``r += n`` |``X&`` |:: | |
| | | | |
| | | { | |
| | | Distance m = n; | |
| | | if (m >= 0) | |
| | | while (m--) | |
| | | ++r; | |
| | | else | |
| | | while (m++) | |
| | | --r; | |
| | | return r; | |
| | | } | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
| ``a + n``, ``n + a`` |``X`` |``{ X tmp = a; return | |
| | |tmp += n; }`` | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``r -= n`` |``X&`` |``return r += -n`` | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a - n`` |``X`` |``{ X tmp = a; return | |
| | |tmp -= n; }`` | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``b - a`` |``Distance`` |``a < b ? |pre: there exists a value |
| | |distance(a,b) : |``n`` of ``Distance`` such |
| | |-distance(b,a)`` |that ``a + n == b``. ``b == |
| | | |a + (b - a)``. |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a[n]`` |convertible to T |``*(a + n)`` |pre: a is a `readable |
| | | |iterator`_ |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a[n] = v`` |convertible to T |``*(a + n) = v`` |pre: a is a `writable |
| | | |iterator`_ |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a < b`` |convertible to ``bool`` |``b - a > 0`` |``<`` is a total ordering |
| | | |relation |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a > b`` |convertible to ``bool`` |``b < a`` |``>`` is a total ordering |
| | | |relation |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a >= b`` |convertible to ``bool`` |``!(a < b)`` | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``a <= b`` |convertible to ``bool`` |``!(a > b)`` | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|``traversal_category<X>::type`` |Convertible to | | |
| |``random_access_traversal_iterator_tag``| | |
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
Addition to [lib.iterator.synopsis]
===================================
::
// lib.iterator.traits, traits and tags
template <class Iterator> struct access_category;
template <class Iterator> struct traversal_category;
template <class AccessTag, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */ {
typedef AccessTag access;
typedef TraversalTag traversal;
};
struct readable_iterator_tag { };
struct writable_iterator_tag { };
struct swappable_iterator_tag { };
struct readable_writable_iterator_tag
: virtual readable_iterator_tag
, virtual writable_iterator_tag
, virtual swappable_iterator_tag { };
struct readable_lvalue_iterator_tag { };
struct writable_lvalue_iterator_tag
: virtual public readable_writable_iterator_tag
, virtual public readable_lvalue_iterator_tag { };
struct incrementable_iterator_tag { };
struct single_pass_iterator_tag : incrementable_iterator_tag { };
struct forward_traversal_tag : single_pass_iterator_tag { };
struct bidirectional_traversal_tag : forward_traversal_tag { };
struct random_access_traversal_tag : bidirectional_traversal_tag { };
struct null_category_tag { };
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
Addition to [lib.iterator.traits]
=================================
The ``iterator_tag`` class template is an iterator category tag that
encodes the access and traversal tags in addition to being compatible
with the original iterator tags. The ``iterator_tag`` class inherits
from one of the original iterator tags according to the following
pseudo-code.
::
inherit-category(access-tag, traversal-tag) =
if (access-tag is convertible to readable_lvalue_iterator_tag) {
if (traversal-tag is convertible to random_access_traversal_tag)
return random_access_iterator_tag;
else if (traversal-tag is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag;
else if (traversal-tag is convertible to forward_traversal_tag)
return forward_iterator_tag;
else if (traversal-tag is convertible to single_pass_traversal_tag)
if (access-tag is convertible to writable_iterator_tag)
return input_output_iterator_tag;
else
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
} else if (access-tag is convertible to readable_writable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_output_iterator_tag;
else if (access-tag is convertible to readable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag
and traversal-tag is convertible to incrementable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
The ``access_category`` and ``traversal_category`` class templates are
traits classes. For iterators whose
``iterator_traits<Iter>::iterator_category`` type is ``iterator_tag``,
the ``access_category`` and ``traversal_category`` traits access the
``access`` and ``traversal`` member types within ``iterator_tag``.
For iterators whose ``iterator_traits<Iter>::iterator_category`` type
is not ``iterator_tag`` and instead is a tag convertible to one of the
original tags, the appropriate traversal and access tags is deduced.
The following pseudo-code describes the algorithm.
::
access-category(Iterator) =
cat = iterator_traits<Iterator>::iterator_category;
if (cat == iterator_tag<Access,Traversal>)
return Access;
else if (cat is convertible to forward_iterator_tag) {
if (iterator_traits<Iterator>::reference is a const reference)
return readable_lvalue_iterator_tag;
else
return writable_lvalue_iterator_tag;
} else if (cat is convertible to input_iterator_tag)
return readable_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return writable_iterator_tag;
else
return null_category_tag;
traversal-category(Iterator) =
cat = iterator_traits<Iterator>::iterator_category;
if (cat == iterator_tag<Access,Traversal>)
return Traversal;
else if (cat is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
else if (cat is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
else if (cat is convertible to forward_iterator_tag)
return forward_traversal_tag;
else if (cat is convertible to input_iterator_tag)
return single_pass_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return incrementable_iterator_tag;
else
return null_category_tag;
The following specializations provide the access and traversal
category tags for pointer types.
::
template <typename T>
struct access_category<const T*>
{
typedef readable_lvalue_iterator_tag type;
};
template <typename T>
struct access_category<T*>
{
typedef writable_lvalue_iterator_tag type;
};
template <typename T>
struct traversal_category<T*>
{
typedef random_access_traversal_tag type;
};
..
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,128 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Permutation Iterator</title>
<meta name="author" content="Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek" />
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab" />
<meta name="date" content="2003-08-05" />
<meta name="copyright" content="Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="permutation-iterator">
<h1 class="title">Permutation Iterator</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>Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="last reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a></td></tr>
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="last reference" href="http://www.osl.iu.edu">Open Systems
Lab</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The permutation iterator adaptor provides a permuted view of a given
range. That is, the view includes every element of the given range but
in a potentially different order.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#introduction" id="id4" name="id4">Introduction</a></li>
<li><a class="reference" href="#reference" id="id5" name="id5">Reference</a><ul>
<li><a class="reference" href="#permutation-iterator-requirements" id="id6" name="id6"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#permutation-iterator-operations" id="id7" name="id7"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id4" name="introduction">Introduction</a></h1>
<p>The adaptor takes two arguments:</p>
<blockquote>
<ul class="simple">
<li>an iterator to the range V on which the permutation
will be applied</li>
<li>the reindexing scheme that defines how the
elements of V will be permuted.</li>
</ul>
</blockquote>
<p>Note that the permutation iterator is not limited to strict
permutations of the given range V. The distance between begin and end
of the reindexing iterators is allowed to be smaller compared to the
size of the range V, in which case the permutation iterator only
provides a permutation of a subrange of V. The indexes neither need
to be unique. In this same context, it must be noted that the past the
end permutation iterator is completely defined by means of the
past-the-end iterator to the indices.</p>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id5" name="reference">Reference</a></h1>
<pre class="literal-block">
template&lt; class ElementIterator
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default &gt;
class permutation_iterator
: public iterator_adaptor&lt;...&gt;
{
typedef iterator_adaptor&lt;...&gt;
friend class iterator_core_access;
public:
permutation_iterator();
explicit permutation_iterator(ElementIterator x, IndexIterator y);
template&lt; class OEIter, class OIIter, class V, class C, class R, class D &gt;
permutation_iterator(
permutation_iterator&lt;OEIter, OIIter, V, C, R, D&gt; const&amp; r
, typename enable_if_convertible&lt;OEIter, ElementIterator&gt;::type* = 0
, typename enable_if_convertible&lt;OIIter, IndexIterator&gt;::type* = 0
);
};
</pre>
<div class="section" id="permutation-iterator-requirements">
<h2><a class="toc-backref" href="#id6" name="permutation-iterator-requirements"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></h2>
<p><tt class="literal"><span class="pre">ElementIterator</span></tt> must be a model of <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>.
<tt class="literal"><span class="pre">IndexIterator</span></tt> must at least be a model <a class="reference" href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>. The
value type of the <tt class="literal"><span class="pre">IndexIterator</span></tt> must be convertible to the
difference type of <tt class="literal"><span class="pre">ElementIterator</span></tt>.</p>
</div>
<div class="section" id="permutation-iterator-operations">
<h2><a class="toc-backref" href="#id7" name="permutation-iterator-operations"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></h2>
<p>The permutation iterator implements the member functions and operators
required for the <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> concept. However, the
permutation iterator can only meet the complexity guarantees of the
same concept as the IndexIterator. Thus for instance, although the
permutation iterator provides <tt class="literal"><span class="pre">operator+=(distance)</span></tt>, this operation
will take linear time in case the IndexIterator is a model of
ForwardIterator instead of amortized constant time.</p>
</div>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="permutation_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,31 +0,0 @@
++++++++++++++++++++++
Permutation Iterator
++++++++++++++++++++++
:Author: Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_
:date: $Date$
:copyright: Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
:abstract:
.. include:: permutation_iterator_abstract.rst
.. contents:: Table of Contents
Introduction
============
.. include:: permutation_iterator_body.rst
Reference
=========
.. include:: permutation_iterator_ref.rst

View File

@ -1,4 +0,0 @@
The permutation iterator adaptor provides a permuted view of a given
range. That is, the view includes every element of the given range but
in a potentially different order.

View File

@ -1,15 +0,0 @@
The adaptor takes two arguments:
* an iterator to the range V on which the permutation
will be applied
* the reindexing scheme that defines how the
elements of V will be permuted.
Note that the permutation iterator is not limited to strict
permutations of the given range V. The distance between begin and end
of the reindexing iterators is allowed to be smaller compared to the
size of the range V, in which case the permutation iterator only
provides a permutation of a subrange of V. The indexes neither need
to be unique. In this same context, it must be noted that the past the
end permutation iterator is completely defined by means of the
past-the-end iterator to the indices.

View File

@ -1,54 +0,0 @@
.. parsed-literal::
template< class ElementIterator
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
class permutation_iterator
: public iterator_adaptor<...>
{
typedef iterator_adaptor<...>
friend class iterator_core_access;
public:
permutation_iterator();
explicit permutation_iterator(ElementIterator x, IndexIterator y);
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
};
``permutation_iterator`` requirements
-------------------------------------
``ElementIterator`` must be a model of RandomAccessIterator__.
``IndexIterator`` must at least be a model ForwardIterator__. The
value type of the ``IndexIterator`` must be convertible to the
difference type of ``ElementIterator``.
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html
__ http://www.sgi.com/tech/stl/ForwardIterator.html
``permutation_iterator`` operations
-----------------------------------
The permutation iterator implements the member functions and operators
required for the `Random Access Iterator`__ concept. However, the
permutation iterator can only meet the complexity guarantees of the
same concept as the IndexIterator. Thus for instance, although the
permutation iterator provides ``operator+=(distance)``, this operation
will take linear time in case the IndexIterator is a model of
ForwardIterator instead of amortized constant time.
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html

View File

@ -1,143 +0,0 @@
<?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.1: http://docutils.sourceforge.net/" />
<title>Reverse Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="reverse-iterator">
<h1 class="title">Reverse Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<!-- I think we'd better strike the old reverse_iterator text from the standard, eh? -->
<p>The reverse iterator adaptor flips the direction of a base iterator's
motion. Invoking <tt class="literal"><span class="pre">operator++()</span></tt> moves the base iterator backward and
invoking <tt class="literal"><span class="pre">operator--()</span></tt> moves the base iterator forward.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#reverse-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class Iterator&gt;
class reverse_iterator :
public iterator_adaptor&lt; reverse_iterator&lt;Iterator&gt;, Iterator &gt;
{
friend class iterator_core_access;
public:
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
template&lt;class OtherIterator&gt;
reverse_iterator(
reverse_iterator&lt;OtherIterator&gt; const&amp; r
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
private: // as-if specification
typename reverse_iterator::reference dereference() const { return *prior(this-&gt;base()); }
void increment() { --this-&gt;base_reference(); }
void decrement() { ++this-&gt;base_reference(); }
void advance(typename reverse_iterator::difference_type n)
{
this-&gt;base_reference() += -n;
}
template &lt;class OtherIterator&gt;
typename reverse_iterator::difference_type
distance_to(reverse_iterator&lt;OtherIterator&gt; const&amp; y) const
{
return this-&gt;base_reference() - y.base();
}
};
</pre>
<div class="section" id="reverse-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="reverse-iterator-requirements"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></h1>
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal
Iterator. The resulting <tt class="literal"><span class="pre">reverse_iterator</span></tt> will be a model of the
most refined standard traversal and access concepts that are modeled
by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<p><tt class="literal"><span class="pre">reverse_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
default constructed base object.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">reverse_iterator(Iterator</span> <span class="pre">x);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
base object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template&lt;class OtherIterator&gt;
reverse_iterator(
reverse_iterator&lt;OtherIterator&gt; const&amp; r
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
</pre>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">r</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="reverse_iterator.rst">View document source</a>.
Generated on: 2003-09-14 02:16 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>

View File

@ -1,23 +0,0 @@
++++++++++++++++++
Reverse Iterator
++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: reverse_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: reverse_iterator_ref.rst

View File

@ -1,6 +0,0 @@
.. I think we'd better strike the old reverse_iterator text from the standard, eh?
The reverse iterator adaptor flips the direction of a base iterator's
motion. Invoking ``operator++()`` moves the base iterator backward and
invoking ``operator--()`` moves the base iterator forward.

View File

@ -1,69 +0,0 @@
::
template <class Iterator>
class reverse_iterator :
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
{
friend class iterator_core_access;
public:
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
private: // as-if specification
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename reverse_iterator::difference_type n)
{
this->base_reference() += -n;
}
template <class OtherIterator>
typename reverse_iterator::difference_type
distance_to(reverse_iterator<OtherIterator> const& y) const
{
return this->base_reference() - y.base();
}
};
``reverse_iterator`` requirements
.................................
The base ``Iterator`` must be a model of Bidirectional Traversal
Iterator. The resulting ``reverse_iterator`` will be a model of the
most refined standard traversal and access concepts that are modeled
by ``Iterator``.
``reverse_iterator();``
:Requires: ``Iterator`` must be Default Constructible.
:Returns: An instance of ``reverse_iterator`` with a
default constructed base object.
``explicit reverse_iterator(Iterator x);``
:Returns: An instance of ``reverse_iterator`` with a
base object copy constructed from ``x``.
::
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``reverse_iterator`` that is a copy of ``r``.

View File

@ -1,169 +0,0 @@
<?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.0: http://docutils.sourceforge.net/" />
<title>Transform Iterator</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="2003-08-05" />
<meta name="copyright" content="Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="transform-iterator">
<h1 class="title">Transform Iterator</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" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" 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" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" 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>2003-08-05</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="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"></td>
</tr>
</tbody>
</table>
<p>The transform iterator adapts an iterator by applying some function
object to the result of dereferencing the iterator. In other words,
the <tt class="literal"><span class="pre">operator*</span></tt> of the transform iterator first dereferences the
base iterator, passes the result of this to the function object, and
then returns the result.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#transform-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#transform-iterator-public-operations" id="id2" name="id2"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></li>
<li><a class="reference" href="#transform-iterator-private-operations" id="id3" name="id3"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class AdaptableUnaryFunction,
class Iterator,
class Reference = use_default,
class Value = use_default&gt;
class transform_iterator
: public iterator_adaptor&lt;/* see discussion */&gt;
{
friend class iterator_core_access;
public:
transform_iterator();
transform_iterator(Iterator const&amp; x, AdaptableUnaryFunction f);
template&lt;class OtherIterator, class R2, class V2&gt;
transform_iterator(
transform_iterator&lt;AdaptableUnaryFunction, OtherIterator, R2, V2&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
AdaptableUnaryFunction functor() const;
private:
typename transform_iterator::value_type dereference() const;
AdaptableUnaryFunction m_f;
};
</pre>
<div class="section" id="transform-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="transform-iterator-requirements"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
<p>The type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> must be Assignable, Copy
Constructible, and the expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid where <tt class="literal"><span class="pre">f</span></tt>
is an object of type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of
type <tt class="literal"><span class="pre">AdaptableUnaryFunction::argument_type</span></tt>, and where the type of
<tt class="literal"><span class="pre">f(x)</span></tt> must be <tt class="literal"><span class="pre">AdaptableUnaryFunction::result_type</span></tt>.</p>
<p>The type <tt class="literal"><span class="pre">Iterator</span></tt> must at least model Readable Iterator. The
resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
following options that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<blockquote>
<ul class="simple">
<li>Writable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> of the
<tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> is a non-const reference.</li>
<li>Readable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> is a const
reference.</li>
<li>Readable Iterator otherwise.</li>
</ul>
</blockquote>
<p>The <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined standard traversal
concept that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of <tt class="literal"><span class="pre">transform_iterator</span></tt> is
<tt class="literal"><span class="pre">remove_reference&lt;result_type&gt;::type</span></tt>. The <tt class="literal"><span class="pre">reference</span></tt> type is
<tt class="literal"><span class="pre">result_type</span></tt>.</p>
</div>
<div class="section" id="transform-iterator-public-operations">
<h1><a class="toc-backref" href="#id2" name="transform-iterator-public-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></h1>
<p><tt class="literal"><span class="pre">transform_iterator();</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
and <tt class="literal"><span class="pre">m_iterator</span></tt> default constructed.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">transform_iterator(Iterator</span> <span class="pre">const&amp;</span> <span class="pre">x,</span> <span class="pre">AdaptableUnaryFunction</span> <span class="pre">f);</span></tt></p>
<table class="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 instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
initialized to <tt class="literal"><span class="pre">f</span></tt> and <tt class="literal"><span class="pre">m_iterator</span></tt> initialized to <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template&lt;class OtherIterator, class R2, class V2&gt;
transform_iterator(
transform_iterator&lt;AdaptableUnaryFunction, OtherIterator, R2, V2&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
</pre>
<table class="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 instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">t</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">AdaptableUnaryFunction</span> <span class="pre">functor()</span> <span class="pre">const;</span></tt></p>
<table class="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="literal"><span class="pre">m_f</span></tt></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="transform-iterator-private-operations">
<h1><a class="toc-backref" href="#id3" name="transform-iterator-private-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></h1>
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">transform_iterator::value_type</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
<table class="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="literal"><span class="pre">m_f(transform_iterator::dereference());</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -1,23 +0,0 @@
++++++++++++++++++++
Transform Iterator
++++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract:
.. include:: transform_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: transform_iterator_ref.rst

View File

@ -1,5 +0,0 @@
The transform iterator adapts an iterator by applying some function
object to the result of dereferencing the iterator. In other words,
the ``operator*`` of the transform iterator first dereferences the
base iterator, passes the result of this to the function object, and
then returns the result.

View File

@ -1,95 +0,0 @@
::
template <class AdaptableUnaryFunction,
class Iterator,
class Reference = use_default,
class Value = use_default>
class transform_iterator
: public iterator_adaptor</* see discussion */>
{
friend class iterator_core_access;
public:
transform_iterator();
transform_iterator(Iterator const& x, AdaptableUnaryFunction f);
template<class OtherIterator, class R2, class V2>
transform_iterator(
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
AdaptableUnaryFunction functor() const;
private:
typename transform_iterator::value_type dereference() const;
AdaptableUnaryFunction m_f;
};
``transform_iterator`` requirements
...................................
The type ``AdaptableUnaryFunction`` must be Assignable, Copy
Constructible, and the expression ``f(x)`` must be valid where ``f``
is an object of type ``AdaptableUnaryFunction``, ``x`` is an object of
type ``AdaptableUnaryFunction::argument_type``, and where the type of
``f(x)`` must be ``AdaptableUnaryFunction::result_type``.
The type ``Iterator`` must at least model Readable Iterator. The
resulting ``transform_iterator`` models the most refined of the
following options that is also modeled by ``Iterator``.
* Writable Lvalue Iterator if the ``result_type`` of the
``AdaptableUnaryFunction`` is a non-const reference.
* Readable Lvalue Iterator if the ``result_type`` is a const
reference.
* Readable Iterator otherwise.
The ``transform_iterator`` models the most refined standard traversal
concept that is modeled by ``Iterator``.
The ``value_type`` of ``transform_iterator`` is
``remove_reference<result_type>::type``. The ``reference`` type is
``result_type``.
``transform_iterator`` public operations
........................................
``transform_iterator();``
:Returns: An instance of ``transform_iterator`` with ``m_f``
and ``m_iterator`` default constructed.
``transform_iterator(Iterator const& x, AdaptableUnaryFunction f);``
:Returns: An instance of ``transform_iterator`` with ``m_f``
initialized to ``f`` and ``m_iterator`` initialized to ``x``.
::
template<class OtherIterator, class R2, class V2>
transform_iterator(
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
:Returns: An instance of ``transform_iterator`` that is a copy of ``t``.
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
``AdaptableUnaryFunction functor() const;``
:Returns: ``m_f``
``transform_iterator`` private operations
.........................................
``typename transform_iterator::value_type dereference() const;``
:Returns: ``m_f(transform_iterator::dereference());``

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -1 +0,0 @@
unit-test ia1 : reverse_iterator.cpp : <sysinclude>../../.. <sysinclude>$(BOOST) ;

View File

@ -1,16 +0,0 @@
#include <boost/iterator/iterator_adaptors.hpp>
#include <boost/cstdlib.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
int x[] = { 1, 2, 3, 4 };
boost::reverse_iterator<int*, int, int&, int*,
boost::iterator_tag<boost::mutable_lvalue_iterator_tag, boost::random_access_traversal_tag>
, std::ptrdiff_t> first(x + 4), last(x);
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}

View File

@ -1,55 +0,0 @@
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// Revision History:
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
#include <iterator>
namespace boost {
template <class UnaryFunction>
class function_output_iterator {
typedef function_output_iterator self;
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
: m_f(f) {}
struct output_proxy {
output_proxy(UnaryFunction& f) : m_f(f) { }
template <class T> output_proxy& operator=(const T& value) {
m_f(value);
return *this;
}
UnaryFunction& m_f;
};
output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; }
self& operator++(int) { return *this; }
private:
UnaryFunction m_f;
};
template <class UnaryFunction>
inline function_output_iterator<UnaryFunction>
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
return function_output_iterator<UnaryFunction>(f);
}
} // namespace boost
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP

View File

@ -1,426 +0,0 @@
// (C) Copyright Jeremy Siek and David Abrahams 2000-2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its suitability
// for any purpose.
//
// Revision History:
// 11 Feb 2001 Use new iterator_adaptor interface, Fixes for Borland.
// (Dave Abrahams)
// 04 Feb 2001 Support for user-defined iterator categories (Dave Abrahams)
// 30 Jan 2001 Initial Checkin (Dave Abrahams)
#ifndef BOOST_HALF_OPEN_RANGE_HPP_
# define BOOST_HALF_OPEN_RANGE_HPP_
# include <boost/counting_iterator.hpp>
# include <functional>
# include <cassert>
# include <boost/operators.hpp>
# include <string>
# include <stdexcept>
# include <iterator>
namespace boost {
namespace detail {
// Template class choose_finish -- allows us to maintain the invariant that
// start() <= finish() on half_open_range specializations that support random
// access.
#ifdef __MWERKS__
template <class T>
const T& choose_finish(const T&, const T& finish, std::input_iterator_tag)
{
return finish;
}
template <class T>
const T& choose_finish(const T&, const T& finish, std::output_iterator_tag)
{
return finish;
}
template <class T>
const T& choose_finish(const T& start, const T& finish, std::random_access_iterator_tag)
{
return finish < start ? start : finish;
}
#else
template <bool is_random_access> struct finish_chooser;
template <>
struct finish_chooser<false>
{
template <class T>
struct rebind
{
static T choose(const T&, const T& finish)
{ return finish; }
};
};
template <>
struct finish_chooser<true>
{
template <class T>
struct rebind
{
static T choose(const T& start, const T& finish)
{ return finish < start ? start : finish; }
};
};
template <class Category, class Incrementable>
struct choose_finish
{
static const Incrementable choose(const Incrementable& start, const Incrementable& finish)
{
return finish_chooser<(
::boost::is_convertible<Category*,std::random_access_iterator_tag*>::value
)>::template rebind<Incrementable>::choose(start, finish);
}
};
#endif
}
template <class Incrementable>
struct half_open_range
{
typedef typename counting_iterator_generator<Incrementable>::type iterator;
private: // utility type definitions
// Using iter_t prevents compiler confusion with boost::iterator
typedef typename counting_iterator_generator<Incrementable>::type iter_t;
typedef std::less<Incrementable> less_value;
typedef typename iter_t::iterator_category category;
typedef half_open_range<Incrementable> self;
public:
typedef iter_t const_iterator;
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
typedef typename iterator::reference reference;
typedef typename iterator::reference const_reference;
typedef typename iterator::pointer pointer;
typedef typename iterator::pointer const_pointer;
// It would be nice to select an unsigned type, but this is appropriate
// since the library makes an attempt to select a difference_type which can
// hold the difference between any two iterators.
typedef typename iterator::difference_type size_type;
half_open_range(Incrementable start, Incrementable finish)
: m_start(start),
m_finish(
#ifndef __MWERKS__
detail::choose_finish<category,Incrementable>::choose(start, finish)
#else
detail::choose_finish(start, finish, category())
#endif
)
{}
// Implicit conversion from std::pair<Incrementable,Incrementable> allows us
// to accept the results of std::equal_range(), for example.
half_open_range(const std::pair<Incrementable,Incrementable>& x)
: m_start(x.first),
m_finish(
#ifndef __MWERKS__
detail::choose_finish<category,Incrementable>::choose(x.first, x.second)
#else
detail::choose_finish(x.first, x.second, category())
#endif
)
{}
half_open_range& operator=(const self& x)
{
m_start = x.m_start;
m_finish = x.m_finish;
return *this;
}
half_open_range& operator=(const std::pair<Incrementable,Incrementable>& x)
{
m_start = x.first;
m_finish =
#ifndef __MWERKS__
detail::choose_finish<category,Incrementable>::choose(x.first, x.second);
#else
detail::choose_finish(x.first, x.second, category();
#endif
}
iterator begin() const { return iterator(m_start); }
iterator end() const { return iterator(m_finish); }
Incrementable front() const { assert(!this->empty()); return m_start; }
Incrementable back() const { assert(!this->empty()); return boost::prior(m_finish); }
Incrementable start() const { return m_start; }
Incrementable finish() const { return m_finish; }
size_type size() const { return boost::detail::distance(begin(), end()); }
bool empty() const
{
return m_finish == m_start;
}
void swap(half_open_range& x) {
std::swap(m_start, x.m_start);
std::swap(m_finish, x.m_finish);
}
public: // functions requiring random access elements
// REQUIRES: x is reachable from this->front()
bool contains(const value_type& x) const
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
return !less_value()(x, m_start) && less_value()(x, m_finish);
}
bool contains(const half_open_range& x) const
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
return x.empty() || !less_value()(x.m_start, m_start) && !less_value()(m_finish, x.m_finish);
}
bool intersects(const half_open_range& x) const
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
return less_value()(
less_value()(this->m_start, x.m_start) ? x.m_start : this->m_start,
less_value()(this->m_finish, x.m_finish) ? this->m_finish : x.m_finish);
}
half_open_range& operator&=(const half_open_range& x)
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
if (less_value()(this->m_start, x.m_start))
this->m_start = x.m_start;
if (less_value()(x.m_finish, this->m_finish))
this->m_finish = x.m_finish;
if (less_value()(this->m_finish, this->m_start))
this->m_start = this->m_finish;
return *this;
}
half_open_range& operator|=(const half_open_range& x)
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
if (!x.empty())
{
if (this->empty())
{
*this = x;
}
else
{
if (less_value()(x.m_start, this->m_start))
this->m_start = x.m_start;
if (less_value()(this->m_finish, x.m_finish))
this->m_finish = x.m_finish;
}
}
return *this;
}
// REQUIRES: x is reachable from this->front()
const_iterator find(const value_type& x) const
{
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
return const_iterator(this->contains(x) ? x : m_finish);
}
// REQUIRES: index >= 0 && index < size()
value_type operator[](size_type index) const
{
assert(index >= 0 && index < size());
return m_start + index;
}
value_type at(size_type index) const
{
if (index < 0 || index >= size())
throw std::out_of_range(std::string("half_open_range"));
return m_start + index;
}
private: // data members
Incrementable m_start, m_finish;
};
template <class Incrementable>
half_open_range<Incrementable> operator|(
half_open_range<Incrementable> x,
const half_open_range<Incrementable>& y)
{
return x |= y;
}
template <class Incrementable>
half_open_range<Incrementable> operator&(
half_open_range<Incrementable> x,
const half_open_range<Incrementable>& y)
{
return x &= y;
}
template <class Incrementable>
inline bool operator==(
const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
const bool y_empty = y.empty();
return x.empty() ? y_empty : !y_empty && x.start() == y.start() && x.finish() == y.finish();
}
template <class Incrementable>
inline bool operator!=(
const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return !(x == y);
}
template <class Incrementable>
inline half_open_range<Incrementable>
make_half_open_range(Incrementable first, Incrementable last)
{
return half_open_range<Incrementable>(first, last);
}
template <class Incrementable>
bool intersects(
const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return x.intersects(y);
}
template <class Incrementable>
bool contains(
const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return x.contains(y);
}
} // namespace boost
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace std {
template <class Incrementable> struct less<boost::half_open_range<Incrementable> >
: binary_function<
boost::half_open_range<Incrementable>,
boost::half_open_range<Incrementable>,bool>
{
bool operator()(
const boost::half_open_range<Incrementable>& x,
const boost::half_open_range<Incrementable>& y) const
{
less<Incrementable> cmp;
return !y.empty() && (
cmp(x.start(), y.start())
|| !cmp(y.start(), x.start())
&& cmp(x.finish(), y.finish()));
}
};
template <class Incrementable> struct less_equal<boost::half_open_range<Incrementable> >
: binary_function<
boost::half_open_range<Incrementable>,
boost::half_open_range<Incrementable>,bool>
{
bool operator()(
const boost::half_open_range<Incrementable>& x,
const boost::half_open_range<Incrementable>& y) const
{
typedef boost::half_open_range<Incrementable> range;
less<range> cmp;
return !cmp(y,x);
}
};
template <class Incrementable> struct greater<boost::half_open_range<Incrementable> >
: binary_function<
boost::half_open_range<Incrementable>,
boost::half_open_range<Incrementable>,bool>
{
bool operator()(
const boost::half_open_range<Incrementable>& x,
const boost::half_open_range<Incrementable>& y) const
{
typedef boost::half_open_range<Incrementable> range;
less<range> cmp;
return cmp(y,x);
}
};
template <class Incrementable> struct greater_equal<boost::half_open_range<Incrementable> >
: binary_function<
boost::half_open_range<Incrementable>,
boost::half_open_range<Incrementable>,bool>
{
bool operator()(
const boost::half_open_range<Incrementable>& x,
const boost::half_open_range<Incrementable>& y) const
{
typedef boost::half_open_range<Incrementable> range;
less<range> cmp;
return !cmp(x,y);
}
};
} // namespace std
#else
namespace boost {
// Can't partially specialize std::less et al, so we must provide the operators
template <class Incrementable>
bool operator<(const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return !y.empty() && (
x.empty() || std::less<Incrementable>()(x.start(), y.start())
|| !std::less<Incrementable>()(y.start(), x.start())
&& std::less<Incrementable>()(x.finish(), y.finish()));
}
template <class Incrementable>
bool operator>(const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return y < x;
}
template <class Incrementable>
bool operator<=(const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return !(y < x);
}
template <class Incrementable>
bool operator>=(const half_open_range<Incrementable>& x,
const half_open_range<Incrementable>& y)
{
return !(x < y);
}
} // namespace boost
#endif
#endif // BOOST_HALF_OPEN_RANGE_HPP_

View File

@ -1,60 +0,0 @@
// interator.hpp workarounds for non-conforming standard libraries ---------//
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
// 26 Jun 00 Initial version (Jeremy Siek)
#ifndef BOOST_ITERATOR_HPP
#define BOOST_ITERATOR_HPP
#include <iterator>
#include <cstddef> // std::ptrdiff_t
#include <boost/config.hpp>
namespace boost
{
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
template <class Category, class T,
class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator
{
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
# else
// declare iterator_base in namespace detail to work around MSVC bugs which
// prevent derivation from an identically-named class in a different namespace.
namespace detail {
template <class Category, class T, class Distance, class Pointer, class Reference>
# if !defined(BOOST_MSVC_STD_ITERATOR)
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
# else
struct iterator_base : std::iterator<Category, T, Distance>
{
typedef Reference reference;
typedef Pointer pointer;
typedef Distance difference_type;
};
# endif
}
template <class Category, class T, class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator : detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
# endif
} // namespace boost
#endif // BOOST_ITERATOR_HPP

View File

@ -1,13 +0,0 @@
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_ITERATOR_ADAPTOR_13062003HK_HPP
#define BOOST_ITERATOR_ADAPTOR_13062003HK_HPP
#define BOOST_ITERATOR_ADAPTORS_VERSION 0x0200
#include <boost/iterator/iterator_adaptor.hpp>
#endif // BOOST_ITERATOR_ADAPTOR_13062003HK_HPP

View File

@ -1,75 +0,0 @@
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_INT_ITERATOR_H
#define BOOST_INT_ITERATOR_H
#include <boost/iterator.hpp>
#if !defined BOOST_MSVC
#include <boost/operators.hpp>
#endif
#include <iostream>
//using namespace std;
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost {
#endif
// this should use random_access_iterator_helper but I've had
// VC++ portablility problems with that. -JGS
template <class IntT>
class int_iterator
{
typedef int_iterator self;
public:
typedef std::random_access_iterator_tag iterator_category;
typedef IntT value_type;
typedef IntT& reference;
typedef IntT* pointer;
typedef std::ptrdiff_t difference_type;
inline int_iterator() : _i(0) { }
inline int_iterator(IntT i) : _i(i) { }
inline int_iterator(const self& x) : _i(x._i) { }
inline self& operator=(const self& x) { _i = x._i; return *this; }
inline IntT operator*() { return _i; }
inline IntT operator[](IntT n) { return _i + n; }
inline self& operator++() { ++_i; return *this; }
inline self operator++(int) { self t = *this; ++_i; return t; }
inline self& operator+=(IntT n) { _i += n; return *this; }
inline self operator+(IntT n) { self t = *this; t += n; return t; }
inline self& operator--() { --_i; return *this; }
inline self operator--(int) { self t = *this; --_i; return t; }
inline self& operator-=(IntT n) { _i -= n; return *this; }
inline IntT operator-(const self& x) const { return _i - x._i; }
inline bool operator==(const self& x) const { return _i == x._i; }
// vc++ had a problem finding != in random_access_iterator_helper
// need to look into this... for now implementing everything here -JGS
inline bool operator!=(const self& x) const { return _i != x._i; }
inline bool operator<(const self& x) const { return _i < x._i; }
inline bool operator<=(const self& x) const { return _i <= x._i; }
inline bool operator>(const self& x) const { return _i > x._i; }
inline bool operator>=(const self& x) const { return _i >= x._i; }
protected:
IntT _i;
};
template <class IntT>
inline int_iterator<IntT>
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} /* namespace boost */
#endif
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost {
using ::int_iterator;
}
#endif
#endif /* BOOST_INT_ITERATOR_H */

View File

@ -1,59 +0,0 @@
// (C) Copyright David Abrahams and Jeremy Siek 2000-2001. Permission to copy,
// use, modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided "as is"
// without express or implied warranty, and with no claim as to its suitability
// for any purpose.
//
// Revision History:
// 04 Jan 2001 Factored counting_iterator stuff into
// boost/counting_iterator.hpp (David Abrahams)
#ifndef BOOST_INTEGER_RANGE_HPP_
#define BOOST_INTEGER_RANGE_HPP_
#include <boost/config.hpp>
#include <boost/iterator/counting_iterator.hpp>
namespace boost {
//=============================================================================
// Counting Iterator and Integer Range Class
template <class IntegerType>
struct integer_range {
typedef counting_iterator<IntegerType> iterator;
typedef iterator const_iterator;
typedef IntegerType value_type;
typedef std::ptrdiff_t difference_type;
typedef IntegerType reference;
typedef IntegerType const_reference;
typedef const IntegerType* pointer;
typedef const IntegerType* const_pointer;
typedef IntegerType size_type;
integer_range(IntegerType start, IntegerType finish)
: m_start(start), m_finish(finish) { }
iterator begin() const { return iterator(m_start); }
iterator end() const { return iterator(m_finish); }
size_type size() const { return m_finish - m_start; }
bool empty() const { return m_finish == m_start; }
void swap(integer_range& x) {
std::swap(m_start, x.m_start);
std::swap(m_finish, x.m_finish);
}
protected:
IntegerType m_start, m_finish;
};
template <class IntegerType>
inline integer_range<IntegerType>
make_integer_range(IntegerType first, IntegerType last)
{
return integer_range<IntegerType>(first, last);
}
} // namespace boost
#endif // BOOST_INTEGER_RANGE_HPP_

View File

@ -1,7 +0,0 @@
// Copyright David Abrahams 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#include <boost/iterator_adaptors.hpp>

View File

@ -1,258 +0,0 @@
// Copyright David Abrahams and Jeremy Siek 2003. Permission to copy,
// use, modify, sell and distribute this software is granted provided
// this copyright notice appears in all copies. This software is
// provided "as is" without express or implied warranty, and with no
// claim as to its suitability for any purpose.
#ifndef BOOST_ITERATOR_TESTS_HPP
# define BOOST_ITERATOR_TESTS_HPP
// This is meant to be the beginnings of a comprehensive, generic
// test suite for STL concepts such as iterators and containers.
//
// Revision History:
// 28 Apr 2002 Fixed input iterator requirements.
// For a == b a++ == b++ is no longer required.
// See 24.1.1/3 for details.
// (Thomas Witt)
// 08 Feb 2001 Fixed bidirectional iterator test so that
// --i is no longer a precondition.
// (Jeremy Siek)
// 04 Feb 2001 Added lvalue test, corrected preconditions
// (David Abrahams)
# include <iterator>
# include <assert.h>
# include <boost/type_traits.hpp>
# include <boost/static_assert.hpp>
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
namespace boost {
// use this for the value type
struct dummyT {
dummyT() { }
dummyT(detail::dummy_constructor) { }
dummyT(int x) : m_x(x) { }
int foo() const { return m_x; }
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
int m_x;
};
// Tests whether type Iterator satisfies the requirements for a
// TrivialIterator.
// Preconditions: i != j, *i == val
template <class Iterator, class T>
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
{
Iterator k;
assert(i == i);
assert(j == j);
assert(i != j);
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
T v = *i;
#else
typename std::iterator_traits<Iterator>::value_type v = *i;
#endif
assert(v == val);
#if 0
// hmm, this will give a warning for transform_iterator... perhaps
// this should be separated out into a stand-alone test since there
// are several situations where it can't be used, like for
// integer_range::iterator.
assert(v == i->foo());
#endif
k = i;
assert(k == k);
assert(k == i);
assert(k != j);
assert(*k == val);
}
// Preconditions: i != j
template <class Iterator, class T>
void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
{
*i = val;
trivial_iterator_test(i, j, val);
}
// Preconditions: *i == v1, *++i == v2
template <class Iterator, class T>
void input_iterator_test(Iterator i, T v1, T v2)
{
Iterator i1(i);
assert(i == i1);
assert(!(i != i1));
// I can see no generic way to create an input iterator
// that is in the domain of== of i and != i.
// The following works for istream_iterator but is not
// guaranteed to work for arbitrary input iterators.
//
// Iterator i2;
//
// assert(i != i2);
// assert(!(i == i2));
assert(*i1 == v1);
assert(*i == v1);
// we cannot test for equivalence of (void)++i & (void)i++
// as i is only guaranteed to be single pass.
assert(*i++ == v1);
i1 = i;
assert(i == i1);
assert(!(i != i1));
assert(*i1 == v2);
assert(*i == v2);
// i is dereferencable, so it must be incrementable.
++i;
// how to test for operator-> ?
}
// how to test output iterator?
template <bool is_pointer> struct lvalue_test
{
template <class Iterator> static void check(Iterator)
{
# ifndef BOOST_NO_STD_ITERATOR_TRAITS
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
# else
typedef typename Iterator::reference reference;
typedef typename Iterator::value_type value_type;
# endif
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
|| boost::is_same<reference,const value_type&>::value
));
}
};
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
template <> struct lvalue_test<true> {
template <class T> static void check(T) {}
};
#endif
template <class Iterator, class T>
void forward_iterator_test(Iterator i, T v1, T v2)
{
input_iterator_test(i, v1, v2);
Iterator i1 = i, i2 = i;
assert(i == i1++);
assert(i != ++i2);
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
++i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
// borland doesn't allow non-type template parameters
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
#endif
}
// Preconditions: *i == v1, *++i == v2
template <class Iterator, class T>
void bidirectional_iterator_test(Iterator i, T v1, T v2)
{
forward_iterator_test(i, v1, v2);
++i;
Iterator i1 = i, i2 = i;
assert(i == i1--);
assert(i != --i2);
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
--i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
}
// mutable_bidirectional_iterator_test
// Preconditions: [i,i+N) is a valid range
template <class Iterator, class TrueVals>
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
{
bidirectional_iterator_test(i, vals[0], vals[1]);
const Iterator j = i;
int c;
for (c = 0; c < N-1; ++c) {
assert(i == j + c);
assert(*i == vals[c]);
assert(*i == j[c]);
assert(*i == *(j + c));
assert(*i == *(c + j));
++i;
assert(i > j);
assert(i >= j);
assert(j <= i);
assert(j < i);
}
Iterator k = j + N - 1;
for (c = 0; c < N-1; ++c) {
assert(i == k - c);
assert(*i == vals[N - 1 - c]);
assert(*i == j[N - 1 - c]);
Iterator q = k - c;
assert(*i == *q);
assert(i > j);
assert(i >= j);
assert(j <= i);
assert(j < i);
--i;
}
}
// Precondition: i != j
template <class Iterator, class ConstIterator>
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
{
assert(i != j);
assert(j != i);
ConstIterator k(i);
assert(k == i);
assert(i == k);
k = i;
assert(k == i);
assert(i == k);
}
} // namespace boost
#endif // BOOST_ITERATOR_TESTS_HPP

View File

@ -1,62 +0,0 @@
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
#ifndef SHARED_CONTAINER_ITERATOR_RG08102002_HPP
#define SHARED_CONTAINER_ITERATOR_RG08102002_HPP
#include "boost/iterator_adaptors.hpp"
#include "boost/shared_ptr.hpp"
#include <utility>
namespace boost {
template <typename Container>
class shared_container_iterator : public iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> {
typedef iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> super_t;
typedef typename Container::iterator iterator_t;
typedef boost::shared_ptr<Container> container_ref_t;
container_ref_t container_ref;
public:
shared_container_iterator() { }
shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
super_t(x), container_ref(c) { }
};
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator iter,
boost::shared_ptr<Container> const& container) {
typedef shared_container_iterator<Container> iterator;
return iterator(iter,container);
}
template <typename Container>
std::pair<
shared_container_iterator<Container>,
shared_container_iterator<Container> >
make_shared_container_range(boost::shared_ptr<Container> const& container) {
return
std::make_pair(
make_shared_container_iterator(container->begin(),container),
make_shared_container_iterator(container->end(),container));
}
} // namespace boost
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP

View File

@ -1,46 +0,0 @@
# Copyright David Abrahams 2003. Permission to copy, use,
# modify, sell and distribute this software is granted provided this
# copyright notice appears in all copies. This software is provided
# "as is" without express or implied warranty, and with no claim as
# to its suitability for any purpose.
subproject libs/iterator/test ;
import testing ;
test-suite iterator
:
# These first two tests will run last, and are expected to fail
# for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated
# compilation problems.
[ run is_convertible_fail.cpp ]
# These tests should work for just about everything.
[ run unit_tests.cpp ]
[ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ]
[ run iterator_adaptor_test.cpp ]
[ compile iterator_archetype_cc.cpp ]
[ run transform_iterator_test.cpp ]
[ run indirect_iterator_test.cpp ]
[ run filter_iterator_test.cpp ]
[ run reverse_iterator_test.cpp ]
[ run counting_iterator_test.cpp ]
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
]
[ run zip_iterator_test.cpp ]
[ run ../../utility/iterator_adaptor_examples.cpp ]
[ run ../../utility/counting_iterator_example.cpp ]
[ run ../../utility/filter_iterator_example.cpp ]
[ run ../../utility/fun_out_iter_example.cpp ]
[ run ../../utility/indirect_iterator_example.cpp ]
[ run ../../utility/projection_iterator_example.cpp ]
[ run ../../utility/reverse_iterator_example.cpp ]
[ run ../../utility/transform_iterator_example.cpp ]
[ run ../../utility/iterator_traits_test.cpp ]
;