Compare commits

...

32 Commits

Author SHA1 Message Date
abffbb8300 This commit was manufactured by cvs2svn to create branch
'python-v2-dev'.

[SVN r14785]
2002-08-12 13:35:54 +00:00
34c159dd8d Minor sunpro compartibility fix
[SVN r14741]
2002-08-08 16:42:18 +00:00
b22a3adc02 Add BOOST_NO_STD_ITERATOR_TRAITS workaround
[SVN r14663]
2002-08-03 22:45:13 +00:00
4a24e0f401 Fixed for VC7.1
[SVN r14433]
2002-07-13 12:11:06 +00:00
3844edc4bf Fixed input iterator requirements. For a == b a++ == b++ is no longer
required. See 24.1.1/3 for details. (Thomas Witt)


[SVN r13716]
2002-05-07 11:56:08 +00:00
fdd1601ba4 Added new config macro BOOST_HAS_MS_INT64 to detect presence of __int64 data type.
Modified boost source to use BOOST_HAS_LONG_LONG and BOOST_HAS_MS_INT64
   where appropriate to do so.


[SVN r13714]
2002-05-07 11:24:29 +00:00
e9b33b336c added typename keyword (Bertolt Mildner)
[SVN r13675]
2002-05-06 06:44:14 +00:00
2574365b5c added support for reference named_parameters
[SVN r13638]
2002-05-03 13:52:39 +00:00
12b9366f33 BOOST_NO_LIMITS should not be used by user code; use <boost/limits.hpp> instead
BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS should not be defined when
BOOST_NO_LIMITS is defined


[SVN r13340]
2002-04-01 18:57:43 +00:00
4772bb099e added more comments in the default_iterator_policies
[SVN r12706]
2002-02-04 20:25:45 +00:00
2be5179020 killed tabs
[SVN r12702]
2002-02-04 20:01:51 +00:00
8cb49713b4 half_open_range.hpp:
- counting_iterator_traits does not contain the iterator traits value_type,
    reference, pointer, etc.


[SVN r12526]
2002-01-27 14:55:20 +00:00
bd666dc0e9 added include guards
[SVN r12517]
2002-01-26 09:26:09 +00:00
57251d58cc Moved concept checks into a separate class, which makes MSVC better at dealing with them
[SVN r12255]
2002-01-09 12:14:16 +00:00
ebcb4d861a Borland workarounds
[SVN r12251]
2002-01-08 18:36:26 +00:00
15a7a839f9 Choose proxy for operator->() only if the reference type is not a reference.
Updated workarounds for __MWERKS__ == 0x2406


[SVN r12245]
2002-01-07 15:43:30 +00:00
76a307d31e fixes
[SVN r12146]
2001-12-24 19:27:39 +00:00
37aee7c13b Re-enabled some STATIC_ASSERTs for MSVC, using bitwise operators to avoid ICEs.
[SVN r12030]
2001-12-13 14:34:11 +00:00
50a502bb81 uses proper template argument names : ElementIterator and IndexIterator
[SVN r11826]
2001-11-30 11:14:24 +00:00
8a4839354e permutation_iterator_adaptor and generator
[SVN r11823]
2001-11-30 10:38:36 +00:00
4da7371246 *** empty log message ***
[SVN r11611]
2001-11-06 15:52:56 +00:00
e162a75e53 *** empty log message ***
[SVN r11609]
2001-11-06 15:28:04 +00:00
e60df6ad92 Workarounds for CWPro7, MSVC
Changed all "bind" to "select" (again), to avoid conflicting with Peter Dimov's code.


[SVN r11590]
2001-11-05 16:33:40 +00:00
4c2b3a9d2c Cleanups for MWERKS, without changing functionality
[SVN r11585]
2001-11-05 15:25:45 +00:00
75023a1dd3 Fixed comparison bugs; more remain.
[SVN r11581]
2001-11-05 06:25:31 +00:00
79370a6dfb non-named parameter version of some BGL algorithms
some VC++ compiler stuff


[SVN r11576]
2001-11-04 23:24:12 +00:00
4566798afc iterator adaptor update and related changes
[SVN r11554]
2001-11-04 02:50:10 +00:00
3fd1c4bc5d Changed projection_iterator to not rely on the default reference,
working around a limitation of detail::iterator_traits


[SVN r11340]
2001-10-04 21:02:12 +00:00
2d6f48d5ab Applied indirect_iterator patch from George A. Heintzelman <georgeh@aya.yale.edu>
Changed name of "bind" to "select" to avoid problems with MSVC.


[SVN r11337]
2001-10-04 19:36:28 +00:00
d1c7594344 Added borland bug fix
[SVN r11290]
2001-09-27 00:26:01 +00:00
ac327f51e9 commit of split-config, including any changes required to existing libraries (mainly regex).
[SVN r11138]
2001-09-18 11:13:39 +00:00
4e18b11263 metrowerks fix for decrement()
[SVN r10997]
2001-09-03 15:38:05 +00:00
13 changed files with 664 additions and 1562 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

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

View File

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

View File

@ -99,17 +99,17 @@ struct half_open_range
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;
typedef typename iterator::value_type value_type;
typedef typename iterator::difference_type difference_type;
typedef typename iterator::reference reference;
typedef typename iterator::reference const_reference;
typedef typename iterator::pointer pointer;
typedef typename iterator::pointer const_pointer;
// It would be nice to select an unsigned type, but this is appropriate
// since the library makes an attempt to select a difference_type which can
// hold the difference between any two iterators.
typedef typename counting_iterator_traits<Incrementable>::difference_type size_type;
typedef typename iterator::difference_type size_type;
half_open_range(Incrementable start, Incrementable finish)
: m_start(start),

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,10 @@
// 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)
@ -74,22 +78,40 @@ 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, i2 = i;
Iterator i1(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;
assert(!(i != i1));
trivial_iterator_test(i, i1, v2);
trivial_iterator_test(i, i2, v2);
// I can see no generic way to create an input iterator
// that is in the domain of== of i and != i.
// The following works for istream_iterator but is not
// guaranteed to work for arbitrary input iterators.
//
// Iterator i2;
//
// assert(i != i2);
// assert(!(i == i2));
assert(*i1 == v1);
assert(*i == v1);
// we cannot test for equivalence of (void)++i & (void)i++
// as i is only guaranteed to be single pass.
assert(*i++ == v1);
i1 = i;
assert(i == i1);
assert(!(i != i1));
assert(*i1 == v2);
assert(*i == v2);
// i is dereferencable, so it must be incrementable.
++i;
// how to test for operator-> ?
}
// how to test output iterator?
@ -124,6 +146,23 @@ 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

@ -0,0 +1,72 @@
// (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