Compare commits

...

30 Commits

Author SHA1 Message Date
6ca935d9fe Allow WritableIteratorConcept to be used with one parameter for
iterators with a sensible value_type


[SVN r20904]
2003-11-21 23:39:10 +00:00
dea89aa823 Added missing #include
[SVN r20896]
2003-11-20 21:42:38 +00:00
ce5d2ec4b4 Reformatting
[SVN r20895]
2003-11-20 21:42:14 +00:00
640379ac34 Better error messages on failure
[SVN r20894]
2003-11-20 21:41:33 +00:00
7cbe926f29 BOOST_TT_BROKEN_COMPILER_SPEC(dummyT) is now supplied with dummyT
[SVN r20893]
2003-11-20 21:41:13 +00:00
5113e4fbec Broken compiler workarounds
[SVN r20892]
2003-11-20 21:40:50 +00:00
66183e43f5 Broaden tests to detect more cases.
[SVN r20891]
2003-11-20 21:40:16 +00:00
4247559960 Broken compiler workarounds, cleanup
[SVN r20890]
2003-11-20 21:38:48 +00:00
c7c6448bd5 Make zip_iterator's test run later, because it's failing on a few
compilers still.


[SVN r20889]
2003-11-20 21:38:09 +00:00
218778bb94 Workarounds for broken compilers
[SVN r20886]
2003-11-20 21:17:54 +00:00
4b4de44736 Workarounds for vc6 and vc7
[SVN r20885]
2003-11-20 21:17:00 +00:00
8deb1c20fb Don't adjust default reference type computation based on
BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY


[SVN r20884]
2003-11-20 21:15:31 +00:00
20e6d71755 undo pointless Borland workarounds
[SVN r20883]
2003-11-20 21:14:29 +00:00
52f72c2115 Uncomment mistakenly disabled tests
[SVN r20880]
2003-11-20 16:17:55 +00:00
6b2da49430 Borland workarounds
[SVN r20879]
2003-11-20 16:17:30 +00:00
f46f7f8091 vc6 workarounds
[SVN r20869]
2003-11-19 22:04:02 +00:00
22670777b8 Change the way input_output_iterator_tag is convertible to
output_iterator_tag from inheritance to implicit conversion operator,
to avoid some tag dispatch ambiguities.


[SVN r20868]
2003-11-19 22:03:48 +00:00
6270de1db0 ETI workaround
[SVN r20867]
2003-11-19 22:02:36 +00:00
6e06e4f89e Refactored minimum_category
[SVN r20865]
2003-11-19 20:16:52 +00:00
eb73b8e0e2 Got everything working with GCC
[SVN r20864]
2003-11-19 20:08:00 +00:00
7ffe2601a9 Commenting and cleanups after a hurried checkin last night
[SVN r20858]
2003-11-19 14:26:43 +00:00
62b70f57a9 progress
[SVN r20853]
2003-11-19 04:25:17 +00:00
cd37eb3bfb Modified Files:
Tag: simplify
	iterator_adaptor.hpp iterator_categories.hpp
	iterator_facade.hpp
 Added Files:
  Tag: simplify
 	is_lvalue_iterator.hpp is_readable_iterator.hpp
 	detail/any_conversion_eater.hpp

The above files were moved over from HEAD and will cause confusion during the merge

Got iterator_adaptor_test.cpp working


[SVN r20843]
2003-11-18 04:19:28 +00:00
bda5890235 iterator_adaptor_test
[SVN r20842]
2003-11-18 04:08:40 +00:00
d51c5ebf07 This commit was manufactured by cvs2svn to create branch 'simplify'.
[SVN r20841]
2003-11-18 03:04:16 +00:00
6f90b8b161 iterator_categories reformed, test added
[SVN r20829]
2003-11-17 16:52:15 +00:00
6ec791e3b9 checkpoint
[SVN r20733]
2003-11-08 04:12:18 +00:00
20f188d971 progress
[SVN r20167]
2003-09-23 22:58:59 +00:00
7273be17c0 Begun simplification
[SVN r20165]
2003-09-23 02:04:53 +00:00
77a89a0b89 This commit was manufactured by cvs2svn to create branch 'simplify'.
[SVN r20118]
2003-09-19 18:44:54 +00:00
101 changed files with 1969 additions and 12184 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

@ -15,7 +15,12 @@
namespace boost {
template <class Incrementable, class Category, class Difference> class counting_iterator;
template <
class Incrementable
, class CategoryOrTraversal
, class Difference
>
class counting_iterator;
namespace detail
{
@ -67,35 +72,38 @@ namespace detail
};
BOOST_STATIC_ASSERT(is_numeric<int>::value);
template <class Incrementable, class Category, class Difference>
template <class Incrementable, class CategoryOrTraversal, class Difference>
struct counting_iterator_base
{
typedef typename mpl::apply_if<
is_same<Category, use_default>
typedef typename detail::ia_dflt_help<
CategoryOrTraversal
, mpl::apply_if<
is_numeric<Incrementable>
, mpl::identity<std::random_access_iterator_tag>
, BOOST_ITERATOR_CATEGORY<Incrementable>
, mpl::identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
>
, mpl::identity<Category>
>::type category;
>::type traversal;
typedef typename mpl::apply_if<
is_same<Difference, use_default>
typedef typename detail::ia_dflt_help<
Difference
, mpl::apply_if<
is_numeric<Incrementable>
, numeric_difference<Incrementable>
, iterator_difference<Incrementable>
>
, mpl::identity<Difference>
>::type difference;
typedef iterator_adaptor<
counting_iterator<Incrementable, Category, Difference> // self
, Incrementable // Base
, Incrementable // value_type
, category
, Incrementable const& // reference
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
, Incrementable // Base
, Incrementable // Value
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
# endif
, traversal
, Incrementable const& // reference
, difference
> type;
};
@ -128,11 +136,20 @@ namespace detail
};
}
template <class Incrementable, class Category = use_default, class Difference = use_default>
template <
class Incrementable
, class CategoryOrTraversal = use_default
, class Difference = use_default
>
class counting_iterator
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
: public detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference
>::type
{
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
typedef typename detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference
>::type super_t;
friend class iterator_core_access;
public:

View File

@ -0,0 +1,19 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
# define ANY_CONVERSION_EATER_DWA20031117_HPP
namespace boost { namespace detail {
// This type can be used in traits to "eat" up the one user-defined
// implicit conversion allowed.
struct any_conversion_eater
{
template <class T>
any_conversion_eater(T const&);
};
}} // namespace boost::detail
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP

View File

@ -1,360 +1 @@
// (C) Copyright Thomas Witt 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.
#ifndef BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
# define BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
# include <boost/config.hpp>
# include <boost/iterator/detail/config_def.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/mpl/or.hpp>
# include <boost/mpl/and.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
# include <iterator>
namespace boost
{
// faked new old-style categories needed to make new->old mapping
// work
namespace detail
{
struct null_category_tag {};
struct input_output_iterator_tag : std::input_iterator_tag, std::output_iterator_tag {};
}
//
// Access Categories
//
struct readable_iterator_tag
{
typedef std::input_iterator_tag max_category;
};
struct writable_iterator_tag
{
typedef std::output_iterator_tag max_category;
};
struct swappable_iterator_tag
{
typedef detail::null_category_tag max_category;
};
struct readable_writable_iterator_tag
: virtual readable_iterator_tag
, virtual writable_iterator_tag
, virtual swappable_iterator_tag
{
typedef detail::input_output_iterator_tag max_category;
};
struct readable_lvalue_iterator_tag
: virtual readable_iterator_tag
{
typedef std::random_access_iterator_tag max_category;
};
struct writable_lvalue_iterator_tag
: virtual public readable_writable_iterator_tag
, virtual public readable_lvalue_iterator_tag
{
typedef std::random_access_iterator_tag max_category;
};
//
// Traversal Categories
//
struct incrementable_traversal_tag
{
typedef std::output_iterator_tag max_category;
};
struct single_pass_traversal_tag
: incrementable_traversal_tag
{
typedef detail::input_output_iterator_tag max_category;
};
struct forward_traversal_tag
: single_pass_traversal_tag
{
typedef std::forward_iterator_tag max_category;
};
struct bidirectional_traversal_tag
: forward_traversal_tag
{
typedef std::bidirectional_iterator_tag max_category;
};
struct random_access_traversal_tag
: bidirectional_traversal_tag
{
typedef std::random_access_iterator_tag max_category;
};
struct error_iterator_tag { };
namespace detail
{
//
// Tag detection meta functions
//
// I bet this is defined somewhere else. Let's wait and see.
struct error_type;
# ifndef BOOST_NO_IS_CONVERTIBLE
// True iff T is a tag "derived" from Tag
template <class Tag, class T>
struct is_tag
: mpl::or_<
is_convertible<T, Tag>
// Because we can't actually get forward_iterator_tag to
// derive from input_output_iterator_tag, we need this
// case.
, mpl::and_<
is_convertible<T,std::forward_iterator_tag>
, is_convertible<detail::input_output_iterator_tag,Tag>
>
>
{};
# else
template <class Tag, class T>
struct is_tag;
# endif
// Generate specializations which will allow us to find
// null_category_tag as a minimum old-style category for new-style
// iterators which don't have an actual old-style category. We
// need that so there is a valid base class for all new-style
// iterators.
# define BOOST_OLD_ITERATOR_CATEGORY(category) \
template <> \
struct is_tag <detail::null_category_tag, std::category> \
: mpl::true_ {};
BOOST_OLD_ITERATOR_CATEGORY(input_iterator_tag)
BOOST_OLD_ITERATOR_CATEGORY(output_iterator_tag)
BOOST_OLD_ITERATOR_CATEGORY(forward_iterator_tag)
BOOST_OLD_ITERATOR_CATEGORY(bidirectional_iterator_tag)
BOOST_OLD_ITERATOR_CATEGORY(random_access_iterator_tag)
# undef BOOST_OLD_ITERATOR_CATEGORY
template <>
struct is_tag<detail::input_output_iterator_tag,std::forward_iterator_tag>
: mpl::true_
{
};
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct is_tag<T,T> : mpl::true_
{};
# ifdef BOOST_NO_IS_CONVERTIBLE
// Workarounds for CWPro7 which can't detect derivation at
// compile-time.
// Fact of life: we can only detect tag refinement relationships
// among predefined tags.
//
// Algorithm:
// is_tag(T,U) ->
// T == U
// || (exists d in derived_from(T) such that is_tag(d, U))
//
// T == U case is handled above
// false by default
template <class Tag, class T>
struct is_tag_impl : mpl::false_
{};
// The generalized template dispatches to is_tag_impl because
// is_tag<T,T> and is_tag<some_tag,T> are equally specialized.
// This technique simulates making is_tag<T,T> more-specialized.
template <class Tag, class T>
struct is_tag
: is_tag_impl<Tag, T>
{};
# define BOOST_ITERATOR_DERIVED_TAG1(base, derived) \
BOOST_ITERATOR_DERIVED_TAG1_AUX(base, _, derived)
# define BOOST_ITERATOR_DERIVED_TAG1_AUX(base, underscore, derived) \
template<class T> \
struct is_tag_impl<base##underscore##tag, T> \
: is_tag<derived##underscore##tag, T> \
{ \
};
// Old-style tag relations
template<class T>
struct is_tag_impl<detail::null_category_tag, T>
: mpl::or_<
is_tag<std::output_iterator_tag, T>
, is_tag<std::input_iterator_tag, T>
>
{
};
BOOST_ITERATOR_DERIVED_TAG1(std::output_iterator, detail::input_output_iterator)
BOOST_ITERATOR_DERIVED_TAG1(std::input_iterator, detail::input_output_iterator)
BOOST_ITERATOR_DERIVED_TAG1(detail::input_output_iterator, std::forward_iterator)
BOOST_ITERATOR_DERIVED_TAG1(std::forward_iterator, std::bidirectional_iterator)
BOOST_ITERATOR_DERIVED_TAG1(std::bidirectional_iterator, std::random_access_iterator)
// Access tag relations
BOOST_ITERATOR_DERIVED_TAG1(readable_lvalue_iterator, writable_lvalue_iterator)
BOOST_ITERATOR_DERIVED_TAG1(swappable_iterator, readable_writable_iterator)
BOOST_ITERATOR_DERIVED_TAG1(readable_writable_iterator, writable_lvalue_iterator)
template<class T>
struct is_tag_impl<readable_iterator_tag, T>
: mpl::or_<
is_tag<readable_lvalue_iterator_tag, T>
, is_tag<readable_writable_iterator_tag, T>
>
{
};
BOOST_ITERATOR_DERIVED_TAG1(writable_iterator, readable_writable_iterator)
// Traversal tag relations
BOOST_ITERATOR_DERIVED_TAG1(bidirectional_traversal, random_access_traversal)
BOOST_ITERATOR_DERIVED_TAG1(forward_traversal, bidirectional_traversal)
BOOST_ITERATOR_DERIVED_TAG1(single_pass_traversal, forward_traversal)
BOOST_ITERATOR_DERIVED_TAG1(incrementable_traversal, single_pass_traversal)
# endif // BOOST_NO_IS_CONVERTIBLE workarounds
# endif // ndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Tag, class Known, class Else>
struct known_tag
: mpl::apply_if<is_tag<Known,Tag>, mpl::identity<Known>, Else>
{};
template <class Tag>
struct max_known_traversal_tag
: known_tag<
Tag, random_access_traversal_tag
, known_tag<
Tag, bidirectional_traversal_tag
, known_tag<
Tag, forward_traversal_tag
, known_tag<
Tag, single_pass_traversal_tag
, known_tag<
Tag, incrementable_traversal_tag
, error_iterator_tag
>
>
>
>
>
{};
// Doesn't cope with these odd combinations: readable+swappable,
// writable+swappable. That doesn't matter for the sake of
// new-style tag base computation, which is all it's used for
// anyway.
template <class Tag>
struct max_known_access_tag
: known_tag<
Tag, writable_lvalue_iterator_tag
, known_tag<
Tag, readable_lvalue_iterator_tag
, known_tag<
Tag, readable_writable_iterator_tag
, known_tag<
Tag, writable_iterator_tag
, known_tag<
Tag, readable_iterator_tag
, mpl::apply_if<
is_tag<Tag, swappable_iterator_tag>
, mpl::identity<null_category_tag>
, error_iterator_tag
>
>
>
>
>
>
{};
//
// Returns the minimum category type or error_type
// if T1 and T2 are unrelated.
//
// For compilers not supporting is_convertible this only
// works with the new boost return and traversal category
// types. The exact boost _types_ are required. No derived types
// will work.
//
//
template <class T1, class T2>
struct minimum_category
: mpl::apply_if<
is_tag<T1,T2>
, mpl::identity<T1>
, mpl::if_<
is_tag<T2, T1>
, T2
, error_type
>
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
};
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// Deal with ETI
template <> struct minimum_category<int, int> { typedef minimum_category type; };
# endif
//
// Tag classification for use in iterator_adaptor
//
template <class Tag>
struct is_access_tag
: mpl::or_<
is_tag<readable_iterator_tag, Tag>
, mpl::or_<
is_tag<writable_iterator_tag, Tag>
, is_tag<swappable_iterator_tag, Tag>
>
>
{};
template <class Tag>
struct is_traversal_tag
: is_tag<incrementable_traversal_tag, Tag>
{};
} // namespace detail
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
#error obsolete

View File

@ -18,7 +18,66 @@
#include <boost/config.hpp> // for prior
#include <boost/detail/workaround.hpp>
#define BOOST_ITERATOR_CONFIG_DEF // if you get an error here, you have nested config_def #inclusion.
#ifdef BOOST_ITERATOR_CONFIG_DEF
# error you have nested config_def #inclusion.
#else
# define BOOST_ITERATOR_CONFIG_DEF
#endif
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
// Recall that in general, compilers without partial specialization
// can't strip constness. Consider counting_iterator, which normally
// passes a const Value to iterator_facade. As a result, any code
// which makes a std::vector of the iterator's value_type will fail
// when its allocator declares functions overloaded on reference and
// const_reference (the same type).
//
// Furthermore, Borland 5.5.1 drops constness in enough ways that we
// end up using a proxy for operator[] when we otherwise shouldn't.
// Using reference constness gives it an extra hint that it can
// return the value_type from operator[] directly, but is not
// strictly neccessary. Not sure how best to resolve this one.
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))
# define BOOST_NO_LVALUE_RETURN_DETECTION
# if 0 // test code
struct v {};
typedef char (&no)[3];
template <class T>
no foo(T const&, ...);
template <class T>
char foo(T&, int);
struct value_iterator
{
v operator*() const;
};
template <class T>
struct lvalue_deref_helper
{
static T& x;
enum { value = (sizeof(foo(*x,0)) == 1) };
};
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
# endif
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \

View File

@ -18,6 +18,7 @@
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#undef BOOST_ARG_DEPENDENT_TYPENAME
#undef BOOST_NO_LVALUE_RETURN_DETECTION
#ifdef BOOST_ITERATOR_CONFIG_DEF
# undef BOOST_ITERATOR_CONFIG_DEF

View File

@ -0,0 +1,214 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# include <boost/iterator/iterator_categories.hpp>
# include <boost/static_assert.hpp>
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
# include <boost/mpl/and.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_const.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/python/detail/indirect_traits.hpp>
# endif
//
// iterator_category deduction for iterator_facade
//
// forward declaration
namespace boost { struct use_default; }
namespace boost { namespace detail {
struct input_output_iterator_tag
: std::input_iterator_tag
{
// Using inheritance for only input_iterator_tag helps to avoid
// ambiguities when a stdlib implementation dispatches on a
// function which is overloaded on both input_iterator_tag and
// output_iterator_tag, as STLPort does, in its __valid_range
// function. I claim it's better to avoid the ambiguity in these
// cases.
operator std::output_iterator_tag() const
{
return std::output_iterator_tag();
}
};
//
// True iff the user has explicitly disabled writability of this
// iterator. Pass the iterator_facade's Value parameter and its
// nested ::reference type.
//
template <class ValueParam, class Reference>
struct iterator_writability_disabled
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
: mpl::or_<
is_const<Reference>
, python::detail::is_reference_to_const<Reference>
, is_const<ValueParam>
>
# else
: is_const<ValueParam>
# endif
{};
//
// Convert an iterator_facade's traversal category, Value parameter,
// and ::reference type to an appropriate old-style category.
//
// If writability has been disabled per the above metafunction, the
// result will not be convertible to output_iterator_tag.
//
// Otherwise, if Traversal == single_pass_traversal_tag, the following
// conditions will result in a tag that is convertible both to
// input_iterator_tag and output_iterator_tag:
//
// 1. Reference is a reference to non-const
// 2. Reference is not a reference and is convertible to Value
//
template <class Traversal, class ValueParam, class Reference>
struct iterator_facade_default_category
: mpl::apply_if<
mpl::and_<
is_reference<Reference>
, is_convertible<Traversal,forward_traversal_tag>
>
, mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<std::random_access_iterator_tag>
, mpl::if_<
is_convertible<Traversal,bidirectional_traversal_tag>
, std::bidirectional_iterator_tag
, std::forward_iterator_tag
>
>
, typename mpl::apply_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
, mpl::or_< // check for readability
is_same<ValueParam,use_default>
, is_convertible<Reference, ValueParam>
>
>
, mpl::if_<
iterator_writability_disabled<ValueParam,Reference>
, std::input_iterator_tag
, input_output_iterator_tag
>
, mpl::identity<std::output_iterator_tag>
>
>
{
};
// True iff T is convertible to an old-style iterator category.
template <class T>
struct is_iterator_category
: mpl::or_<
is_convertible<T,std::input_iterator_tag>
, is_convertible<T,std::output_iterator_tag>
>
{
};
template <class T>
struct is_iterator_traversal
: is_convertible<T,incrementable_traversal_tag>
{};
//
// A composite iterator_category tag convertible to Category (a pure
// old-style category) and Traversal (a pure traversal tag).
// Traversal must be a strict increase of the traversal power given by
// Category.
//
template <class Category, class Traversal>
struct iterator_category_with_traversal
: Category, Traversal
{
# if 0
// Because of limitations on multiple user-defined conversions,
// this should be a good test of whether convertibility is enough
// in the spec, or whether we need to specify inheritance.
operator Category() const { return Category(); }
operator Traversal() const { return Traversal(); }
# endif
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// Make sure this isn't used to build any categories where
// convertibility to Traversal is redundant. Should just use the
// Category element in that case.
BOOST_STATIC_ASSERT(
!(is_convertible<
typename iterator_category_to_traversal<Category>::type
, Traversal
>::value));
BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
# endif
};
// Computes an iterator_category tag whose traversal is Traversal and
// which is appropriate for an iterator
template <class Traversal, class ValueParam, class Reference>
struct facade_iterator_category_impl
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
# endif
typedef typename iterator_facade_default_category<
Traversal,ValueParam,Reference
>::type category;
typedef typename mpl::if_<
is_same<
Traversal
, typename iterator_category_to_traversal<category>::type
>
, category
, iterator_category_with_traversal<category,Traversal>
>::type type;
};
//
// Compute an iterator_category for iterator_facade
//
template <class CategoryOrTraversal, class ValueParam, class Reference>
struct facade_iterator_category
: mpl::apply_if<
is_iterator_category<CategoryOrTraversal>
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
>
{
};
}} // namespace boost::detail
# include <boost/iterator/detail/config_undef.hpp>
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP

View File

@ -0,0 +1,98 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
# define MINIMUM_CATEGORY_DWA20031119_HPP
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
namespace boost { namespace detail {
//
// Returns the minimum category type or error_type
// if T1 and T2 are unrelated.
//
// For compilers not supporting is_convertible this only
// works with the new boost return and traversal category
// types. The exact boost _types_ are required. No derived types
// will work.
//
//
template <bool GreaterEqual, bool LessEqual>
struct minimum_category_impl;
template <class T1, class T2>
struct error_not_related_by_convertibility;
template <>
struct minimum_category_impl<true,false>
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
};
template <>
struct minimum_category_impl<false,true>
{
template <class T1, class T2> struct apply
{
typedef T1 type;
};
};
template <>
struct minimum_category_impl<true,true>
{
template <class T1, class T2> struct apply
{
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
typedef T1 type;
};
};
template <>
struct minimum_category_impl<false,false>
{
template <class T1, class T2> struct apply
: error_not_related_by_convertibility<T1,T2>
{
};
};
template <class T1 = mpl::_1, class T2 = mpl::_2>
struct minimum_category
{
typedef minimum_category_impl<
::boost::is_convertible<T1,T2>::value
, ::boost::is_convertible<T2,T1>::value
> outer;
typedef typename outer::template apply<T1,T2> inner;
typedef typename inner::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
};
template <>
struct minimum_category<mpl::_1,mpl::_2>
{
template <class T1, class T2>
struct apply : minimum_category<T1,T2>
{};
};
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct minimum_category<int,int>
{
typedef int type;
};
# endif
}} // namespace boost::detail
#endif // MINIMUM_CATEGORY_DWA20031119_HPP

View File

@ -13,28 +13,42 @@
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/static_assert.hpp>
namespace boost
{
template <class Predicate, class Iterator>
class filter_iterator;
namespace detail
{
template <class Predicate, class Iterator>
struct filter_iterator_base
{
typedef iterator_adaptor<
filter_iterator<Predicate, Iterator>
, Iterator
, use_default
, typename mpl::if_<
is_convertible<
typename iterator_traversal<Iterator>::type
, bidirectional_traversal_tag
>
, forward_traversal_tag
, use_default
>::type
> type;
};
}
template <class Predicate, class Iterator>
class filter_iterator
: public iterator_adaptor<
filter_iterator<Predicate, Iterator>, Iterator
, use_default
, typename detail::minimum_category<
bidirectional_traversal_tag
, typename traversal_category<Iterator>::type
>::type
>
: public detail::filter_iterator_base<Predicate, Iterator>::type
{
typedef iterator_adaptor<
filter_iterator<Predicate, Iterator>, Iterator
, use_default
, typename detail::minimum_category<
bidirectional_traversal_tag
, typename traversal_category<Iterator>::type
>::type
> super_t;
typedef typename detail::filter_iterator_base<
Predicate, Iterator
>::type super_t;
friend class iterator_core_access;

View File

@ -0,0 +1,150 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
#include <boost/iterator.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
// should be the last #includes
#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
namespace boost {
namespace detail
{
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
// Calling lvalue_preserver( <expression>, 0 ) returns a reference
// to the expression's result if <expression> is an lvalue, or
// not_an_lvalue() otherwise.
struct not_an_lvalue {};
template <class T>
T& lvalue_preserver(T&, int);
template <class U>
not_an_lvalue lvalue_preserver(U const&, ...);
# define BOOST_LVALUE_PRESERVER(expr) lvalue_preserver(expr,0)
#else
# define BOOST_LVALUE_PRESERVER(expr) expr
#endif
// Guts of is_lvalue_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template.
template <class Value>
struct is_lvalue_iterator_impl
{
// Eat implicit conversions so we don't report true for things
// convertible to Value const&
struct conversion_eater
{
conversion_eater(Value&);
};
static char tester(conversion_eater, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>
struct rebind
{
static It& x;
BOOST_STATIC_CONSTANT(
bool
, value = (
sizeof(
is_lvalue_iterator_impl<Value>::tester(
BOOST_LVALUE_PRESERVER(*x), 0
)
) == 1
)
);
};
};
#undef BOOST_LVALUE_PRESERVER
//
// void specializations to handle std input and output iterators
//
template <>
struct is_lvalue_iterator_impl<void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <>
struct is_lvalue_iterator_impl<const void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_lvalue_iterator_impl<volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_lvalue_iterator_impl<const volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#endif
//
// This level of dispatching is required for Borland. We might save
// an instantiation by removing it for others.
//
template <class It>
struct is_readable_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
>::template rebind<It>
{};
template <class It>
struct is_non_const_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
>::template rebind<It>
{};
} // namespace detail
// Define the trait with full mpl lambda capability and various broken
// compiler workarounds
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#include <boost/type_traits/detail/bool_trait_undef.hpp>
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP

View File

@ -0,0 +1,108 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
# define IS_READABLE_ITERATOR_DWA2003112_HPP
#include <boost/mpl/bool.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
// should be the last #include
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
namespace boost {
namespace detail
{
// Guts of is_readable_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template.
template <class Value>
struct is_readable_iterator_impl
{
static char tester(Value&, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>
struct rebind
{
static It& x;
BOOST_STATIC_CONSTANT(
bool
, value = (
sizeof(
is_readable_iterator_impl<Value>::tester(*x, 1)
) == 1
)
);
};
};
#undef BOOST_READABLE_PRESERVER
//
// void specializations to handle std input and output iterators
//
template <>
struct is_readable_iterator_impl<void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <>
struct is_readable_iterator_impl<const void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_readable_iterator_impl<volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_readable_iterator_impl<const volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#endif
//
// This level of dispatching is required for Borland. We might save
// an instantiation by removing it for others.
//
template <class It>
struct is_readable_iterator_impl2
: is_readable_iterator_impl<
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
>::template rebind<It>
{};
} // namespace detail
// Define the trait with full mpl lambda capability and various broken
// compiler workarounds
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2<T>::value)
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP

View File

@ -26,12 +26,32 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/type_traits/remove_reference.hpp>
#else
# include <boost/type_traits/add_reference.hpp>
#endif
#include <boost/iterator/detail/config_def.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost
{
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
struct use_default;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not
// needed for vc6/vc7.
template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
# endif
namespace detail
{
@ -142,63 +162,51 @@ namespace boost
class Derived
, class Base
, class Value
, class Category
, class Traversal
, class Reference
, class Difference
>
struct iterator_adaptor_base
{
private: // intermediate results
typedef typename mpl::apply_if<
mpl::or_<
is_same<Category, use_default>
, mpl::or_<
is_access_tag<Category>
, is_traversal_tag<Category>
>
>
, BOOST_ITERATOR_CATEGORY<Base>
, mpl::identity<Category>
>::type category;
typedef typename detail::ia_dflt_help<
Reference
, mpl::apply_if<
is_same<Value, use_default>
, iterator_reference<Base>
, mpl::identity<Value&>
>
>::type reference;
public: // return type
typedef iterator_facade<
Derived
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename detail::ia_dflt_help<
Value
, mpl::apply_if<
is_same<Reference,use_default>
, iterator_value<Base>
, remove_reference<Reference>
>
>::type
# else
, typename detail::ia_dflt_help<
Value, iterator_value<Base>
>::type
, typename mpl::apply_if<
is_access_tag<Category>
, mpl::identity<Category>
, access_category_tag<category, reference>
>::type
# endif
, typename detail::ia_dflt_help<
Traversal
, iterator_traversal<Base>
>::type
, typename detail::ia_dflt_help<
Reference
, mpl::apply_if<
is_same<Value,use_default>
, iterator_reference<Base>
, add_reference<Value>
>
>::type
, typename mpl::apply_if<
is_traversal_tag<Category>
, mpl::identity<Category>
, traversal_category_tag<category>
>::type
, reference
, typename detail::ia_dflt_help<
Difference, iterator_difference<Base>
>::type
>
type;
};
template <class T> int static_assert_convertible_to(T);
}
//
@ -215,8 +223,8 @@ namespace boost
// const. If const, a conforming compiler strips constness for the
// value_type. If not supplied, iterator_traits<Base>::value_type is used
//
// Category - the iterator_category of the resulting iterator. If not
// supplied, iterator_traits<Base>::iterator_category is used.
// Category - the traversal category of the resulting iterator. If not
// supplied, iterator_traversal<Base>::type is used.
//
// Reference - the reference type of the resulting iterator, and in
// particular, the result type of operator*(). If not supplied but
@ -230,19 +238,19 @@ namespace boost
class Derived
, class Base
, class Value = use_default
, class Category = use_default
, class Traversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
: public detail::iterator_adaptor_base<
Derived, Base, Value, Category, Reference, Difference
Derived, Base, Value, Traversal, Reference, Difference
>::type
{
friend class iterator_core_access;
typedef typename detail::iterator_adaptor_base<
Derived, Base, Value, Category, Reference, Difference
Derived, Base, Value, Traversal, Reference, Difference
>::type super_t;
public:
@ -287,17 +295,18 @@ namespace boost
// );
return m_iterator == x.base();
}
typedef typename iterator_category_to_traversal<
typename super_t::iterator_category
>::type my_traversal;
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
typedef int assertion[sizeof(detail::static_assert_convertible_to<cat>(my_traversal()))];
// BOOST_STATIC_ASSERT((is_convertible<my_traversal,cat>::value));
void advance(typename super_t::difference_type n)
{
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
BOOST_STATIC_ASSERT(
(detail::is_tag<
random_access_traversal_tag
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
>::value)
);
# endif
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
m_iterator += n;
}
@ -305,14 +314,7 @@ namespace boost
void decrement()
{
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
BOOST_STATIC_ASSERT(
(detail::is_tag<
bidirectional_traversal_tag
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
>::value)
);
# endif
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
--m_iterator;
}
@ -322,12 +324,7 @@ namespace boost
typename super_t::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
{
BOOST_STATIC_ASSERT(
(detail::is_tag<
random_access_traversal_tag
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
>::value)
);
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
@ -335,6 +332,8 @@ namespace boost
return y.base() - m_iterator;
}
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
private: // data members
Base m_iterator;
};

View File

@ -8,341 +8,449 @@
#define BOOST_ITERATOR_ARCHETYPES_HPP
#include <boost/iterator/iterator_categories.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#include <boost/mpl/bitand.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/identity.hpp>
#include <cstddef>
namespace boost
namespace boost {
template <class Value, class AccessCategory>
struct access_archetype;
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype;
namespace iterator_archetypes
{
enum {
readable_iterator_bit = 1
, writable_iterator_bit = 2
, swappable_iterator_bit = 4
, lvalue_iterator_bit = 8
};
template <class Value, class AccessCategory>
struct access_archetype;
// Not quite tags, since dispatching wouldn't work.
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
typedef mpl::int_<
(readable_iterator_bit|writable_iterator_bit)
>::type readable_writable_iterator_t;
typedef mpl::int_<
(readable_iterator_bit|lvalue_iterator_bit)
>::type readable_lvalue_iterator_t;
typedef mpl::int_<
(lvalue_iterator_bit|writable_iterator_bit)
>::type writable_lvalue_iterator_t;
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype;
template <class Derived, class Base>
struct has_access
: mpl::equal_to<
mpl::bitand_<Derived,Base>
, Base
>
{};
}
namespace detail {
template <class T>
struct assign_proxy
{
namespace detail
{
template <class T>
struct assign_proxy
{
assign_proxy& operator=(T);
};
};
template <class T>
struct read_write_proxy :
assign_proxy<T>
{
template <class T>
struct read_proxy
{
operator T();
};
};
template <class T>
struct arrow_proxy
{
template <class T>
struct read_write_proxy
: assign_proxy<T>
, read_proxy<T>
{
};
template <class T>
struct arrow_proxy
{
T const* operator->() const;
};
};
struct no_operator_brackets {};
struct no_operator_brackets {};
template <class ValueType>
struct readable_operator_brackets
{
ValueType operator[](std::ptrdiff_t n) const;
};
template <class ValueType>
struct readable_operator_brackets
{
read_proxy<ValueType> operator[](std::ptrdiff_t n) const;
};
template <class ValueType>
struct writable_operator_brackets
{
template <class ValueType>
struct writable_operator_brackets
{
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
};
};
template <class Value, class AccessCategory, class TraversalCategory>
struct operator_brackets :
mpl::if_< is_tag<random_access_traversal_tag, TraversalCategory>,
mpl::if_< is_tag<writable_iterator_tag, AccessCategory>,
writable_operator_brackets< Value >,
mpl::if_< is_tag<readable_iterator_tag, AccessCategory>,
readable_operator_brackets<Value>,
no_operator_brackets > >,
no_operator_brackets >::type
{
};
template <class Value, class AccessCategory, class TraversalCategory>
struct operator_brackets
: mpl::aux::msvc_eti_base<
typename mpl::apply_if<
is_convertible<TraversalCategory, random_access_traversal_tag>
, mpl::apply_if<
iterator_archetypes::has_access<
AccessCategory
, iterator_archetypes::writable_iterator_t
>
, mpl::identity<writable_operator_brackets<Value> >
, mpl::if_<
iterator_archetypes::has_access<
AccessCategory
, iterator_archetypes::readable_iterator_t
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
>
, mpl::identity<no_operator_brackets>
>::type
>::type
{};
template <class TraversalCategory>
struct traversal_archetype_impl
{
template <class Derived,class Value> struct archetype;
};
template <class TraversalCategory>
struct traversal_archetype_impl
{
template <class Derived,class Value> struct archetype;
};
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: mpl::aux::msvc_eti_base<
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
>::type
{};
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: mpl::aux::msvc_eti_base<
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
>::type
{};
template <>
struct traversal_archetype_impl<incrementable_traversal_tag>
{
template<class Derived, class Value>
struct archetype
{
typedef void difference_type;
template <>
struct traversal_archetype_impl<incrementable_traversal_tag>
{
template<class Derived, class Value>
struct archetype
{
typedef void difference_type;
Derived& operator++();
Derived operator++(int) const;
};
};
Derived& operator++();
Derived operator++(int) const;
};
};
template <>
struct traversal_archetype_impl<single_pass_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
{
};
};
template <>
struct traversal_archetype_impl<single_pass_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
{
};
};
template <class Derived, class Value>
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
template <class Derived, class Value>
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// doesn't seem to pick up != from equality_comparable
template <class Derived, class Value>
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
template <class Derived, class Value>
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
#endif
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
typedef std::ptrdiff_t difference_type;
};
};
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
typedef std::ptrdiff_t difference_type;
};
};
template <>
struct traversal_archetype_impl<bidirectional_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
{
Derived& operator--();
Derived operator--(int) const;
};
};
template <>
struct traversal_archetype_impl<bidirectional_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
{
Derived& operator--();
Derived operator--(int) const;
};
};
template <>
struct traversal_archetype_impl<random_access_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t);
Derived& operator-=(std::ptrdiff_t);
};
};
template <>
struct traversal_archetype_impl<random_access_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t);
Derived& operator-=(std::ptrdiff_t);
};
};
template <class Derived, class Value>
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t);
template <class Derived, class Value>
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t);
template <class Derived, class Value>
Derived& operator+(std::ptrdiff_t,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
Derived& operator+(std::ptrdiff_t,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t);
template <class Derived, class Value>
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t);
template <class Derived, class Value>
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
template <class Derived, class Value>
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
struct bogus_type;
struct bogus_type;
template <class Value>
struct convertible_type
: mpl::if_< is_const<Value>,
typename remove_const<Value>::type,
bogus_type >
{};
} // namespace detail
template <class> struct undefined;
template <class AccessCategory>
struct iterator_access_archetype_impl
{
template <class Value> struct archetype;
};
template <class Value, class AccessCategory>
struct iterator_access_archetype
: mpl::aux::msvc_eti_base<
typename iterator_access_archetype_impl<
AccessCategory
>::template archetype<Value>
>::type
{
};
template <>
struct iterator_access_archetype_impl<
iterator_archetypes::readable_iterator_t
>
{
template <class Value>
struct convertible_type
: mpl::if_< is_const<Value>,
typename remove_const<Value>::type,
bogus_type >
{};
struct archetype
{
typedef typename remove_cv<Value>::type value_type;
typedef Value reference;
typedef Value* pointer;
} // namespace detail
value_type operator*() const;
detail::arrow_proxy<Value> operator->() const;
};
};
template <class> struct undefined;
template <class AccessCategory>
struct access_archetype_impl
{
template <class Value> struct archetype;
};
template <class Value, class AccessCategory>
struct access_archetype
: mpl::aux::msvc_eti_base<
typename access_archetype_impl<AccessCategory>::template archetype<Value>
>::type
{
};
template <>
struct access_archetype_impl<readable_iterator_tag>
{
template <class Value>
struct archetype
{
typedef typename remove_cv<Value>::type value_type;
typedef Value reference;
typedef Value* pointer;
value_type operator*() const;
detail::arrow_proxy<Value> operator->() const;
};
};
template <>
struct access_archetype_impl<writable_iterator_tag>
{
template <class Value>
struct archetype
{
template <>
struct iterator_access_archetype_impl<
iterator_archetypes::writable_iterator_t
>
{
template <class Value>
struct archetype
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(!is_const<Value>::value);
BOOST_STATIC_ASSERT(!is_const<Value>::value);
# endif
typedef void value_type;
typedef void reference;
typedef void pointer;
typedef void value_type;
typedef void reference;
typedef void pointer;
detail::assign_proxy<Value> operator*() const;
};
};
detail::assign_proxy<Value> operator*() const;
};
};
template <>
struct access_archetype_impl<readable_writable_iterator_tag>
{
template <class Value>
struct archetype
: public virtual access_archetype<Value, readable_iterator_tag>
{
typedef detail::read_write_proxy<Value> reference;
detail::read_write_proxy<Value> operator*() const;
};
};
template <>
struct access_archetype_impl<readable_lvalue_iterator_tag>
{
template <class Value>
struct archetype
: public virtual access_archetype<Value, readable_iterator_tag>
{
typedef Value& reference;
Value& operator*() const;
Value* operator->() const;
};
};
template <>
struct access_archetype_impl<writable_lvalue_iterator_tag>
{
template <class Value>
struct archetype
: public virtual access_archetype<Value, readable_lvalue_iterator_tag>
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT((!is_const<Value>::value));
# endif
};
};
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype;
template <class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype_base
: detail::operator_brackets<
typename remove_cv<Value>::type
, AccessCategory
, TraversalCategory
>
, detail::traversal_archetype_<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value
, TraversalCategory
template <>
struct iterator_access_archetype_impl<
iterator_archetypes::readable_writable_iterator_t
>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, iterator_archetypes::readable_iterator_t
>
{
};
{
typedef detail::read_write_proxy<Value> reference;
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
, public access_archetype<Value, AccessCategory>
detail::read_write_proxy<Value> operator*() const;
};
};
// These broken libraries require derivation from std::iterator
// (or related magic) in order to handle iter_swap and other
// iterator operations
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
, public std::iterator<
iterator_tag<AccessCategory,TraversalCategory>
, typename access_archetype<Value, AccessCategory>::value_type
, typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type
>
template <>
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, iterator_archetypes::readable_iterator_t
>
{
typedef Value& reference;
Value& operator*() const;
Value* operator->() const;
};
};
template <>
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, iterator_archetypes::readable_lvalue_iterator_t
>
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT((!is_const<Value>::value));
# endif
};
};
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype;
template <class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype_base
: detail::operator_brackets<
typename remove_cv<Value>::type
, AccessCategory
, TraversalCategory
>
, detail::traversal_archetype_<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value
, TraversalCategory
>
{
};
namespace detail
{
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype_base
: iterator_access_archetype<Value, AccessCategory>
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
{
// Derivation from std::iterator above caused ambiguity, so now
// we have to declare all the types here.
typedef iterator_access_archetype<Value, AccessCategory> access;
typedef typename detail::facade_iterator_category<
TraversalCategory
, typename mpl::apply_if<
iterator_archetypes::has_access<
AccessCategory, iterator_archetypes::writable_iterator_t
>
, remove_const<Value>
, add_const<Value>
>::type
, typename access::reference
>::type iterator_category;
// Needed for some broken libraries (see below)
typedef boost::iterator<
iterator_category
, Value
, typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type
, typename access::pointer
, typename access::reference
> workaround_iterator_base;
};
}
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
// These broken libraries require derivation from std::iterator
// (or related magic) in order to handle iter_swap and other
// iterator operations
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
typedef typename access_archetype<Value, AccessCategory>::reference reference;
typedef typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
, public detail::iterator_archetype_base<
Value, AccessCategory, TraversalCategory
>::workaround_iterator_base
# endif
{
// Derivation from std::iterator above caused references to nested
// types to be ambiguous, so now we have to redeclare them all
// here.
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
typedef detail::iterator_archetype_base<
Value,AccessCategory,TraversalCategory
> base;
typedef typename base::value_type value_type;
typedef typename base::reference reference;
typedef typename base::pointer pointer;
typedef typename base::difference_type difference_type;
typedef typename base::iterator_category iterator_category;
# endif
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
iterator_archetype();
iterator_archetype(iterator_archetype const&);
iterator_archetype();
iterator_archetype(iterator_archetype const&);
iterator_archetype& operator=(iterator_archetype const&);
iterator_archetype& operator=(iterator_archetype const&);
// Optional conversion from mutable
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
};
// Optional conversion from mutable
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
};
} // namespace boost

View File

@ -4,425 +4,159 @@
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// TODO:
// Add separate category tag for operator[].
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
#define BOOST_ITERATOR_CATEGORIES_HPP
# define BOOST_ITERATOR_CATEGORIES_HPP
#include <boost/config.hpp>
#include <boost/iterator/detail/categories.hpp>
# include <boost/config.hpp>
# include <boost/detail/iterator.hpp>
# include <boost/iterator/detail/config_def.hpp>
#include <boost/type_traits/conversion_traits.hpp>
#include <boost/type_traits/cv_traits.hpp>
# include <boost/detail/workaround.hpp>
#include <boost/python/detail/indirect_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/has_xxx.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
# include <boost/mpl/apply_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/placeholders.hpp>
#endif
# include <boost/mpl/aux_/lambda_support.hpp>
#include <iterator>
# include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator/detail/config_def.hpp> // must be last #include
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
#endif
# include <boost/static_assert.hpp>
namespace boost {
namespace detail
{
// Helper metafunction for std_category below
template <class Cat, class Tag, class Next>
struct match_tag
: mpl::apply_if<is_tag<Tag, Cat>, mpl::identity<Tag>, Next>
{
};
// Converts a possibly user-defined category tag to the
// most-derived standard tag which is a base of that tag.
template <class Category>
struct std_category
: match_tag<
Category, std::random_access_iterator_tag
, match_tag<Category, std::bidirectional_iterator_tag
, match_tag<Category, std::forward_iterator_tag
, match_tag<Category, std::input_iterator_tag
, match_tag<Category, std::output_iterator_tag
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
, mpl::identity<void>
# else
, void
# endif
>
>
>
>
>
{
};
// std_to_new_tags --
//
// A metafunction which converts any standard tag into its
// corresponding new-style traversal tag.
//
// Also, instantiations are metafunction classes which convert a
// reference type into a corresponding new-style access tag.
template <class Category> struct std_to_new_tags
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) // handle ETI
{
typedef void type;
template <class T> struct apply { typedef void type; };
}
# endif
;
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // handle ETI
template <> struct std_to_new_tags<int> {};
# endif
//
// Specializations for specific standard tags
//
template <>
struct std_to_new_tags<std::input_iterator_tag>
{
typedef single_pass_traversal_tag type;
template <class Reference>
struct apply
: mpl::identity<readable_iterator_tag> {};
};
template <>
struct std_to_new_tags<std::output_iterator_tag>
{
typedef incrementable_traversal_tag type;
template <class Reference>
struct apply
: mpl::identity<writable_iterator_tag> {};
};
template <>
struct std_to_new_tags<std::forward_iterator_tag>
{
typedef forward_traversal_tag type;
template <class Reference>
struct apply
: mpl::if_<
python::detail::is_reference_to_const<Reference>
, boost::readable_lvalue_iterator_tag
, boost::writable_lvalue_iterator_tag
>
{};
};
template <>
struct std_to_new_tags<std::bidirectional_iterator_tag>
: std_to_new_tags<std::forward_iterator_tag>
{
typedef bidirectional_traversal_tag type;
};
template <>
struct std_to_new_tags<std::random_access_iterator_tag>
: std_to_new_tags<std::bidirectional_iterator_tag>
{
typedef random_access_traversal_tag type;
};
template <class Category>
struct old_tag_converter
: std_to_new_tags<
typename std_category<Category>::type
>
{
};
template <typename Category>
struct iter_category_to_traversal
: std_to_new_tags<
typename std_category<Category>::type
>
{};
template <typename Category, typename Reference>
struct iter_category_to_access
: mpl::apply1<
iter_category_to_traversal<Category>
, Reference
>
{};
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// Deal with ETI
template <> struct iter_category_to_access<int, int> {};
template <> struct iter_category_to_traversal<int> {};
# endif
// A metafunction returning true iff T is boost::iterator_tag<R,U>
template <class T>
struct is_boost_iterator_tag;
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
//
// has_xxx fails, so we have to use
// something less sophisticated.
//
// The solution depends on the fact that only
// std iterator categories work with is_xxx_iterator
// meta functions, as BOOST_NO_IS_CONVERTIBLE is
// defined for cwpro7.
//
template <class Tag>
struct is_new_iterator_tag
: mpl::not_<
mpl::or_<
is_tag<std::input_iterator_tag, Tag>
, is_tag<std::output_iterator_tag, Tag>
>
>
{};
#elif BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class Tag>
struct is_new_iterator_tag
: is_boost_iterator_tag<Tag>
{
};
#else
BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal)
template <class Tag>
struct is_new_iterator_tag
: mpl::if_<
is_class<Tag>
, has_traversal<Tag>
, mpl::false_
>::type
{
};
#endif
} // namespace detail
//
// Traversal Categories
//
struct incrementable_traversal_tag {};
namespace detail {
template <class NewCategoryTag>
struct get_traversal_category {
typedef typename NewCategoryTag::traversal type;
};
// Remove all writability from the given access tag. This
// functionality is part of new_category_to_access in order to
// support deduction of the proper default access category for
// iterator_adaptor; when the reference type is a reference to
// constant we must strip writability.
template <class AccessTag>
struct remove_access_writability
: mpl::apply_if<
is_tag<writable_lvalue_iterator_tag, AccessTag>
, mpl::identity<readable_lvalue_iterator_tag>
, mpl::apply_if<
is_tag<readable_writable_iterator_tag, AccessTag>
, mpl::identity<readable_iterator_tag>
, mpl::if_<
is_tag<writable_iterator_tag, AccessTag>
// Is this OK? I think it may correct be for all
// legitimate cases, because at this point the
// iterator is not readable, so it could not have
// been any more than writable + swappable.
, swappable_iterator_tag
, AccessTag
>
>
>
{};
struct single_pass_traversal_tag
: incrementable_traversal_tag {};
template <class NewCategoryTag, class Reference>
struct new_category_to_access
: mpl::apply_if<
python::detail::is_reference_to_const<Reference>
, remove_access_writability<typename NewCategoryTag::access>
, mpl::identity<typename NewCategoryTag::access>
>
{};
struct forward_traversal_tag
: single_pass_traversal_tag {};
struct bidirectional_traversal_tag
: forward_traversal_tag {};
struct random_access_traversal_tag
: bidirectional_traversal_tag {};
template <class CategoryTag, class Reference>
struct access_category_tag
: mpl::apply_if<
is_new_iterator_tag<CategoryTag>
, new_category_to_access<CategoryTag, Reference>
, iter_category_to_access<CategoryTag, Reference>
namespace detail
{
//
// Convert a "strictly old-style" iterator category to a traversal
// tag. This is broken out into a separate metafunction to reduce
// the cost of instantiating iterator_category_to_traversal, below,
// for new-style types.
//
template <class Cat>
struct old_category_to_traversal
: mpl::apply_if<
is_convertible<Cat,std::random_access_iterator_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::apply_if<
is_convertible<Cat,std::bidirectional_iterator_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::apply_if<
is_convertible<Cat,std::forward_iterator_tag>
, mpl::identity<forward_traversal_tag>
, mpl::apply_if<
is_convertible<Cat,std::input_iterator_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::apply_if<
is_convertible<Cat,std::output_iterator_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
{
};
template <class CategoryTag>
struct traversal_category_tag
: mpl::apply_if<
is_new_iterator_tag<CategoryTag>
, get_traversal_category<CategoryTag>
, iter_category_to_traversal<CategoryTag>
>
{
};
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
// Deal with ETI
template <> struct access_category_tag<int, int> { typedef void type; };
template <> struct traversal_category_tag<int> { typedef void type; };
# endif
// iterator_tag_base - a metafunction to compute the appropriate
// old-style tag (if any) to use as a base for a new-style tag.
template <class KnownAccessTag, class KnownTraversalTag>
struct iterator_tag_base
: minimum_category<
typename KnownAccessTag::max_category
, typename KnownTraversalTag::max_category
>
{};
# if BOOST_WORKAROUND(BOOST_MSVC,<=1200)
template <>
struct iterator_tag_base<int,int>
: mpl::false_ {}; // just using false_ so that the result will be
// a legal base class
# endif
// specialization for this special case. Otherwise we get
// input_output_iterator_tag, because the standard hierarchy has a
// sudden anomalous distinction between readability and
// writability at the level of input iterator/output iterator.
template <>
struct iterator_tag_base<
readable_lvalue_iterator_tag,single_pass_traversal_tag>
{
typedef std::input_iterator_tag type;
};
} // namespace detail
template <class Iterator>
struct access_category
: detail::access_category_tag<
typename detail::iterator_traits<Iterator>::iterator_category
, typename detail::iterator_traits<Iterator>::reference>
>
{};
template <class Iterator>
struct traversal_category
: detail::traversal_category_tag<
typename detail::iterator_traits<Iterator>::iterator_category
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct old_category_to_traversal<int>
{
typedef int type;
};
# endif
template <class Traversal>
struct pure_traversal_tag
: mpl::apply_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::apply_if<
is_convertible<Traversal,bidirectional_traversal_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::apply_if<
is_convertible<Traversal,forward_traversal_tag>
, mpl::identity<forward_traversal_tag>
, mpl::apply_if<
is_convertible<Traversal,single_pass_traversal_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::apply_if<
is_convertible<Traversal,incrementable_traversal_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
>
{
};
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
template <>
struct pure_traversal_tag<int>
{
typedef int type;
};
# endif
} // namespace detail
//
// Convert an iterator category into a traversal tag
//
template <class Cat>
struct iterator_category_to_traversal
: mpl::apply_if< // if already convertible to a traversal tag, we're done.
is_convertible<Cat,incrementable_traversal_tag>
, mpl::identity<Cat>
, detail::old_category_to_traversal<Cat>
>
{};
// Trait to get an iterator's traversal category
template <class Iterator = mpl::_1>
struct iterator_traversal
: iterator_category_to_traversal<
typename boost::detail::iterator_traits<Iterator>::iterator_category
>
{};
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
template <>
struct access_category<mpl::_1>
{
template <class T>
struct apply : access_category<T>
{};
};
template <>
struct traversal_category<mpl::_1>
{
template <class T>
struct apply : traversal_category<T>
{};
};
# endif
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct access_category<T*>
: mpl::if_<
is_const<T>
, readable_lvalue_iterator_tag
, writable_lvalue_iterator_tag>
{
};
template <typename T>
struct traversal_category<T*>
{
typedef random_access_traversal_tag type;
};
# endif
template <class AccessTag, class TraversalTag>
struct iterator_tag
: detail::iterator_tag_base<
typename detail::max_known_access_tag<AccessTag>::type
, typename detail::max_known_traversal_tag<TraversalTag>::type
>::type
{
typedef AccessTag access;
typedef TraversalTag traversal;
};
namespace detail
{
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
struct iterator_traversal<mpl::_1>
{
template <class T>
struct is_boost_iterator_tag
: mpl::false_ {};
template <class R, class T>
struct is_boost_iterator_tag<iterator_tag<R,T> >
: mpl::true_ {};
# else
template <class T>
struct is_boost_iterator_tag
{
typedef char (&yes)[1];
typedef char (&no)[2];
template <class R, class U>
static yes test(mpl::identity<iterator_tag<R,U> >*);
static no test(...);
static mpl::identity<T>* inst;
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes));
typedef mpl::bool_<value> type;
};
struct apply : iterator_traversal<T>
{};
};
template <>
struct iterator_traversal<mpl::_>
: iterator_traversal<mpl::_1>
{};
# endif
}
} // namespace boost

View File

@ -15,16 +15,20 @@
#include <boost/concept_check.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/static_assert.hpp>
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/static_assert.hpp>
// Use boost/limits to work around missing limits headers on some compilers
#include <boost/limits.hpp>
@ -56,7 +60,6 @@ namespace boost_concepts {
public:
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::reference reference;
typedef BOOST_DEDUCED_TYPENAME ::boost::access_category<Iterator>::type access_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
@ -64,8 +67,6 @@ namespace boost_concepts {
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_iterator_tag, access_category>::value));
reference r = *i; // or perhaps read(x)
value_type v(r);
boost::ignore_unused_variable_warning(v);
@ -73,19 +74,19 @@ namespace boost_concepts {
Iterator i;
};
template <typename Iterator, typename ValueType>
template <
typename Iterator
, typename ValueType = typename boost::detail::iterator_traits<Iterator>::value_type
>
class WritableIteratorConcept {
public:
typedef typename boost::access_category<Iterator>::type access_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::detail::is_tag<boost::writable_iterator_tag, access_category>::value));
*i = v; // a good alternative could be something like write(x, v)
}
ValueType v;
@ -95,11 +96,8 @@ namespace boost_concepts {
template <typename Iterator>
class SwappableIteratorConcept {
public:
typedef typename boost::access_category<Iterator>::type access_category;
void constraints() {
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::swappable_iterator_tag, access_category>::value));
std::iter_swap(i1, i2);
}
Iterator i1;
@ -107,25 +105,25 @@ namespace boost_concepts {
};
template <typename Iterator>
class ReadableLvalueIteratorConcept {
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
typedef typename boost::access_category<Iterator>::type access_category;
class ReadableLvalueIteratorConcept
{
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
void constraints() {
boost::function_requires< ReadableIteratorConcept<Iterator> >();
void constraints()
{
boost::function_requires< ReadableIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_lvalue_iterator_tag, access_category>::value));
typedef boost::mpl::or_<
boost::is_same<reference, value_type&>,
boost::is_same<reference, value_type const&> > correct_reference;
typedef boost::mpl::or_<
boost::is_same<reference, value_type&>
, boost::is_same<reference, value_type const&>
> correct_reference;
BOOST_STATIC_ASSERT(correct_reference::value);
BOOST_STATIC_ASSERT(correct_reference::value);
reference v = *i;
boost::ignore_unused_variable_warning(v);
reference v = *i;
boost::ignore_unused_variable_warning(v);
}
Iterator i;
};
@ -135,7 +133,6 @@ namespace boost_concepts {
public:
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
typedef typename boost::access_category<Iterator>::type access_category;
void constraints() {
boost::function_requires<
@ -145,7 +142,6 @@ namespace boost_concepts {
boost::function_requires<
SwappableIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_lvalue_iterator_tag, access_category>::value));
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
}
@ -157,14 +153,19 @@ namespace boost_concepts {
template <typename Iterator>
class IncrementableIteratorConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
void constraints() {
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
boost::function_requires<
boost::DefaultConstructibleConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::incrementable_traversal_tag, traversal_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_convertible<
traversal_category
, boost::incrementable_traversal_tag
>::value
));
++i;
(void)i++;
@ -175,21 +176,26 @@ namespace boost_concepts {
template <typename Iterator>
class SinglePassIteratorConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
void constraints() {
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::single_pass_traversal_tag, traversal_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_convertible<
traversal_category
, boost::single_pass_traversal_tag
>::value
));
}
};
template <typename Iterator>
class ForwardTraversalConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
void constraints() {
@ -201,19 +207,29 @@ namespace boost_concepts {
> difference_type_is_signed_integral;
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::forward_traversal_tag, traversal_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_convertible<
traversal_category
, boost::forward_traversal_tag
>::value
));
}
};
template <typename Iterator>
class BidirectionalTraversalConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
void constraints() {
boost::function_requires< ForwardTraversalConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::bidirectional_traversal_tag, traversal_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_convertible<
traversal_category
, boost::bidirectional_traversal_tag
>::value
));
--i;
(void)i--;
@ -224,14 +240,19 @@ namespace boost_concepts {
template <typename Iterator>
class RandomAccessTraversalConcept {
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
difference_type;
void constraints() {
boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::random_access_traversal_tag, traversal_category>::value));
BOOST_STATIC_ASSERT(
(boost::is_convertible<
traversal_category
, boost::random_access_traversal_tag
>::value
));
i += n;
i = i + n;
@ -326,11 +347,11 @@ namespace detail
class InteroperableConcept
{
public:
typedef typename boost::traversal_category<Iterator>::type traversal_category;
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
difference_type;
typedef typename boost::traversal_category<ConstIterator>::type
typedef typename boost::iterator_traversal<ConstIterator>::type
const_traversal_category;
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
const_difference_type;

View File

@ -12,15 +12,17 @@
#include <boost/static_assert.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/interoperable.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/or.hpp>
@ -30,22 +32,8 @@ namespace boost
{
// This forward declaration is required for the friend declaration
// in iterator_core_access
template <class I, class V, class AC, class TC, class R, class D> class iterator_facade;
template <class I, class V, class TC, class R, class D> class iterator_facade;
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
struct use_default;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not
// needed for vc6/vc7.
template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
# endif
namespace detail
{
//
@ -75,59 +63,30 @@ namespace boost
#endif
};
//
// Add const qualification for iterators which are not writable
//
template<class Value, class AccessCategory>
struct const_qualified_ref :
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
Value&,
Value const& >
{};
// The apparent duplication here works around a Borland problem
template<class Value, class AccessCategory>
struct const_qualified_ptr :
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
Value*,
Value const* >
{};
//
// Generates the associated types for an iterator_facade with the
// given parameters. Additionally generates a 'base' type for
// compiler/library combinations which require user-defined
// iterators to inherit from std::iterator.
// Generates associated types for an iterator_facade with the
// given parameters.
//
template <
class Value
, class AccessCategory
, class TraversalCategory
, class Reference
class ValueParam
, class CategoryOrTraversal
, class Reference
, class Difference
>
struct iterator_facade_types
{
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
typedef typename facade_iterator_category<
CategoryOrTraversal, ValueParam, Reference
>::type iterator_category;
typedef typename remove_cv<Value>::type value_type;
typedef typename remove_const<ValueParam>::type value_type;
typedef Difference difference_type;
typedef typename const_qualified_ptr<Value, AccessCategory>::type pointer;
// The use_default support is needed for iterator_adaptor.
// For practical reasons iterator_adaptor needs to specify
// a fixed number of template arguments of iterator_facade.
// So use_default is its way to say: "What I really mean
// is your default parameter".
typedef typename mpl::if_<
is_same<Reference, use_default>
, typename const_qualified_ref<Value, AccessCategory>::type
, Reference
>::type reference;
typedef typename mpl::apply_if<
detail::iterator_writability_disabled<ValueParam,Reference>
, add_pointer<typename add_const<value_type>::type>
, add_pointer<value_type>
>::type pointer;
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
@ -141,7 +100,7 @@ namespace boost
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
typedef
iterator<iterator_category, value_type, difference_type, pointer, reference>
iterator<iterator_category, value_type, Difference, pointer, Reference>
base;
# endif
};
@ -205,10 +164,10 @@ namespace boost
public:
operator_brackets_proxy(Iterator const& iter)
: m_iter(iter)
: m_iter(iter)
{}
operator reference()
operator reference() const
{
return *m_iter;
}
@ -223,28 +182,24 @@ namespace boost
Iterator m_iter;
};
template <class Iterator, class ValueType, class Category, class Reference>
template <class Iterator, class Value, class Reference>
struct operator_brackets_result
{
typedef typename access_category_tag<Category,Reference>::type access_category;
typedef is_tag<writable_iterator_tag, access_category> use_proxy;
typedef typename mpl::if_<
use_proxy
typedef typename mpl::if_<
iterator_writability_disabled<Value,Reference>
, Value
, operator_brackets_proxy<Iterator>
, ValueType
>::type type;
};
template <class Iterator>
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::false_)
{
return operator_brackets_proxy<Iterator>(iter);
}
template <class Iterator>
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::true_)
{
return *iter;
}
@ -253,20 +208,20 @@ namespace boost
// Macros which describe the declarations of binary operators
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class AC1, class TC1, class R1, class D1 \
, class Derived2, class V2, class AC2, class TC2, class R2, class D2 \
> \
prefix typename detail::enable_if_interoperable< \
Derived1, Derived2, result_type \
>::type \
operator op( \
iterator_facade<Derived1, V1, AC1, TC1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, AC2, TC2, R2, D2> const& rhs)
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class R1, class D1 \
, class Derived2, class V2, class TC2, class R2, class D2 \
> \
prefix typename detail::enable_if_interoperable< \
Derived1, Derived2, result_type \
>::type \
operator op( \
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class AC, class TC, class R, class D> \
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \
prefix Derived operator+ args
//
@ -287,7 +242,7 @@ namespace boost
public:
# else
template <class I, class V, class AC, class TC, class R, class D> friend class iterator_facade;
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
# define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
@ -307,7 +262,7 @@ namespace boost
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend
, (iterator_facade<Derived, V, AC, TC, R, D> const&
, (iterator_facade<Derived, V, TC, R, D> const&
, typename Derived::difference_type)
)
;
@ -315,7 +270,7 @@ namespace boost
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend
, (typename Derived::difference_type
, iterator_facade<Derived, V, AC, TC, R, D> const&)
, iterator_facade<Derived, V, TC, R, D> const&)
)
;
@ -370,26 +325,21 @@ namespace boost
template <
class Derived // The derived iterator type being constructed
, class Value
, class AccessCategory
, class TraversalCategory
, class Reference = BOOST_DEDUCED_TYPENAME detail::const_qualified_ref<Value, AccessCategory>::type
, class CategoryOrTraversal
, class Reference = Value&
, class Difference = std::ptrdiff_t
>
class iterator_facade
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public detail::iterator_facade_types<
Value, AccessCategory, TraversalCategory, Reference, Difference
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
{
private:
typedef typename
detail::iterator_facade_types<Value, AccessCategory, TraversalCategory, Reference, Difference>
types;
//
// Curiously Recursive Template interface.
// Curiously Recurring Template interface.
//
typedef Derived derived_t;
@ -403,13 +353,17 @@ namespace boost
return static_cast<Derived const&>(*this);
}
typedef detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
public:
typedef typename types::value_type value_type;
typedef typename types::reference reference;
typedef typename types::difference_type difference_type;
typedef typename types::pointer pointer;
typedef typename types::iterator_category iterator_category;
typedef typename associated_types::value_type value_type;
typedef Reference reference;
typedef Difference difference_type;
typedef typename associated_types::pointer pointer;
typedef typename associated_types::iterator_category iterator_category;
reference operator*() const
{
@ -430,14 +384,16 @@ namespace boost
>::make(*this->derived());
}
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
typename detail::operator_brackets_result<Derived,Value,Reference>::type
operator[](difference_type n) const
{
typedef typename
detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::use_proxy
use_proxy;
typedef detail::iterator_writability_disabled<Value,Reference>
not_writable;
return detail::make_operator_brackets_result<Derived>(this->derived() + n, use_proxy());
return detail::make_operator_brackets_result<Derived>(
this->derived() + n
, not_writable()
);
}
Derived& operator++()
@ -615,13 +571,13 @@ namespace boost
}
BOOST_ITERATOR_FACADE_PLUS((
iterator_facade<Derived, V, AC, TC, R, D> const& i
iterator_facade<Derived, V, TC, R, D> const& i
, typename Derived::difference_type n
))
BOOST_ITERATOR_FACADE_PLUS((
typename Derived::difference_type n
, iterator_facade<Derived, V, AC, TC, R, D> const& i
, iterator_facade<Derived, V, TC, R, D> const& i
))
# undef BOOST_ITERATOR_FACADE_PLUS
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD

View File

@ -24,15 +24,13 @@
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/detail/iterator.hpp>
# include <boost/pending/iterator_tests.hpp>
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
# include <boost/iterator/detail/config_def.hpp>
namespace boost {
void is_readable(readable_iterator_tag) { }
void is_writable(writable_iterator_tag) { }
void is_swappable(swappable_iterator_tag) { }
void is_constant_lvalue(readable_lvalue_iterator_tag) { }
void is_mutable_lvalue(writable_lvalue_iterator_tag) { }
// Preconditions: *i == v
template <class Iterator, class T>
void readable_iterator_test(const Iterator i1, T v)
@ -45,8 +43,12 @@ void readable_iterator_test(const Iterator i1, T v)
T v2 = r2;
assert(v1 == v);
assert(v2 == v);
typedef typename access_category<Iterator>::type result_category;
is_readable(result_category());
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
// I think we don't really need this as it checks the same things as
// the above code.
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>
@ -54,7 +56,6 @@ void writable_iterator_test(Iterator i, T v)
{
Iterator i2(i); // Copy Constructible
*i2 = v;
is_writable(typename access_category<Iterator>::type());
}
template <class Iterator>
@ -65,8 +66,6 @@ void swappable_iterator_test(Iterator i, Iterator j)
iter_swap(i2, j2);
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
assert(bi == aj && bj == ai);
typedef typename access_category<Iterator>::type result_category;
is_swappable(result_category());
}
template <class Iterator, class T>
@ -78,12 +77,14 @@ void constant_lvalue_iterator_test(Iterator i, T v1)
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
const T& v2 = *i2;
assert(v1 == v2);
typedef typename access_category<Iterator>::type result_category;
is_constant_lvalue(result_category());
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>
void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
{
Iterator i2(i);
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
@ -91,11 +92,17 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
T& v3 = *i2;
assert(v1 == v3);
// A non-const lvalue iterator is not neccessarily writable, but we
// are assuming the value_type is assignable here
*i = v2;
T& v4 = *i2;
assert(v2 == v4);
typedef typename access_category<Iterator>::type result_category;
is_mutable_lvalue(result_category());
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
# endif
}
template <class Iterator, class T>
@ -159,7 +166,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
readable_iterator_test(i2, v2);
}
// random access
// Preconditions: [i,i+N) is a valid range
template <class Iterator, class TrueVals>
@ -169,10 +175,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
const Iterator j = i;
int c;
for (c = 0; c < N-1; ++c) {
for (c = 0; c < N-1; ++c)
{
assert(i == j + c);
assert(*i == vals[c]);
assert(*i == j[c]);
typename detail::iterator_traits<Iterator>::value_type x = j[c];
assert(*i == x);
assert(*i == *(j + c));
assert(*i == *(c + j));
++i;
@ -183,10 +191,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
}
Iterator k = j + N - 1;
for (c = 0; c < N-1; ++c) {
for (c = 0; c < N-1; ++c)
{
assert(i == k - c);
assert(*i == vals[N - 1 - c]);
assert(*i == j[N - 1 - c]);
typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
assert(*i == x);
Iterator q = k - c;
assert(*i == *q);
assert(i > j);
@ -197,8 +207,8 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
}
}
// #if 0'd code snipped; see CVS v 1.4 if you need it back
} // namespace boost
# include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_NEW_ITERATOR_TESTS_HPP

View File

@ -24,6 +24,8 @@
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/iterator/detail/config_def.hpp>
namespace boost
{
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
@ -46,53 +48,38 @@ namespace boost
};
#endif
// Given the transform iterator's transformation and iterator, this
// is the type used as its traits.
// Compute the iterator_adaptor instantiation to be used for transform_iterator
template <class UnaryFunction, class Iterator, class Reference, class Value>
struct transform_iterator_base
{
private:
private:
// By default, dereferencing the iterator yields the same as
// the function. Do we need to adjust the way
// function_object_result is computed for the standard
// proposal (e.g. using Doug's result_of)?
typedef typename ia_dflt_help<
Reference
, function_object_result<UnaryFunction>
>::type reference;
// transform_iterator does not support writable/swappable iterators
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
#endif
typedef typename mpl::apply_if<
is_same< Reference, use_default >
, function_object_result<UnaryFunction>
, mpl::identity<Reference>
>::type result_type;
// To get the default for Value: remove any reference on the
// result type, but retain any constness to signal
// non-writability. Note that if we adopt Thomas' suggestion
// to key non-writability *only* on the Reference argument,
// we'd need to strip constness here as well.
typedef typename ia_dflt_help<
Value
, remove_reference<reference>
>::type cv_value_type;
typedef typename mpl::if_<
is_same< Value, use_default >
, typename remove_reference< result_type >::type
, Value
>::type cv_value_type;
typedef typename mpl::if_<
is_reference< result_type >
, typename mpl::if_<
is_const< cv_value_type >
, readable_lvalue_iterator_tag
, writable_lvalue_iterator_tag
>::type
, readable_iterator_tag
>::type maximum_access_tag;
typedef typename minimum_category<
maximum_access_tag
, typename access_category<Iterator>::type
>::type access_category;
public:
typedef iterator_adaptor<
transform_iterator<UnaryFunction, Iterator, Reference, Value>
, Iterator
, cv_value_type
, access_category
, result_type
> type;
public:
typedef iterator_adaptor<
transform_iterator<UnaryFunction, Iterator, Reference, Value>
, Iterator
, cv_value_type
, use_default // Leave the traversal category alone
, reference
> type;
};
}
@ -150,12 +137,16 @@ namespace boost
return transform_iterator<UnaryFunction, Iterator>(it, fun);
}
// Version which allows explicit specification of the UnaryFunction
// type.
//
// This generator is not provided if UnaryFunction is a function
// pointer type, because it's too dangerous: the default-constructed
// function pointer in the iterator be 0, leading to a runtime
// crash.
template <class UnaryFunction, class Iterator>
// don't provide this generator if UnaryFunction is a
// function pointer type. Too dangerous. We should probably
// find a cheaper test than is_class<>
typename iterators::enable_if<
is_class<UnaryFunction>
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
, transform_iterator<UnaryFunction, Iterator>
>::type
make_transform_iterator(Iterator it)
@ -174,4 +165,6 @@ namespace boost
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP

View File

@ -26,7 +26,9 @@
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
#include <boost/iterator/iterator_categories.hpp>
#include <boost/detail/iterator_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/iterator/detail/minimum_category.hpp>
#include <boost/tuple/tuple.hpp>
@ -259,16 +261,17 @@ namespace boost {
)
{
typedef typename tuple_meta_transform<
typename Tuple::tail_type
BOOST_DEDUCED_TYPENAME Tuple::tail_type
, Fun
>::type transformed_tail_type;
return tuples::cons<
typename mpl::apply1<Fun, typename Tuple::head_type>::type
BOOST_DEDUCED_TYPENAME mpl::apply1<
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
>::type
, transformed_tail_type
>(
f(boost::tuples::get<0>(t)),
tuple_transform(t.get_tail(), f)
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
);
}
@ -380,12 +383,12 @@ namespace boost {
{
typedef typename tuple_impl_specific::tuple_meta_transform<
IteratorTuple
, traversal_category<mpl::_1>
, iterator_traversal<>
>::type tuple_of_traversal_tags;
typedef typename tuple_impl_specific::tuple_meta_accumulate<
tuple_of_traversal_tags
, minimum_category<mpl::_1,mpl::_2>
, minimum_category<>
, random_access_traversal_tag
>::type type;
};
@ -398,31 +401,6 @@ namespace boost {
};
#endif
template<typename Iterator>
struct iterator_is_readable
: is_tag<
readable_iterator_tag
, typename access_category<Iterator>::type
>
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(1, iterator_is_readable, (Iterator))
};
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
template <>
struct iterator_is_readable<mpl::_1>
{
template <class T>
struct apply : iterator_is_readable<T>
{};
};
# endif
// We need to call tuple_meta_accumulate with mpl::and_ as the
// accumulating functor. To this end, we need to wrap it into
// a struct that has exactly two arguments (that is, template
@ -446,28 +424,6 @@ namespace boost {
};
# endif
// Metafunction to assert that all iterators in a tuple are
// readable.
//
// Probably not worth it, IMO. Why not a writable zip_iterator
// anyway? -- dwa.
//
template<typename IteratorTuple>
struct all_iterators_in_tuple_readable
{
typedef typename tuple_impl_specific::tuple_meta_transform<
IteratorTuple,
iterator_is_readable<mpl::_1>
>::type tuple_of_readability_bools;
typedef typename tuple_impl_specific::tuple_meta_accumulate<
tuple_of_readability_bools,
and_with_two_args<mpl::_1,mpl::_2>
, mpl::bool_<true>
>::type type;
};
///////////////////////////////////////////////////////////////////
//
// Class zip_iterator_base
@ -479,14 +435,6 @@ namespace boost {
struct zip_iterator_base
{
private:
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// seems to give vc7's parser fits, and vc6 needs help here too
BOOST_STATIC_ASSERT(
detail::all_iterators_in_tuple_readable<
IteratorTuple
>::type::value
);
#endif
// Reference type is the type of the tuple obtained from the
// iterators' reference types.
typedef typename
@ -506,11 +454,6 @@ namespace boost {
detail::minimum_traversal_category_in_iterator_tuple<
IteratorTuple
>::type traversal_category;
// Access category is readable_iterator_tag. It has been
// asserted that all iterators in the tuple are readable.
typedef readable_iterator_tag access_category;
public:
// The iterator facade type from which the zip iterator will
@ -518,7 +461,6 @@ namespace boost {
typedef iterator_facade<
zip_iterator<IteratorTuple>,
value_type,
access_category,
traversal_category,
reference,
difference_type
@ -616,7 +558,7 @@ namespace boost {
{
detail::tuple_impl_specific::tuple_for_each(
m_iterator_tuple,
detail::advance_iterator<typename super_t::difference_type>(n)
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
);
}
// Incrementing a zip iterator means to increment all iterators in

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

@ -18,7 +18,12 @@ test-suite iterator
# compilation problems.
[ run is_convertible_fail.cpp ]
[ run zip_iterator_test.cpp ]
# These tests should work for just about everything.
[ compile is_lvalue_iterator.cpp ]
[ compile is_readable_iterator.cpp ]
[ run unit_tests.cpp ]
[ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ]
@ -31,7 +36,6 @@ test-suite iterator
[ 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 ]

44
test/Jamfile.v2 Normal file
View File

@ -0,0 +1,44 @@
# 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.
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 ]
;

View File

@ -5,15 +5,16 @@
// to its suitability for any purpose.
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp> // remove
#include <boost/detail/workaround.hpp>
#include "static_assert_same.hpp" // remove
struct new_random_access
: std::random_access_iterator_tag
, boost::random_access_traversal_tag
{};
struct new_iterator
: public boost::iterator< boost::iterator_tag<
boost::writable_lvalue_iterator_tag
, boost::random_access_traversal_tag>, int>
: public boost::iterator< new_random_access, int >
{
int& operator*() const { return *m_x; }
new_iterator& operator++() { return *this; }
@ -52,103 +53,13 @@ struct old_iterator
};
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
struct my_writable_lvalue_iterator_tag
{
operator boost::writable_lvalue_iterator_tag() const;
};
struct my_single_pass_traversal_tag
{
operator boost::single_pass_traversal_tag() const;
};
void test_tag_convertibility()
{
// This set of tests is by no means complete.
// Test that this is an input/output iterator
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
{
typedef boost::iterator_tag<
boost::writable_lvalue_iterator_tag
, boost::single_pass_traversal_tag
> tag;
BOOST_STATIC_ASSERT((
boost::is_convertible<tag, std::output_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
boost::is_convertible<tag, std::input_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
!boost::is_convertible<tag, std::forward_iterator_tag>::value
));
}
// Test that it's possible to build new sub-tags without
// derivation. Convertibility should be enough
{
typedef boost::iterator_tag<
my_writable_lvalue_iterator_tag
, my_single_pass_traversal_tag
> tag;
BOOST_STATIC_ASSERT((
boost::is_convertible<tag, std::output_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
boost::is_convertible<tag, std::input_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
!boost::is_convertible<tag, std::forward_iterator_tag>::value
));
}
// Test that a single-pass readable lvalue iterator is only an
// input iterator. Requires special case handling in
// categories.hpp
{
typedef boost::iterator_tag<
boost::readable_lvalue_iterator_tag
, boost::single_pass_traversal_tag
> tag;
BOOST_STATIC_ASSERT((
boost::is_convertible<tag, std::input_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
!boost::is_convertible<tag, std::output_iterator_tag>::value
));
BOOST_STATIC_ASSERT((
!boost::is_convertible<tag, std::forward_iterator_tag>::value
));
}
#endif
}
int
main()
{
test_tag_convertibility();
typedef boost::iterator_tag< boost::writable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag;
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<tag>::value));
int test = static_assert_same<tag::access, boost::writable_lvalue_iterator_tag>::value;
test = static_assert_same<tag::traversal, boost::random_access_traversal_tag>::value;
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<new_iterator::iterator_category>::value));
test = static_assert_same<new_iterator::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
test = static_assert_same<new_iterator::iterator_category::traversal, boost::random_access_traversal_tag>::value;
typedef boost::traversal_category<new_iterator>::type traversal_category;
// BOOST_STATIC_ASSERT(boost::detail::has_traversal<new_iterator::iterator_category>::value);
BOOST_STATIC_ASSERT(boost::detail::is_new_iterator_tag<new_iterator::iterator_category>::value);
test = static_assert_same<traversal_category, boost::random_access_traversal_tag>::value;
(void)test;
boost::iterator_traversal<new_iterator>::type tc;
boost::random_access_traversal_tag derived = tc;
(void)derived;
boost::function_requires<
boost_concepts::WritableLvalueIteratorConcept<int*> >();
boost::function_requires<

View File

@ -286,7 +286,7 @@ int main()
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# endif
// Also prove that we can handle raw pointers.
int array[2000];
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));

View File

@ -7,13 +7,12 @@
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <deque>
#include <iostream>
using boost::dummyT;
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
struct one_or_four
{
@ -38,12 +37,12 @@ int main()
filter_iter(one_or_four(), array, array+N)
, dummyT(1), dummyT(4));
BOOST_STATIC_ASSERT((
!boost::detail::is_tag<
boost::random_access_traversal_tag
, boost::traversal_category<filter_iter>::type
>::value
));
BOOST_STATIC_ASSERT(
(!boost::is_convertible<
boost::iterator_traversal<filter_iter>::type
, boost::random_access_traversal_tag
>::value
));
//# endif

View File

@ -46,8 +46,7 @@
struct my_iterator_tag : public std::random_access_iterator_tag { };
using boost::dummyT;
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<boost::dummyT>)
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<dummyT>)
typedef std::vector<int> storage;
typedef std::vector<int*> pointer_ra_container;

145
test/is_lvalue_iterator.cpp Executable file
View File

@ -0,0 +1,145 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
BOOST_TT_BROKEN_COMPILER_SPEC(v)
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
template <class T>
struct proxy_iterator
: boost::iterator<std::output_iterator_tag,T>
{
typedef T value_type;
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,value_type> base;
typedef base::iterator_category iterator_category;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator value_type&() const;
proxy& operator=(value_type) const;
};
proxy operator*() const;
};
template <class T>
struct lvalue_iterator
{
typedef T value_type;
typedef T& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T* pointer;
T& operator*() const;
lvalue_iterator& operator++();
lvalue_iterator operator++(int);
};
template <class T>
struct constant_lvalue_iterator
{
typedef T value_type;
typedef T const& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T const* pointer;
T const& operator*() const;
constant_lvalue_iterator& operator++();
constant_lvalue_iterator operator++(int);
};
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<v>::proxy)
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<int>::proxy)
int main()
{
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
#endif
// Make sure inaccessible copy constructor doesn't prevent
// reference binding
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
#endif
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
#endif
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
return 0;
}

93
test/is_readable_iterator.cpp Executable file
View File

@ -0,0 +1,93 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
BOOST_TT_BROKEN_COMPILER_SPEC(v)
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator v&();
proxy& operator=(v) const;
};
proxy operator*() const;
};
struct proxy_iterator2 : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
proxy& operator=(v) const;
};
proxy operator*() const;
};
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy)
int main()
{
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<proxy_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<proxy_iterator2>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<value_iterator>::value);
// Make sure inaccessible copy constructor doesn't prevent
// readability
BOOST_STATIC_ASSERT(boost::is_readable_iterator<noncopyable_iterator>::value);
return 0;
}

View File

@ -14,6 +14,10 @@
#include <numeric>
#include <boost/iterator/iterator_adaptor.hpp>
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
#endif
#include <boost/pending/iterator_tests.hpp>
# include <boost/type_traits/broken_compiler_spec.hpp>
@ -26,7 +30,7 @@
#include "static_assert_same.hpp"
struct my_iterator_tag : public std::random_access_iterator_tag { };
#include <boost/iterator/detail/config_def.hpp>
using boost::dummyT;
@ -83,7 +87,7 @@ struct ptr_iterator
ptr_iterator<V>
, V*
, V
, std::random_access_iterator_tag
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
, V&
#endif
@ -94,7 +98,7 @@ private:
ptr_iterator<V>
, V*
, V
, std::random_access_iterator_tag
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
, V&
#endif
@ -114,13 +118,13 @@ public:
};
// Non-functional iterator for category modification checking
template <class Iter, class Category>
struct modify_category
template <class Iter, class Traversal>
struct modify_traversal
: boost::iterator_adaptor<
modify_category<Iter, Category>
modify_traversal<Iter, Traversal>
, Iter
, boost::use_default
, Category
, Traversal
>
{};
@ -179,6 +183,33 @@ struct constant_iterator
: base_t(it) {}
};
char (& traversal2(boost::incrementable_traversal_tag) )[1];
char (& traversal2(boost::single_pass_traversal_tag ) )[2];
char (& traversal2(boost::forward_traversal_tag ) )[3];
char (& traversal2(boost::bidirectional_traversal_tag) )[4];
char (& traversal2(boost::random_access_traversal_tag) )[5];
template <class Cat>
struct traversal3
{
static typename boost::iterator_category_to_traversal<Cat>::type x;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
typedef char (&type)[value];
};
template <class Cat>
typename traversal3<Cat>::type traversal(Cat);
template <class Iter, class Trav>
int static_assert_traversal(Iter* = 0, Trav* = 0)
{
typedef typename boost::iterator_category_to_traversal<
BOOST_DEDUCED_TYPENAME Iter::iterator_category
>::type t2;
return static_assert_same<Trav,t2>::value;
}
int
main()
{
@ -219,7 +250,17 @@ main()
typedef ptr_iterator<int const> Iter1;
test = static_assert_same<Iter1::value_type, int>::value;
test = static_assert_same<Iter1::reference, const int&>::value;
test = static_assert_same<Iter1::iterator_category::access, boost::readable_lvalue_iterator_tag>::value; test = static_assert_same<Iter1::pointer, const int*>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
# endif
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter1::pointer, int const*>::value;
#endif
}
{
@ -229,19 +270,19 @@ main()
test = static_assert_same<Iter::value_type, int>::value;
test = static_assert_same<Iter::reference, int const&>::value;
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter::pointer, int const*>::value;
#endif
test = static_assert_same<BaseIter::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
test = static_assert_same<Iter::iterator_category::access, boost::readable_lvalue_iterator_tag>::value;
// Test category modification
typedef modify_category<BaseIter, boost::readable_iterator_tag> ReadableIter;
test = static_assert_same<ReadableIter::iterator_category::access, boost::readable_iterator_tag>::value;
typedef modify_category<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
test = static_assert_same<BaseIter::iterator_category::traversal, boost::random_access_traversal_tag>::value;
test = static_assert_same<IncrementableIter::iterator_category::traversal, boost::incrementable_traversal_tag>::value;
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
}
// Test the iterator_adaptor

View File

@ -12,14 +12,15 @@
int main()
{
{
typedef boost::iterator_archetype<int,
boost::writable_lvalue_iterator_tag,
boost::random_access_traversal_tag> iter;
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
}
return 0; // keep msvc happy
return 0; // keep msvc happy
}

View File

@ -11,8 +11,6 @@
using boost::dummyT;
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
// Test reverse iterator
int main()
{

View File

@ -10,13 +10,17 @@
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U>
struct static_assert_same;
struct static_assert_same_base;
template <class T>
struct static_assert_same<T,T>
struct static_assert_same_base<T,T>
{
enum { value = 1 };
};
template <class T, class U>
struct static_assert_same : static_assert_same_base<T,U> {};
#else
# include <boost/mpl/if.hpp>
# include <boost/mpl/bool.hpp>

View File

@ -184,17 +184,14 @@ main()
for (int k2 = 0; k2 < N; ++k2)
x[k2] = x[k2] * 2;
boost::input_iterator_test(boost::make_transform_iterator(y, mult_2)
, x[0]
, x[1]);
boost::input_iterator_test(
boost::make_transform_iterator(y, mult_2), x[0], x[1]);
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_2)
, x[0]
, x[1]);
boost::input_iterator_test(
boost::make_transform_iterator(&y[0], mult_2), x[0], x[1]);
boost::random_access_readable_iterator_test(boost::make_transform_iterator(y, mult_2)
, N
, x);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator(y, mult_2), N, x);
}
@ -213,25 +210,34 @@ main()
}
std::copy(x,
x + N,
boost::make_transform_iterator((pair_t*)values, select_first()));
std::copy(
x
, x + N
, boost::make_transform_iterator((pair_t*)values, select_first())
);
std::copy(y,
y + N,
boost::make_transform_iterator((pair_t*)values, select_second()));
std::copy(
y
, y + N
, boost::make_transform_iterator((pair_t*)values, select_second())
);
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, value_select_first()),
N,
x);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator((pair_t*)values, value_select_first())
, N
, x
);
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()),
N,
x);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator((pair_t*)values, const_select_first())
, N, x
);
boost::constant_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
boost::constant_lvalue_iterator_test(
boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
boost::mutable_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
boost::non_const_lvalue_iterator_test(
boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
}

View File

@ -5,9 +5,12 @@
// to its suitability for any purpose.
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/static_assert.hpp>
#include "static_assert_same.hpp"
#include <boost/type_traits/broken_compiler_spec.hpp>
#include <boost/iterator/detail/minimum_category.hpp>
struct X { int a; };
@ -40,29 +43,32 @@ void category_test()
using namespace boost::detail;
BOOST_STATIC_ASSERT((
!is_tag<
input_output_iterator_tag
, std::input_iterator_tag>::value));
BOOST_STATIC_ASSERT((
!is_tag<
input_output_iterator_tag
, std::output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
is_tag<
!boost::is_convertible<
std::input_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
is_tag<
!boost::is_convertible<
std::output_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
is_tag<
boost::is_convertible<
input_output_iterator_tag
, std::forward_iterator_tag>::value));
, std::input_iterator_tag>::value));
BOOST_STATIC_ASSERT((
boost::is_convertible<
input_output_iterator_tag
, std::output_iterator_tag>::value));
#if 0 // This seems wrong; we're not advertising
// input_output_iterator_tag are we?
BOOST_STATIC_ASSERT((
boost::is_convertible<
std::forward_iterator_tag
, input_output_iterator_tag>::value));
#endif
int test = static_assert_min_cat<
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
@ -72,9 +78,11 @@ void category_test()
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
>::value;
#if 0
test = static_assert_min_cat<
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
>::value;
#endif
test = static_assert_min_cat<
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
@ -84,29 +92,13 @@ void category_test()
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
>::value;
#if 0 // This would be wrong: a random access iterator is not
// neccessarily writable, as is an output iterator.
test = static_assert_min_cat<
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
>::value;
#endif
BOOST_STATIC_ASSERT((is_traversal_tag< incrementable_traversal_tag >::value));
BOOST_STATIC_ASSERT((is_traversal_tag< single_pass_traversal_tag >::value));
BOOST_STATIC_ASSERT((is_traversal_tag< forward_traversal_tag >::value));
BOOST_STATIC_ASSERT((is_traversal_tag< bidirectional_traversal_tag >::value));
BOOST_STATIC_ASSERT((is_traversal_tag< random_access_traversal_tag >::value));
BOOST_STATIC_ASSERT((!is_traversal_tag< std::input_iterator_tag >::value));
BOOST_STATIC_ASSERT((!is_traversal_tag< readable_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< readable_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< writable_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< swappable_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< readable_writable_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< readable_lvalue_iterator_tag >::value));
BOOST_STATIC_ASSERT((is_access_tag< writable_lvalue_iterator_tag >::value));
BOOST_STATIC_ASSERT((!is_access_tag< std::input_iterator_tag >::value));
BOOST_STATIC_ASSERT((!is_access_tag< incrementable_traversal_tag >::value));
(void)test;
}

Some files were not shown because too many files have changed in this diff Show More