Compare commits

..

1 Commits

Author SHA1 Message Date
671474e521 This commit was manufactured by cvs2svn to create tag
'Version_1_20_1'.

[SVN r8548]
2001-01-10 18:29:12 +00:00
23 changed files with 793 additions and 4526 deletions

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,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>

View File

@ -1,215 +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.
//
// See http://www.boost.org for most recent version including documentation.
//
// Supplies:
//
// template <class Incrementable> class counting_iterator_traits;
// template <class Incrementable> class counting_iterator_policies;
//
// Iterator traits and policies for adapted iterators whose dereferenced
// value progresses through consecutive values of Incrementable when the
// iterator is derferenced.
//
// template <class Incrementable> struct counting_iterator_generator;
//
// A "type generator" whose nested type "type" is a counting iterator as
// described above.
//
// template <class Incrementable>
// typename counting_iterator_generator<Incrementable>::type
// make_counting_iterator(Incrementable);
//
// A function which produces an adapted counting iterator over values of
// Incrementable.
//
// Revision History
// 14 Feb 2001 Removed unnecessary typedefs from counting_iterator_traits
// (Jeremy Siek)
// 11 Feb 2001 Use BOOST_STATIC_CONSTANT (Dave Abrahams)
// 11 Feb 2001 Clean up after John Maddocks's (finally effective!) Borland
// fixes (David Abrahams).
// 10 Feb 2001 Use new iterator_adaptor<> interface (David Abrahams)
// 10 Feb 2001 Rolled in supposed Borland fixes from John Maddock, but not
// seeing any improvement yet (David Abrahams)
// 09 Feb 2001 Factored out is_numeric computation. Borland still
// unhappy :( (David Abrahams)
// 08 Feb 2001 Beginning of a failed attempt to appease Borland
// (David Abrahams)
// 07 Feb 2001 rename counting_iterator() -> make_counting_iterator()
// (David Abrahams)
// 04 Feb 2001 Added counting_iterator_generator; updated comments
// (David Abrahams)
// 24 Jan 2001 initial revision, based on Jeremy Siek's
// boost/pending/integer_range.hpp (David Abrahams)
#ifndef BOOST_COUNTING_ITERATOR_HPP_DWA20000119
# define BOOST_COUNTING_ITERATOR_HPP_DWA20000119
# include <boost/config.hpp>
# include <boost/detail/iterator.hpp>
# include <boost/iterator_adaptors.hpp>
# include <boost/type_traits.hpp>
# include <boost/detail/numeric_traits.hpp>
# include <boost/static_assert.hpp>
# ifndef BOOST_NO_LIMITS
# include <limits>
# endif
namespace boost {
namespace detail {
// Template class counting_iterator_traits_select -- choose an
// iterator_category and difference_type for a counting_iterator at
// compile-time based on whether or not it wraps an integer or an iterator,
// using "poor man's partial specialization".
template <bool is_integer> struct counting_iterator_traits_select;
// Incrementable is an iterator type
template <>
struct counting_iterator_traits_select<false>
{
template <class Incrementable>
struct traits
{
private:
typedef boost::detail::iterator_traits<Incrementable> x;
public:
typedef typename x::iterator_category iterator_category;
typedef typename x::difference_type difference_type;
};
};
// Incrementable is a numeric type
template <>
struct counting_iterator_traits_select<true>
{
template <class Incrementable>
struct traits
{
typedef typename
boost::detail::numeric_traits<Incrementable>::difference_type
difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
};
// Template class distance_policy_select -- choose a policy for computing the
// distance between counting_iterators at compile-time based on whether or not
// the iterator wraps an integer or an iterator, using "poor man's partial
// specialization".
template <bool is_integer> struct distance_policy_select;
// A policy for wrapped iterators
template <>
struct distance_policy_select<false>
{
template <class Distance, class Incrementable>
struct policy {
static Distance distance(Incrementable x, Incrementable y)
{ return boost::detail::distance(x, y); }
};
};
// A policy for wrapped numbers
template <>
struct distance_policy_select<true>
{
template <class Distance, class Incrementable>
struct policy {
static Distance distance(Incrementable x, Incrementable y)
{ return numeric_distance(x, y); }
};
};
// Try to detect numeric types at compile time in ways compatible with the
// limitations of the compiler and library.
template <class T>
struct is_numeric {
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# else
# if !defined(__BORLANDC__)
BOOST_STATIC_CONSTANT(bool, value = (
boost::is_convertible<int,T>::value && boost::is_convertible<T,int>::value));
# else
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
# endif
# endif
};
// Compute the distance over arbitrary numeric and/or iterator types
template <class Distance, class Incrementable>
Distance any_distance(Incrementable start, Incrementable finish, Distance* = 0)
{
return distance_policy_select<(
is_numeric<Incrementable>::value)>::template
policy<Distance, Incrementable>::distance(start, finish);
}
} // namespace detail
template <class Incrementable>
struct counting_iterator_traits {
private:
typedef ::boost::detail::counting_iterator_traits_select<(
::boost::detail::is_numeric<Incrementable>::value
)> binder;
typedef typename binder::template traits<Incrementable> traits;
public:
typedef typename traits::difference_type difference_type;
typedef typename traits::iterator_category iterator_category;
};
template <class Incrementable>
struct counting_iterator_policies : public default_iterator_policies
{
const Incrementable& dereference(type<const Incrementable&>, const Incrementable& i) const
{ return i; }
template <class Difference, class Iterator1, class Iterator2>
Difference distance(type<Difference>, const Iterator1& x,
const Iterator2& y) const
{
return boost::detail::any_distance<Difference>(x, y);//,(Difference*)());
}
};
// A type generator for counting iterators
template <class Incrementable>
struct counting_iterator_generator
{
typedef counting_iterator_traits<Incrementable> traits;
typedef iterator_adaptor<Incrementable,
counting_iterator_policies<Incrementable>,
Incrementable,
const Incrementable&,
const Incrementable*,
typename traits::iterator_category,
typename traits::difference_type
> type;
};
// Manufacture a counting iterator for an arbitrary incrementable type
template <class Incrementable>
inline typename counting_iterator_generator<Incrementable>::type
make_counting_iterator(Incrementable x)
{
typedef typename counting_iterator_generator<Incrementable>::type result_t;
return result_t(x);
}
} // namespace boost
#endif // BOOST_COUNTING_ITERATOR_HPP_DWA20000119

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 counting_iterator_traits<Incrementable>::value_type value_type;
typedef typename counting_iterator_traits<Incrementable>::difference_type difference_type;
typedef typename counting_iterator_traits<Incrementable>::reference reference;
typedef typename counting_iterator_traits<Incrementable>::reference const_reference;
typedef typename counting_iterator_traits<Incrementable>::pointer pointer;
typedef typename counting_iterator_traits<Incrementable>::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 counting_iterator_traits<Incrementable>::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,4 +1,4 @@
// interator.hpp workarounds for non-conforming standard libraries ---------//
// integer.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
@ -8,7 +8,6 @@
// See http://www.boost.org for most recent version including 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)
@ -16,7 +15,6 @@
#define BOOST_ITERATOR_HPP
#include <iterator>
#include <cstddef> // std::ptrdiff_t
#include <boost/config.hpp>
namespace boost

File diff suppressed because it is too large Load Diff

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

@ -29,7 +29,7 @@ public:
typedef IntT value_type;
typedef IntT& reference;
typedef IntT* pointer;
typedef std::ptrdiff_t difference_type;
typedef ptrdiff_t difference_type;
inline int_iterator() : _i(0) { }
inline int_iterator(IntT i) : _i(i) { }

View File

@ -1,27 +1,63 @@
// (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.
// (C) Copyright David Abrahams 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.
//
// Revision History:
// 04 Jan 2001 Factored counting_iterator stuff into
// boost/counting_iterator.hpp (David Abrahams)
// (C) Copyright Jeremy Siek 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.
#ifndef BOOST_INTEGER_RANGE_HPP_
#define BOOST_INTEGER_RANGE_HPP_
#include <boost/config.hpp>
#include <boost/counting_iterator.hpp>
#if 1
// Still evaluating whether VC++ can handle this.
#define BOOST_USE_ITERATOR_ADAPTORS
#endif
#ifdef BOOST_USE_ITERATOR_ADAPTORS
#include <boost/pending/iterator_adaptors.hpp>
#else
#include <boost/pending/detail/int_iterator.hpp>
#endif
namespace boost {
//=============================================================================
// Counting Iterator and Integer Range Class
#ifdef BOOST_USE_ITERATOR_ADAPTORS
template <class IntegerType>
struct counting_iterator_policies : public default_iterator_policies
{
IntegerType
dereference(type<IntegerType>, const IntegerType& i) const
{ return i; }
};
template <class IntegerType>
struct counting_iterator_traits {
typedef IntegerType value_type;
typedef IntegerType reference;
typedef value_type* pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
#endif
template <class IntegerType>
struct integer_range {
typedef typename counting_iterator_generator<IntegerType>::type iterator;
#ifdef BOOST_USE_ITERATOR_ADAPTORS
typedef iterator_adaptor<IntegerType,
counting_iterator_policies<IntegerType>,
counting_iterator_traits<IntegerType> > iterator;
#else
typedef int_iterator<IntegerType> iterator;
#endif
typedef iterator const_iterator;
typedef IntegerType value_type;
@ -56,4 +92,8 @@ make_integer_range(IntegerType first, IntegerType last)
} // namespace boost
#ifdef BOOST_USE_ITERATOR_ADAPTORS
#undef BOOST_USE_ITERATOR_ADAPTORS
#endif
#endif // BOOST_INTEGER_RANGE_HPP_

View File

@ -1 +1,735 @@
#include <boost/iterator_adaptors.hpp>
// (C) Copyright David Abrahams 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.
//
// (C) Copyright Jeremy Siek 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.
#ifndef BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_
#define BOOST_ITERATOR_ADAPTOR_DWA053000_HPP_
#include <boost/iterator.hpp>
#include <boost/utility.hpp>
#include <boost/compressed_pair.hpp>
#include <boost/concept_check.hpp>
// I was having some problems with VC6. I couldn't tell whether our hack for
// stock GCC was causing problems so I needed an easy way to turn it on and
// off. Now we can test the hack with various compilers and still have an
// "out" if it doesn't work. -dwa 7/31/00
#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 && !defined(__STL_USE_NAMESPACES)
# define BOOST_RELOPS_AMBIGUITY_BUG 1
#endif
namespace boost {
// Just a "type envelope"; works around some MSVC deficiencies.
template <class T>
struct type {};
//============================================================================
// Concept checking classes that express the requirements for iterator
// policies and adapted types. These classes are mostly for
// documentation purposes, and are not used in this header file. They
// merely provide a more succinct statement of what is expected of the
// iterator policies.
template <class Policies, class Adapted, class Traits>
struct TrivialIteratorPoliciesConcept
{
typedef typename Traits::reference Reference;
void constraints() {
function_requires< AssignableConcept<Policies> >();
function_requires< DefaultConstructibleConcept<Policies> >();
function_requires< AssignableConcept<Adapted> >();
function_requires< DefaultConstructibleConcept<Adapted> >();
const_constraints();
}
void const_constraints() const {
Reference r = p.dereference(type<Reference>(), x);
b = p.equal(x, x);
}
Policies p;
Adapted x;
mutable bool b;
};
template <class Policies, class Adapted, class Traits>
struct ForwardIteratorPoliciesConcept
{
void constraints() {
function_requires<
TrivialIteratorPoliciesConcept<Policies, Adapted, Traits>
>();
p.increment(x);
}
Policies p;
Adapted x;
};
template <class Policies, class Adapted, class Traits>
struct BidirectionalIteratorPoliciesConcept
{
void constraints() {
function_requires<
ForwardIteratorPoliciesConcept<Policies, Adapted, Traits>
>();
p.decrement(x);
}
Policies p;
Adapted x;
};
template <class Policies, class Adapted, class Traits>
struct RandomAccessIteratorPoliciesConcept
{
typedef typename Traits::difference_type DifferenceType;
void constraints() {
function_requires<
BidirectionalIteratorPoliciesConcept<Policies, Adapted, Traits>
>();
p.advance(x, n);
const_constraints();
}
void const_constraints() const {
n = p.distance(type<DifferenceType>(), x, x);
b = p.less(x, x);
}
Policies p;
Adapted x;
mutable DifferenceType n;
mutable bool b;
};
//============================================================================
// Default policies for iterator adaptors. You can use this as a base
// class if you want to customize particular policies.
struct default_iterator_policies
{
// Some of these members were defined static, but Borland got confused
// and thought they were non-const. Also, Sun C++ does not like static
// function templates.
template <class Reference, class Iterator>
Reference dereference(type<Reference>, const Iterator& x) const
{ return *x; }
template <class Iterator>
void increment(Iterator& x)
{ ++x; }
template <class Iterator>
void decrement(Iterator& x)
{ --x; }
template <class Iterator, class DifferenceType>
void advance(Iterator& x, DifferenceType n)
{ x += n; }
template <class Difference, class Iterator1, class Iterator2>
Difference distance(type<Difference>, const Iterator1& x,
const Iterator2& y) const
{ return y - x; }
template <class Iterator1, class Iterator2>
bool equal(const Iterator1& x, const Iterator2& y) const
{ return x == y; }
template <class Iterator1, class Iterator2>
bool less(const Iterator1& x, const Iterator2& y) const
{ return x < y; }
};
// putting the comparisons in a base class avoids the g++
// ambiguous overload bug due to the relops operators
#ifdef BOOST_RELOPS_AMBIGUITY_BUG
template <class Derived, class Base>
struct iterator_comparisons : Base { };
template <class D1, class D2, class Base1, class Base2>
inline bool operator==(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return x.policies().equal(x.iter(), y.iter());
}
template <class D1, class D2, class Base1, class Base2>
inline bool operator!=(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return !x.policies().equal(x.iter(), y.iter());
}
template <class D1, class D2, class Base1, class Base2>
inline bool operator<(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return x.policies().less(x.iter(), y.iter());
}
template <class D1, class D2, class Base1, class Base2>
inline bool operator>(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return x.policies().less(y.iter(), x.iter());
}
template <class D1, class D2, class Base1, class Base2>
inline bool operator>=(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return !x.policies().less(x.iter(), y.iter());
}
template <class D1, class D2, class Base1, class Base2>
inline bool operator<=(const iterator_comparisons<D1,Base1>& xb,
const iterator_comparisons<D2,Base2>& yb)
{
const D1& x = static_cast<const D1&>(xb);
const D2& y = static_cast<const D2&>(yb);
return !x.policies().less(y.iter(), x.iter());
}
#endif
//============================================================================
// iterator_adaptor - A generalized adaptor around an existing
// iterator, which is itself an iterator
//
// Iterator - the iterator type being wrapped.
//
// Policies - a set of policies determining how the resulting iterator
// works.
//
// Traits - a class satisfying the same requirements as a specialization of
// std::iterator_traits for the resulting iterator.
//
template <class Iterator, class Policies,
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
class Traits
#else
class Traits = std::iterator_traits<Iterator>
#endif
>
struct iterator_adaptor :
#ifdef BOOST_RELOPS_AMBIGUITY_BUG
iterator_comparisons<
iterator_adaptor<Iterator,Policies,Traits>,
#endif
boost::iterator<typename Traits::iterator_category,
typename Traits::value_type, typename Traits::difference_type,
typename Traits::pointer, typename Traits::reference>
#ifdef BOOST_RELOPS_AMBIGUITY_BUG
>
#endif
{
typedef iterator_adaptor<Iterator, Policies, Traits> Self;
public:
typedef typename Traits::difference_type difference_type;
typedef typename Traits::value_type value_type;
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef typename Traits::iterator_category iterator_category;
typedef Iterator iterator_type;
iterator_adaptor() { }
iterator_adaptor(const Iterator& iter, const Policies& p = Policies())
: m_iter_p(iter, p) {}
template <class OtherIter, class OtherTraits>
iterator_adaptor (const iterator_adaptor<OtherIter, Policies,
OtherTraits>& src)
: m_iter_p(src.iter(), src.policies()) {
}
reference operator*() const {
return policies().dereference(type<reference>(), iter());
}
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning( disable : 4284 )
#endif
pointer operator->() const
{ return &*this; }
#ifdef _MSC_VER
# pragma warning(pop)
#endif
reference operator[](difference_type n) const
{ return *(*this + n); }
Self& operator++() {
#ifdef __MWERKS__
// Odd bug, MWERKS couldn't deduce the type for the member template
// Workaround by explicitly specifying the type.
policies().increment<Iterator>(iter());
#else
policies().increment(iter());
#endif
return *this;
}
Self operator++(int) { Self tmp(*this); ++*this; return tmp; }
Self& operator--() {
#ifdef __MWERKS__
policies().decrement<Iterator>(iter());
#else
policies().decrement(iter());
#endif
return *this;
}
Self operator--(int) { Self tmp(*this); --*this; return tmp; }
Self& operator+=(difference_type n) {
#ifdef __MWERKS__
policies().advance<Iterator>(iter(), n);
#else
policies().advance(iter(), n);
#endif
return *this;
}
Self& operator-=(difference_type n) {
#ifdef __MWERKS__
policies().advance<Iterator>(iter(), -n);
#else
policies().advance(iter(), -n);
#endif
return *this;
}
iterator_type base() const { return m_iter_p.first(); }
private:
typedef Policies policies_type;
compressed_pair<Iterator,Policies> m_iter_p;
public: // too many compilers have trouble when these are private.
Policies& policies() { return m_iter_p.second(); }
const Policies& policies() const { return m_iter_p.second(); }
Iterator& iter() { return m_iter_p.first(); }
const Iterator& iter() const { return m_iter_p.first(); }
};
template <class Iterator, class Policies, class Traits>
iterator_adaptor<Iterator,Policies,Traits>
operator-(iterator_adaptor<Iterator,Policies,Traits> p, const typename Traits::difference_type x)
{
return p -= x;
}
template <class Iterator, class Policies, class Traits>
iterator_adaptor<Iterator,Policies,Traits>
operator+(iterator_adaptor<Iterator,Policies,Traits> p, typename Traits::difference_type x)
{
return p += x;
}
template <class Iterator, class Policies, class Traits>
iterator_adaptor<Iterator,Policies,Traits>
operator+(typename Traits::difference_type x, iterator_adaptor<Iterator,Policies,Traits> p)
{
return p += x;
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
typename Traits1::difference_type operator-(
const iterator_adaptor<Iterator1,Policies,Traits1>& x,
const iterator_adaptor<Iterator2,Policies,Traits2>& y )
{
typedef typename Traits1::difference_type difference_type;
return x.policies().distance(type<difference_type>(), y.iter(), x.iter());
}
#ifndef BOOST_RELOPS_AMBIGUITY_BUG
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator==(const iterator_adaptor<Iterator1,Policies,Traits1>& x, const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return x.policies().equal(x.iter(), y.iter());
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator<(const iterator_adaptor<Iterator1,Policies,Traits1>& x, const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return x.policies().less(x.iter(), y.iter());
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator>(const iterator_adaptor<Iterator1,Policies,Traits1>& x,
const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return x.policies().less(y.iter(), x.iter());
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator>=(const iterator_adaptor<Iterator1,Policies,Traits1>& x, const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return !x.policies().less(x.iter(), y.iter());
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator<=(const iterator_adaptor<Iterator1,Policies,Traits1>& x,
const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return !x.policies().less(y.iter(), x.iter());
}
template <class Iterator1, class Iterator2, class Policies, class Traits1, class Traits2>
inline bool
operator!=(const iterator_adaptor<Iterator1,Policies,Traits1>& x,
const iterator_adaptor<Iterator2,Policies,Traits2>& y) {
return !x.policies().equal(x.iter(), y.iter());
}
#endif
//=============================================================================
// iterator_adaptors - A type generator that simplifies creating
// mutable/const pairs of iterator adaptors.
template <class Iterator, class ConstIterator,
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
class Traits,
class ConstTraits,
#else
class Traits = std::iterator_traits<Iterator>,
class ConstTraits = std::iterator_traits<ConstIterator>,
#endif
class Policies = default_iterator_policies>
class iterator_adaptors
{
public:
typedef iterator_adaptor<Iterator, Policies, Traits> iterator;
typedef iterator_adaptor<ConstIterator, Policies, ConstTraits>
const_iterator;
};
//=============================================================================
// Transform Iterator Adaptor
//
// Upon deference, apply some unary function object and return the
// result by value.
template <class AdaptableUnaryFunction>
struct transform_iterator_policies : public default_iterator_policies
{
transform_iterator_policies() { }
transform_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { }
template <class Reference, class Iterator>
Reference dereference(type<Reference>, const Iterator& iter) const
{ return m_f(*iter); }
AdaptableUnaryFunction m_f;
};
template <class AdaptableUnaryFunction, class IteratorTraits>
struct transform_iterator_traits {
typedef typename AdaptableUnaryFunction::result_type value_type;
typedef value_type reference;
typedef value_type* pointer;
typedef typename IteratorTraits::difference_type difference_type;
typedef typename IteratorTraits::iterator_category iterator_category;
};
template <class AdaptableUnaryFunction,
class Iterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>
#else
class Traits
#endif
>
struct transform_iterator
{
typedef transform_iterator_traits<AdaptableUnaryFunction,Traits>
TransTraits;
typedef iterator_adaptor<Iterator,
transform_iterator_policies<AdaptableUnaryFunction>, TransTraits>
type;
};
//=============================================================================
// Indirect Iterators Adaptor
// Given a pointer to pointers (or iterator to iterators),
// apply a double dereference inside operator*().
//
// We use the term "outer" to refer to the first level iterator type
// and "inner" to refer to the second level iterator type. For
// example, given T**, T* is the inner iterator type and T** is the
// outer iterator type. Also, const T* would be the const inner
// iterator.
// We tried to implement this with transform_iterator, but that required
// using boost::remove_ref, which is not compiler portable.
struct indirect_iterator_policies : public default_iterator_policies
{
template <class Reference, class Iterator>
Reference dereference(type<Reference>, const Iterator& x) const
{ return **x; }
};
template <class OuterIterator, class InnerIterator,
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
class OuterTraits,
class InnerTraits
#else
class OuterTraits = std::iterator_traits<OuterIterator>,
class InnerTraits = std::iterator_traits<InnerIterator>
#endif
>
struct indirect_traits
{
typedef typename OuterTraits::difference_type difference_type;
typedef typename InnerTraits::value_type value_type;
typedef typename InnerTraits::pointer pointer;
typedef typename InnerTraits::reference reference;
typedef typename OuterTraits::iterator_category iterator_category;
};
template <class OuterIterator, // Mutable or Immutable, does not matter
class InnerIterator, // Mutable -> mutable indirect iterator
// Immutable -> immutable indirect iterator
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
class OuterTraits,
class InnerTraits
#else
class OuterTraits = std::iterator_traits<OuterIterator>,
class InnerTraits = std::iterator_traits<InnerIterator>
#endif
>
struct indirect_iterator
{
typedef iterator_adaptor<OuterIterator,
indirect_iterator_policies,
indirect_traits<OuterIterator, InnerIterator,
OuterTraits, InnerTraits>
> type;
};
template <class OuterIterator, // Mutable or Immutable, does not matter
class InnerIterator, // Mutable
class ConstInnerIterator, // Immutable
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
class OuterTraits,
class InnerTraits,
class ConstInnerTraits
#else
class OuterTraits = std::iterator_traits<OuterIterator>,
class InnerTraits = std::iterator_traits<InnerIterator>,
class ConstInnerTraits = std::iterator_traits<ConstInnerIterator>
#endif
>
struct indirect_iterators
{
typedef iterator_adaptors<OuterIterator, OuterIterator,
indirect_traits<OuterIterator, InnerIterator,
OuterTraits, InnerTraits>,
indirect_traits<OuterIterator, ConstInnerIterator,
OuterTraits, ConstInnerTraits>,
indirect_iterator_policies
> Adaptors;
typedef typename Adaptors::iterator iterator;
typedef typename Adaptors::const_iterator const_iterator;
};
//=============================================================================
// Reverse Iterators Adaptor
struct reverse_iterator_policies
{
template <class Reference, class Iterator>
Reference dereference(type<Reference>, const Iterator& x) const
{ return *boost::prior(x); }
template <class Iterator>
void increment(Iterator& x) const
{ --x; }
template <class Iterator>
void decrement(Iterator& x) const
{ ++x; }
template <class Iterator, class DifferenceType>
void advance(Iterator& x, DifferenceType n) const
{ x -= n; }
template <class Difference, class Iterator1, class Iterator2>
Difference distance(type<Difference>, const Iterator1& x,
const Iterator2& y) const
{ return x - y; }
template <class Iterator1, class Iterator2>
bool equal(const Iterator1& x, const Iterator2& y) const
{ return x == y; }
template <class Iterator1, class Iterator2>
bool less(const Iterator1& x, const Iterator2& y) const
{ return y < x; }
};
template <class Iterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>
#else
class Traits
#endif
>
struct reverse_iterator
{
typedef iterator_adaptor<Iterator, reverse_iterator_policies,
Traits> type;
};
template <class ConstIterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class ConstTraits = std::iterator_traits<ConstIterator>
#else
class ConstTraits
#endif
>
struct const_reverse_iterator
{
typedef iterator_adaptor<ConstIterator, reverse_iterator_policies,
ConstTraits> type;
};
template <class Iterator, class ConstIterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>,
class ConstTraits = std::iterator_traits<ConstIterator>
#else
class Traits,
class ConstTraits
#endif
>
struct reverse_iterators
{
typedef iterator_adaptors<Iterator,ConstIterator,Traits,ConstTraits,
reverse_iterator_policies> Adaptor;
typedef typename Adaptor::iterator iterator;
typedef typename Adaptor::const_iterator const_iterator;
};
//=============================================================================
// Projection Iterators Adaptor
template <class AdaptableUnaryFunction>
struct projection_iterator_policies : public default_iterator_policies
{
projection_iterator_policies() { }
projection_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { }
template <class Reference, class Iterator>
Reference dereference (type<Reference>, Iterator const& iter) const {
return m_f(*iter);
}
AdaptableUnaryFunction m_f;
};
template <class AdaptableUnaryFunction, class Traits>
struct projection_iterator_traits {
typedef typename AdaptableUnaryFunction::result_type value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef typename Traits::difference_type difference_type;
typedef typename Traits::iterator_category iterator_category;
};
template <class AdaptableUnaryFunction, class Traits>
struct const_projection_iterator_traits {
typedef typename AdaptableUnaryFunction::result_type value_type;
typedef value_type const& reference;
typedef value_type const* pointer;
typedef typename Traits::difference_type difference_type;
typedef typename Traits::iterator_category iterator_category;
};
template <class AdaptableUnaryFunction, class Iterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>
#else
class Traits
#endif
>
struct projection_iterator {
typedef projection_iterator_traits<AdaptableUnaryFunction, Traits>
Projection_Traits;
typedef iterator_adaptor<Iterator,
projection_iterator_policies<AdaptableUnaryFunction>,
Projection_Traits> type;
};
template <class AdaptableUnaryFunction, class Iterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>
#else
class Traits
#endif
>
struct const_projection_iterator {
typedef const_projection_iterator_traits<AdaptableUnaryFunction,
Traits> Projection_Traits;
typedef iterator_adaptor<Iterator,
projection_iterator_policies<AdaptableUnaryFunction>,
Projection_Traits> type;
};
template <class AdaptableUnaryFunction, class Iterator, class ConstIterator,
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
class Traits = std::iterator_traits<Iterator>,
class ConstTraits = std::iterator_traits<ConstIterator>
#else
class Traits,
class ConstTraits
#endif
>
struct projection_iterators {
typedef projection_iterator_traits<AdaptableUnaryFunction, Traits>
Projection_Traits;
typedef const_projection_iterator_traits<AdaptableUnaryFunction,
ConstTraits> Const_Projection_Traits;
typedef iterator_adaptors<Iterator, ConstIterator,
Projection_Traits, Const_Projection_Traits,
projection_iterator_policies<AdaptableUnaryFunction> > Adaptors;
typedef typename Adaptors::iterator iterator;
typedef typename Adaptors::const_iterator const_iterator;
};
} // namespace boost
#endif

View File

@ -1,28 +1,17 @@
#ifndef BOOST_ITERATOR_TESTS_HPP
# define 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:
// 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
#include <iterator>
#include <assert.h>
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; }
@ -94,47 +83,17 @@ void input_iterator_test(Iterator i, T v1, T v2)
// 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);
// 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);
input_iterator_test(i, v1, v2);
++i;
Iterator i1 = i, i2 = i;
@ -148,8 +107,8 @@ void bidirectional_iterator_test(Iterator i, T v1, T v2)
--i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
--i1;
--i2;
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);

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>