Compare commits

..

1 Commits

Author SHA1 Message Date
3c14eb8d61 This commit was manufactured by cvs2svn to create tag
'Version_1_21_2'.

[SVN r9983]
2001-04-25 14:10:57 +00:00
12 changed files with 1450 additions and 661 deletions

View File

@ -0,0 +1,199 @@
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
#define BOOST_ITERATOR_CONCEPTS_HPP
#include <boost/concept_check.hpp>
#include <boost/iterator_traits.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 boost::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::iterator_traits<Iterator>::reference reference;
typedef typename boost::iterator_traits<Iterator>::return_category
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::iterator_traits<Iterator>::return_category
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; // an alternative could be something like write(x, v)
}
ValueType v;
Iterator i;
};
template <typename Iterator>
class ConstantLvalueIteratorConcept {
public:
typedef typename boost::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::iterator_traits<Iterator>::reference reference;
typedef typename boost::iterator_traits<Iterator>::return_category
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 boost::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::iterator_traits<Iterator>::reference reference;
typedef typename boost::iterator_traits<Iterator>::return_category
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 SinglePassIteratorConcept {
public:
typedef typename boost::iterator_traits<Iterator>::traversal_category
traversal_category;
typedef typename boost::iterator_traits<Iterator>::difference_type
difference_type;
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::single_pass_iterator_tag*>::value));
// difference_type must be a signed integral type
++i;
(void)i++;
}
Iterator i;
};
template <typename Iterator>
class ForwardIteratorConcept {
public:
typedef typename boost::iterator_traits<Iterator>::traversal_category
traversal_category;
void constraints() {
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
boost::forward_iterator_tag*>::value));
}
};
template <typename Iterator>
class BidirectionalIteratorConcept {
public:
typedef typename boost::iterator_traits<Iterator>::traversal_category
traversal_category;
void constraints() {
boost::function_requires< ForwardIteratorConcept<Iterator> >();
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
boost::bidirectional_iterator_tag*>::value));
--i;
(void)i--;
}
Iterator i;
};
template <typename Iterator>
class RandomAccessIteratorConcept {
public:
typedef typename boost::iterator_traits<Iterator>::traversal_category
traversal_category;
typedef typename boost::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_iterator_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

@ -0,0 +1,137 @@
#ifndef BOOST_ITERATOR_TRAITS_HPP
#define BOOST_ITERATOR_TRAITS_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 {
// Traversal Categories
struct single_pass_iterator_tag { };
struct forward_iterator_tag : public single_pass_iterator_tag { };
struct bidirectional_iterator_tag : public forward_iterator_tag { };
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
// Return Type Categories
struct readable_iterator_tag { };
struct writable_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 { };
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 iter_traits_from_nested_types {
template <typename Iterator> struct bind {
typedef typename Iterator::value_type value_type;
typedef typename Iterator::reference reference;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::return_category return_category;
typedef typename Iterator::traversal_category traversal_category;
};
};
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,
boost::random_access_iterator_tag,
typename ct_if<
is_convertible<Category*, std::bidirectional_iterator_tag*>::value,
boost::bidirectional_iterator_tag,
typename ct_if<
is_convertible<Category*, std::forward_iterator_tag*>::value,
boost::forward_iterator_tag,
boost::single_pass_iterator_tag>::type
>::type
>::type type;
};
struct iter_traits_from_old_traits {
template <typename Iterator> class bind {
typedef boost::detail::iterator_traits<Iterator> OldTraits;
typedef typename OldTraits::iterator_category Cat;
public:
typedef typename OldTraits::value_type value_type;
typedef typename OldTraits::reference reference;
typedef typename OldTraits::pointer pointer;
typedef typename OldTraits::difference_type difference_type;
typedef iter_category_to_return<Cat,value_type>::type return_category;
typedef iter_category_to_traversal<Cat>::type traversal_category;
};
};
template <typename Iterator>
class choose_iter_traits {
typedef typename ct_if<is_convertible<Iterator*,
new_iterator_base*>::value,
iter_traits_from_nested_types,
iter_traits_from_old_traits>::type Choice;
public:
typedef typename Choice:: template bind<Iterator> type;
};
} // namespace detail
template <typename Iterator>
class iterator_traits
: public detail::choose_iter_traits<Iterator>::type { };
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <typename T>
struct iterator_traits<T*>
{
typedef T value_type;
typedef T& reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
typedef typename ct_if<is_const<T>::value,
boost::constant_lvalue_iterator_tag,
boost::mutable_lvalue_iterator_tag>::type
return_category;
typedef boost::random_access_iterator_tag traversal_category;
};
#endif
} // namespace boost
#endif // BOOST_ITERATOR_TRAITS_HPP

View File

@ -0,0 +1,76 @@
#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_iterator_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; }
struct bar { };
void foo(bar) { }
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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,606 @@
<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 concepts (the iterator requirements defined
in the C++ Standard) have a flaw. They glom together two separate
issues into a single set of concepts. The two issues are iterator
traversal and dereference return type semantics. These two issues are
inherently orthogonal and therefore ought to be represented by two
separate sets of concepts. The concepts described here do just
that.</p>
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:MutableLvalueIterator">Mutable Lvalue Iterator</a></li>
<li><a href="#concept:ConstantLvalueIterator">Constant Lvalue Iterator</a></li>
</ul>
The other set of concepts handles iterator traversal:
<ul>
<li><a href="#concept:SinglePassIterator">Single-Pass Iterator</a></li>
<li><a href="#concept:ForwardIterator">Forward Iterator</a></li>
<li><a href="#concept:BidirectionalIterator">Bidirectional Iterator</a></li>
<li><a href="#concept:RandomAccessIterator">Random Access Iterator</a></li>
</ul>
<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" width="541" height="214"></TD></TR>
</TABLE>
</DIV>
<p></p>
<h2>Relationship with the standard iterator concepts</h2>
<p>
std::Input Iterator refines boost::Single-Pass Iterator and
boost::ReadableIterator.
<p>
std::Output Iterator refines boost::Single-Pass Iterator and
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>.</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>
<H2><A NAME="concept:ReadableIterator"></A>
Readable Iterator
</H2>
A Readable Iterator is an iterator that dereferences to produce an
rvalue that is convertible to the <tt>value_type</tt> of the
iterator. For example, derefencing may return a temporary object and
therefore it would be a mistake to bind the result to a reference.
Also, an attempt to assign a value to the result will most likely
cause an error.
<pre>
template &lt;class Readable Iterator&gt;
void foo(Readable Iterator x)
{
typedef std::iterator_traits&lt;Readable Iterator&gt;::value_type T;
T t = *x; // Read a value. This is OK.
T& s = *x; // Bind to a reference. This is a bad idea.
*x = t; // Try to assign. This is a really bad idea.
}
</pre>
<h3>Associated Types</h3>
<Table border>
<TR>
<TD>Value type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::value_type</tt></TD>
<TD>
The type of the value obtained by dereferencing a LvalueIterator
</TD>
</tr>
<TR>
<TD>Return Category</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::return_category</tt></TD>
<TD>
A type convertible to <tt>boost::readable_iterator_tag</tt>
</TD>
</tr>
</Table>
<h3>Refinement of</h3>
<A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>,
<A href="http://www.sgi.com/Technology/STL/EqualityComparable.html">Equality Comparable</A>,
<A href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">Default 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>Convertible to <tt>T</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>
<H2><A NAME="concept:WritableIterator"></A>
Writable Iterator
</H2>
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><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::return_category</tt></TD>
<TD>
A type convertible to <tt>boost::writable_iterator_tag</tt>
</TD>
</tr>
</Table>
<h3>Refinement of</h3>
<A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>,
<A href="http://www.sgi.com/Technology/STL/EqualityComparable.html">Equality Comparable</A>,
<A href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">Default 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>
<H2><A NAME="concept:ConstantLvalueIterator"></A>
Constant Lvalue Iterator
</H2>
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:Readable Iterator">Readable Iterator</a>
<h3>Associated Types</h3>
<Table border>
<TR>
<TD>Value type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::value_type</tt></TD>
<TD>
The type of the value obtained by dereferencing a Constant Lvalue Iterator.
</TD>
</tr>
<TR>
<TD>Reference type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::reference</tt></TD>
<TD>
The return type of <tt>operator*()</tt>, which must be
<tt>const T&amp;</tt>.
</TD>
</tr>
<TR>
<TD>POinter type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&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><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::return_category</tt></TD>
<TD>
A type convertible to <tt>boost::constant_lvalue_iterator_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>Dereference</TD>
<TD><tt>*x</tt></TD>
<TD>&nbsp;</TD>
<TD><tt>const T&amp;</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>
<H2><A NAME="concept:MutableLvalueIterator"></A>
Mutable Lvalue Iterator
</H2>
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:Readable Iterator">Readable Iterator</a> and
<a href="#concept:WritableIterator">Writable Iterator</a>.
<h3>Associated Types</h3>
<Table border>
<TR>
<TD>Value type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::value_type</tt></TD>
<TD>
The type of the value obtained by dereferencing a Mutable Lvalue Iterator.
</TD>
</tr>
<TR>
<TD>Reference type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::reference</tt></TD>
<TD>
The return type of <tt>operator*()</tt>, which is
<tt>T&amp;</tt>.
</TD>
</tr>
<TR>
<TD>Pointer type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&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><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::return_category</tt></TD>
<TD>
A type convertible to <tt>boost::mutable_lvalue_iterator_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>Dereference</TD>
<TD><tt>*x</tt></TD>
<TD>&nbsp;</TD>
<TD> <tt>T&amp;</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>
<H2><A NAME="concept:SinglePassIterator"></A>
Single-Pass Iterator
</H2>
A Single-Pass Iterator is an iterator that can be incremented to
traverse through a sequence of objects, but the sequence can only be
traversed a single time.
<h3>Associated types</h3>
<Table border>
<TR>
<TD>Difference type</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::difference_type</tt></TD>
<TD>
A signed integral type used to represent the distance from one
iterator to another, or the number of elements in a range.
</TD>
</TR>
<TR>
<TD>Traversal Category</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::traversal_category</tt></TD>
<TD>
A type convertible to <tt>boost::single_pass_iterator_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>(void)i++</tt></TD><TD>&nbsp;</TD><TD>&nbsp;</TD>
</TR>
</Table>
<p>
<hr>
<H2><A NAME="concept:ForwardIterator"></A>
Forward Iterator
</H2>
The Forward Iterator is an iterator that can be incremented. Also, it
is permissible to make multiple passes through the sequence.
<h3>Refinement of</h3>
<a href="#concept:SinglePassIterator">Single-Pass Iterator</a>
<h3>Associated types</h3>
<Table border>
<TR>
<TD>Traversal Category</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::traversal_category</tt></TD>
<TD>
A type convertible to <tt>boost::forward_iterator_tag</tt>
</TD>
</tr>
</Table>
<p>
<hr>
<H2><A NAME="concept:BidirectionalIterator"></A>
Bidirectional Iterator
</H2>
An iterator that can be incremented and decremented.
<h3>Refinement of</h3>
<a href="#concept:ForwardIterator">Forward Iterator</a>
<h3>Associated types</h3>
<Table border>
<TR>
<TD>Traversal Category</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::traversal_category</tt></TD>
<TD>
A type convertible to <tt>boost::bidirectional_iterator_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><tt>X</tt></TD>
</tr>
</table>
<p>
<hr>
<H2><A NAME="concept:RandomAccessIterator"></A>
Random Access Iterator
</H2>
An iterator that provides constant-time methods for moving forward and
backward in arbitrary-sized steps
<h3>Refinement of</h3>
<a href="#concept:BidirectionalIterator">Bidirectional Iterator</a>
<h3>Associated types</h3>
<Table border>
<TR>
<TD>Traversal Category</TD>
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::traversal_category</tt></TD>
<TD>
A type convertible to <tt>boost::random_access_iterator_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><a href="./iterator_traits.htm">boost::iterator_traits</a>&lt;X&gt;::difference_type</tt></TD>
</TR>
<TR><TD>Element operator</TD>
<TD><tt>i[n]</tt></TD>
<TD><tt>X</tt> must be a model of
<a href="#concept:Readable Iterator">Readable Iterator</a>. </TD>
<TD>The same return type as <tt>*i</tt>.</TD>
</TR>
<TR><TD>Element assignment</TD>
<TD><tt>i[n] = t</tt></TD>
<TD><tt>X</tt> must be a model of
<a href="#concept:WritableIterator">Writable Iterator</a>.</TD>
<TD>unspecified</TD>
</tr>
</table>
<hr>
<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

@ -0,0 +1,137 @@
<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.
-->
<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 Traits</h1>
Header <tt><a href="../../boost/iterator_traits.hpp">boost/iterator_traits.hpp</a></tt>
<p>
The <tt>boost::iterator_traits</tt> class provides access to the
associated types of 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 main difference between <tt>std::iterator_traits</tt> and
<tt>boost::iterator_traits</tt> is that the <tt>iterator_category</tt>
type has been removed, and replaced with two new types:
<ul>
<li><tt>traversal_category</tt>:&nbsp;&nbsp; Can the iterator go forward, backward, etc.?
<li><tt>return_category</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::iterator_traits</tt> is that it
is <b>backwards compatible</b>, i.e., it will 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::iterator_traits</tt>, you can either create a
specialization of <tt>boost::iterator_traits</tt> 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 <tt>boost::iterator_traits</tt> know
that it will be able to find typedefs for <tt>traversal_category</tt>
and <tt>return_category</tt> in you iterator class.
<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 iterator_traits
{
if (Iterator inherits from new_iterator_base) {
typedef typename Iterator::value_type value_type;
typedef typename Iterator::reference reference;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::return_category return_category;
typedef typename Iterator::traversal_category traversal_category;
} else {
typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
typedef typename OldTraits::value_type value_type;
typedef typename OldTraits::reference reference;
typedef typename OldTraits::pointer pointer;
typedef typename OldTraits::difference_type difference_type;
typedef typename OldTraits::iterator_category Cat;
<i>// Determine the traversal_category based on the old iterator_category</i>
if (Cat inherits from std::random_access_iterator_tag)
typedef boost::random_access_iterator_tag traversal_category;
else if (Cat inherits from std::bidirectional_iterator_tag)
typedef boost::bidirectional_iterator_tag traversal_category;
else if (Cat inherits from std::forward_iterator_tag)
typedef boost::forward_iterator_tag traversal_category;
else
typedef boost::single_pass_iterator_tag traversal_category;
<i>// Determine the return_category based on the old iterator_category and value_type</i>
if (Cat inherits from std::forward_iterator_tag)
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag return_category;
else
typedef boost::mutable_lvalue_iterator_tag return_category;
else if (Cat inherits from std::input_iterator_tag)
typedef boost::readable_iterator_tag return_category;
else if (Cat inherits from std::output_iterator_tag)
typedef boost::writable_iterator_tag return_category;
else
typedef boost::error_iterator_tag return_category;
}
};
template &lt;typename T&gt;
struct iterator_traits&lt;T*&gt;
{
typedef T value_type;
typedef T&amp; reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag return_category;
else
typedef boost::mutable_lvalue_iterator_tag return_category;
typedef boost::random_access_iterator_tag traversal_category;
};
}
</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

@ -56,7 +56,9 @@
# include <boost/type_traits.hpp>
# include <boost/detail/numeric_traits.hpp>
# include <boost/static_assert.hpp>
# include <boost/limits.hpp>
# ifndef BOOST_NO_LIMITS
# include <limits>
# endif
namespace boost {
@ -133,15 +135,7 @@ namespace detail {
// 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
# if defined(BOOST_HAS_LONG_LONG)
BOOST_STATIC_CONSTANT(bool,
value = (
std::numeric_limits<T>::is_specialized
| boost::is_same<T,long long>::value
| boost::is_same<T,unsigned long long>::value));
# else
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# endif
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# else
# if !defined(__BORLANDC__)
BOOST_STATIC_CONSTANT(bool, value = (
@ -179,17 +173,14 @@ struct counting_iterator_traits {
template <class Incrementable>
struct counting_iterator_policies : public default_iterator_policies
{
template <class IteratorAdaptor>
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& i) const
{ return i.base(); }
template <class Iterator1, class Iterator2>
typename Iterator1::difference_type distance(
const Iterator1& x, const Iterator2& y) const
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
{
typedef typename Iterator1::difference_type difference_type;
return boost::detail::any_distance<difference_type>(
x.base(), y.base());
return boost::detail::any_distance<Difference>(x, y);//,(Difference*)());
}
};
@ -197,20 +188,15 @@ struct counting_iterator_policies : public default_iterator_policies
template <class Incrementable>
struct counting_iterator_generator
{
typedef typename boost::remove_const<
Incrementable
>::type value_type;
typedef counting_iterator_traits<Incrementable> traits;
typedef counting_iterator_traits<value_type> traits;
typedef iterator_adaptor<
value_type
, counting_iterator_policies<value_type>
, value_type
, value_type const&
, value_type const*
, typename traits::iterator_category
, typename traits::difference_type
typedef iterator_adaptor<Incrementable,
counting_iterator_policies<Incrementable>,
Incrementable,
const Incrementable&,
const Incrementable*,
typename traits::iterator_category,
typename traits::difference_type
> type;
};

View File

@ -99,17 +99,17 @@ struct half_open_range
public:
typedef iter_t const_iterator;
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
typedef typename iterator::reference reference;
typedef typename iterator::reference const_reference;
typedef typename iterator::pointer pointer;
typedef typename iterator::pointer const_pointer;
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 iterator::difference_type size_type;
typedef typename counting_iterator_traits<Incrementable>::difference_type size_type;
half_open_range(Incrementable start, Incrementable finish)
: m_start(start),

View File

@ -21,7 +21,7 @@
namespace boost
{
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
# ifdef BOOST_NO_STD_ITERATOR
template <class Category, class T,
class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,6 @@
// test suite for STL concepts such as iterators and containers.
//
// Revision History:
// 28 Apr 2002 Fixed input iterator requirements.
// For a == b a++ == b++ is no longer required.
// See 24.1.1/3 for details.
// (Thomas Witt)
// 08 Feb 2001 Fixed bidirectional iterator test so that
// --i is no longer a precondition.
// (Jeremy Siek)
@ -78,40 +74,22 @@ void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
template <class Iterator, class T>
void input_iterator_test(Iterator i, T v1, T v2)
{
Iterator i1(i);
Iterator i1 = i, i2 = i;
assert(i == i1);
assert(!(i != i1));
assert(i == i1++);
assert(i != ++i2);
// I can see no generic way to create an input iterator
// that is in the domain of== of i and != i.
// The following works for istream_iterator but is not
// guaranteed to work for arbitrary input iterators.
//
// Iterator i2;
//
// assert(i != i2);
// assert(!(i == i2));
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
assert(*i1 == v1);
assert(*i == v1);
// we cannot test for equivalence of (void)++i & (void)i++
// as i is only guaranteed to be single pass.
assert(*i++ == v1);
i1 = i;
assert(i == i1);
assert(!(i != i1));
assert(*i1 == v2);
assert(*i == v2);
// i is dereferencable, so it must be incrementable.
++i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
// how to test for operator-> ?
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
}
// how to test output iterator?
@ -146,23 +124,6 @@ void forward_iterator_test(Iterator i, T v1, T v2)
{
input_iterator_test(i, v1, v2);
Iterator i1 = i, i2 = i;
assert(i == i1++);
assert(i != ++i2);
trivial_iterator_test(i, i1, v1);
trivial_iterator_test(i, i2, v1);
++i;
assert(i == i1);
assert(i == i2);
++i1;
++i2;
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
// borland doesn't allow non-type template parameters
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);

View File

@ -1,72 +0,0 @@
// (C) Copyright Toon Knapen 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.
//
#ifndef boost_permutation_iterator_hpp
#define boost_permutation_iterator_hpp
#include <boost/iterator_adaptors.hpp>
namespace boost {
template < typename IndexIterator >
struct permutation_iterator_policies : public default_iterator_policies
{
permutation_iterator_policies() {}
permutation_iterator_policies(IndexIterator order_it)
: order_it_( order_it )
{}
template <class IteratorAdaptor>
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const
{ return *(x.base() + *order_it_); }
template <class IteratorAdaptor>
void increment(IteratorAdaptor&)
{ ++order_it_; }
template <class IteratorAdaptor>
void decrement(IteratorAdaptor&)
{ --order_it_; }
template <class IteratorAdaptor, class DifferenceType>
void advance(IteratorAdaptor& x, DifferenceType n)
{ std::advance( order_it_, n ); }
template <class IteratorAdaptor1, class IteratorAdaptor2>
typename IteratorAdaptor1::difference_type
distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
{ return std::distance( x.policies().order_it_, y.policies().order_it_ ); }
template <class IteratorAdaptor1, class IteratorAdaptor2>
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
{ return x.policies().order_it_ == y.policies().order_it_; }
IndexIterator order_it_;
};
template < typename ElementIterator, typename IndexIterator >
struct permutation_iterator_generator
{
typedef boost::iterator_adaptor
< ElementIterator,
permutation_iterator_policies< IndexIterator >
> type;
};
template < class IndexIterator, class ElementIterator >
inline typename permutation_iterator_generator< ElementIterator, IndexIterator >::type
make_permutation_iterator(ElementIterator base, IndexIterator order)
{
typedef typename permutation_iterator_generator< ElementIterator, IndexIterator >::type result_t;
return result_t( base, order );
}
} // namespace boost
#endif // boost_permutation_iterator_hpp