forked from boostorg/iterator
Compare commits
30 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
6ca935d9fe | |||
dea89aa823 | |||
ce5d2ec4b4 | |||
640379ac34 | |||
7cbe926f29 | |||
5113e4fbec | |||
66183e43f5 | |||
4247559960 | |||
c7c6448bd5 | |||
218778bb94 | |||
4b4de44736 | |||
8deb1c20fb | |||
20e6d71755 | |||
52f72c2115 | |||
6b2da49430 | |||
f46f7f8091 | |||
22670777b8 | |||
6270de1db0 | |||
6e06e4f89e | |||
eb73b8e0e2 | |||
7ffe2601a9 | |||
62b70f57a9 | |||
cd37eb3bfb | |||
bda5890235 | |||
d51c5ebf07 | |||
6f90b8b161 | |||
6ec791e3b9 | |||
20f188d971 | |||
7273be17c0 | |||
77a89a0b89 |
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
@ -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<Iter>::type</tt> Can the iterator go forward, backward, etc.?
|
||||
<li><tt>return_category<Iter>::type</tt> 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 <typename Iterator>
|
||||
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<Iterator> 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 <typename T>
|
||||
struct return_category<T*>
|
||||
{
|
||||
<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 <typename Iterator>
|
||||
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<Iterator> 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 <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
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>
|
@ -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 |
@ -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<X>::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<X>::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<X>::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<X>::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> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->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<X>::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<X>::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&</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<X>::reference</tt></td>
|
||||
<td>
|
||||
The return type of dereferencing the iterator, which must be
|
||||
<tt>const T&</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- I don't think this is needed
|
||||
<tr>
|
||||
<td>Pointer type</td>
|
||||
<td><tt>std::iterator_traits<X>::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<X>::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> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->m</tt></td>
|
||||
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
|
||||
<td>
|
||||
|
||||
</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&</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<X>::reference</tt></td>
|
||||
<td>The return type of dereferencing the iterator, which must be
|
||||
<tt>T&</tt>.</td>
|
||||
</tr>
|
||||
|
||||
<!-- I don't think this is necessary
|
||||
<tr>
|
||||
<td>Pointer type</td>
|
||||
<td><tt>std::iterator_traits<X>::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<X>::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> </td>
|
||||
<td><tt>std::iterator_traits<X>::reference</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Member access</td>
|
||||
<td><tt>x->m</tt></td>
|
||||
<td><tt>T</tt> is a type with a member named <tt>m</tt>.</td>
|
||||
<td>
|
||||
|
||||
</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<X>::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<X>::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> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Postincrement</td>
|
||||
<td><tt>i++</tt></td><td> </td><td>convertible to <tt>const X&</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<X>::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> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Postdecrement</td>
|
||||
<td><tt>i--</tt></td><td> </td><td>convertible to <tt>const X&</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><</tt> is a total ordering
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<Table border>
|
||||
<tr>
|
||||
<td>Traversal Category</td>
|
||||
<td><tt>std::traversal_category<X>::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> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator addition</td>
|
||||
<td><tt>i + n</tt> or <tt>n + i</tt></td><td> </td><td><tt>X</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator subtraction</td>
|
||||
<td><tt>i -= n</tt></td><td> </td><td><tt>X&</tt></td>
|
||||
</tr>
|
||||
<tr><td>Iterator subtraction</td>
|
||||
<td><tt>i - n</tt></td><td> </td><td><tt>X</tt></td>
|
||||
</tr>
|
||||
<tr><td>Difference</td>
|
||||
<td><tt>i - j</tt></td><td> </td><td><tt>std::iterator_traits<X>::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<X>::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 © 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>
|
BIN
doc/access.png
BIN
doc/access.png
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 41 KiB |
@ -1,150 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Counting Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="counting-iterator">
|
||||
<h1 class="title">Counting Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The counting iterator adaptor implements dereference by returning a
|
||||
reference to the base object. The other operations are implemented by
|
||||
the base <tt class="literal"><span class="pre">m_iterator</span></tt>, as per the inheritance from
|
||||
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#counting-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#counting-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <class Incrementable, class Category = use_default, class Difference = use_default>
|
||||
class counting_iterator
|
||||
: public iterator_adaptor<
|
||||
counting_iterator<Incrementable, Category, Difference>
|
||||
, Incrementable
|
||||
, Incrementable
|
||||
, /* see details for category */
|
||||
, Incrementable const&
|
||||
, Incrementable const*
|
||||
, /* distance = Difference or a signed integral type */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
counting_iterator();
|
||||
counting_iterator(counting_iterator const& rhs);
|
||||
counting_iterator(Incrementable x);
|
||||
private:
|
||||
typename counting_iterator::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<dl>
|
||||
<dt>[<em>Note:</em> implementers are encouraged to provide an implementation of</dt>
|
||||
<dd><tt class="literal"><span class="pre">distance_to</span></tt> and a <tt class="literal"><span class="pre">difference_type</span></tt> that avoids overflows in
|
||||
the cases when the <tt class="literal"><span class="pre">Incrementable</span></tt> type is a numeric type.]</dd>
|
||||
</dl>
|
||||
<div class="section" id="counting-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="counting-iterator-requirements"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></h1>
|
||||
<p>The <tt class="literal"><span class="pre">Incrementable</span></tt> type must be Default Constructible, Copy
|
||||
Constructible, and Assignable. The default distance is
|
||||
an implementation defined signed integegral type.</p>
|
||||
<p>The resulting <tt class="literal"><span class="pre">counting_iterator</span></tt> models Readable Lvalue Iterator.</p>
|
||||
<p>Furthermore, if you wish to create a counting iterator that is a Forward
|
||||
Traversal Iterator, then the following expressions must be valid:</p>
|
||||
<pre class="literal-block">
|
||||
Incrementable i, j;
|
||||
++i // pre-increment
|
||||
i == j // operator equal
|
||||
</pre>
|
||||
<p>If you wish to create a counting iterator that is a
|
||||
Bidirectional Traversal Iterator, then pre-decrement is also required:</p>
|
||||
<pre class="literal-block">
|
||||
--i
|
||||
</pre>
|
||||
<p>If you wish to create a counting iterator that is a Random Access
|
||||
Traversal Iterator, then these additional expressions are also
|
||||
required:</p>
|
||||
<pre class="literal-block">
|
||||
counting_iterator::difference_type n;
|
||||
i += n
|
||||
n = i - j
|
||||
i < j
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="counting-iterator-operations">
|
||||
<h1><a class="toc-backref" href="#id2" name="counting-iterator-operations"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">counting_iterator();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A default constructed instance of <tt class="literal"><span class="pre">counting_iterator</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">counting_iterator(counting_iterator</span> <span class="pre">const&</span> <span class="pre">rhs);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">rhs</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">counting_iterator(Incrementable</span> <span class="pre">x);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> with its base
|
||||
object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="counting_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
+++++++++++++++++++
|
||||
Counting Iterator
|
||||
+++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: counting_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: counting_iterator_ref.rst
|
@ -1,5 +0,0 @@
|
||||
The counting iterator adaptor implements dereference by returning a
|
||||
reference to the base object. The other operations are implemented by
|
||||
the base ``m_iterator``, as per the inheritance from
|
||||
``iterator_adaptor``.
|
||||
|
@ -1,85 +0,0 @@
|
||||
::
|
||||
|
||||
template <class Incrementable, class Category = use_default, class Difference = use_default>
|
||||
class counting_iterator
|
||||
: public iterator_adaptor<
|
||||
counting_iterator<Incrementable, Category, Difference>
|
||||
, Incrementable
|
||||
, Incrementable
|
||||
, /* see details for category */
|
||||
, Incrementable const&
|
||||
, Incrementable const*
|
||||
, /* distance = Difference or a signed integral type */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
counting_iterator();
|
||||
counting_iterator(counting_iterator const& rhs);
|
||||
counting_iterator(Incrementable x);
|
||||
private:
|
||||
typename counting_iterator::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
[*Note:* implementers are encouraged to provide an implementation of
|
||||
``distance_to`` and a ``difference_type`` that avoids overflows in
|
||||
the cases when the ``Incrementable`` type is a numeric type.]
|
||||
|
||||
``counting_iterator`` requirements
|
||||
----------------------------------
|
||||
|
||||
The ``Incrementable`` type must be Default Constructible, Copy
|
||||
Constructible, and Assignable. The default distance is
|
||||
an implementation defined signed integegral type.
|
||||
|
||||
The resulting ``counting_iterator`` models Readable Lvalue Iterator.
|
||||
|
||||
Furthermore, if you wish to create a counting iterator that is a Forward
|
||||
Traversal Iterator, then the following expressions must be valid:
|
||||
::
|
||||
|
||||
Incrementable i, j;
|
||||
++i // pre-increment
|
||||
i == j // operator equal
|
||||
|
||||
If you wish to create a counting iterator that is a
|
||||
Bidirectional Traversal Iterator, then pre-decrement is also required:
|
||||
::
|
||||
|
||||
--i
|
||||
|
||||
If you wish to create a counting iterator that is a Random Access
|
||||
Traversal Iterator, then these additional expressions are also
|
||||
required:
|
||||
::
|
||||
|
||||
counting_iterator::difference_type n;
|
||||
i += n
|
||||
n = i - j
|
||||
i < j
|
||||
|
||||
|
||||
|
||||
|
||||
``counting_iterator`` operations
|
||||
--------------------------------
|
||||
|
||||
``counting_iterator();``
|
||||
|
||||
:Returns: A default constructed instance of ``counting_iterator``.
|
||||
|
||||
|
||||
``counting_iterator(counting_iterator const& rhs);``
|
||||
|
||||
:Returns: An instance of ``counting_iterator`` that is a copy of ``rhs``.
|
||||
|
||||
|
||||
|
||||
``counting_iterator(Incrementable x);``
|
||||
|
||||
:Returns: An instance of ``counting_iterator`` with its base
|
||||
object copy constructed from ``x``.
|
||||
|
188
doc/default.css
188
doc/default.css
@ -1,188 +0,0 @@
|
||||
/*
|
||||
:Author: David Goodger
|
||||
:Contact: goodger@users.sourceforge.net
|
||||
:date: $Date$
|
||||
:version: $Revision$
|
||||
:copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
*/
|
||||
|
||||
.first {
|
||||
margin-top: 0 }
|
||||
|
||||
.last {
|
||||
margin-bottom: 0 }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.attention, div.caution, div.danger, div.error, div.hint,
|
||||
div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.hint p.admonition-title, div.important p.admonition-title,
|
||||
div.note p.admonition-title, div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
font-size: smaller }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.title {
|
||||
text-align: center }
|
||||
|
||||
h2.subtitle {
|
||||
text-align: center }
|
||||
|
||||
hr {
|
||||
width: 75% }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.topic-title {
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font-family: serif ;
|
||||
font-size: 100% }
|
||||
|
||||
pre.line-block {
|
||||
font-family: serif ;
|
||||
font-size: 100% }
|
||||
|
||||
pre.literal-block, pre.doctest-block {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em ;
|
||||
background-color: #eeeeee }
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option-argument {
|
||||
font-style: italic }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic {
|
||||
color: red }
|
||||
|
||||
table {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.citation {
|
||||
border-left: solid thin gray ;
|
||||
padding-left: 0.5ex }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid thin black ;
|
||||
padding-left: 0.5ex }
|
||||
|
||||
td, th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
th.docinfo-name, th.field-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap }
|
||||
|
||||
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
|
||||
font-size: 100% }
|
||||
|
||||
tt {
|
||||
background-color: #eeeeee }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
File diff suppressed because it is too large
Load Diff
@ -1,398 +0,0 @@
|
||||
+++++++++++++++++++++++++++++
|
||||
Iterator Facade and Adaptor
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:Number: **This document is a revised version of the official** N1476=03-0059
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract: We propose a set of class templates that help programmers
|
||||
build standard-conforming iterators, both from scratch and
|
||||
by adapting other iterators.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
============
|
||||
Motivation
|
||||
============
|
||||
|
||||
Iterators play an important role in modern C++ programming. The
|
||||
iterator is the central abstraction of the algorithms of the Standard
|
||||
Library, allowing algorithms to be re-used in in a wide variety of
|
||||
contexts. The C++ Standard Library contains a wide variety of useful
|
||||
iterators. Every one of the standard containers comes with constant
|
||||
and mutable iterators [#mutable]_, and also reverse versions of those
|
||||
same iterators which traverse the container in the opposite direction.
|
||||
The Standard also supplies ``istream_iterator`` and
|
||||
``ostream_iterator`` for reading from and writing to streams,
|
||||
``insert_iterator``, ``front_insert_iterator`` and
|
||||
``back_insert_iterator`` for inserting elements into containers, and
|
||||
``raw_storage_iterator`` for initializing raw memory [7].
|
||||
|
||||
Despite the many iterators supplied by the Standard Library, obvious
|
||||
and useful iterators are missing, and creating new iterator types is
|
||||
still a common task for C++ programmers. The literature documents
|
||||
several of these, for example line_iterator [3] and Constant_iterator
|
||||
[9]. The iterator abstraction is so powerful that we expect
|
||||
programmers will always need to invent new iterator types.
|
||||
|
||||
Although it is easy to create iterators that *almost* conform to the
|
||||
standard, the iterator requirements contain subtleties which can make
|
||||
creating an iterator which *actually* conforms quite difficult.
|
||||
Further, the iterator interface is rich, containing many operators
|
||||
that are technically redundant and tedious to implement. To automate
|
||||
the repetitive work of constructing iterators, we propose
|
||||
``iterator_facade``, an iterator base class template which provides
|
||||
the rich interface of standard iterators and delegates its
|
||||
implementation to member functions of the derived class. In addition
|
||||
to reducing the amount of code necessary to create an iterator, the
|
||||
``iterator_facade`` also provides compile-time error detection.
|
||||
Iterator implementation mistakes that often go unnoticed are turned
|
||||
into compile-time errors because the derived class implementation must
|
||||
match the expectations of the ``iterator_facade``.
|
||||
|
||||
A common pattern of iterator construction is the adaptation of one
|
||||
iterator to form a new one. The functionality of an iterator is
|
||||
composed of four orthogonal aspects: traversal, indirection, equality
|
||||
comparison and distance measurement. Adapting an old iterator to
|
||||
create a new one often saves work because one can reuse one aspect of
|
||||
functionality while redefining the other. For example, the Standard
|
||||
provides ``reverse_iterator``, which adapts any Bidirectional Iterator
|
||||
by inverting its direction of traversal. As with plain iterators,
|
||||
iterator adaptors defined outside the Standard have become commonplace
|
||||
in the literature:
|
||||
|
||||
* Checked iter[13] adds bounds-checking to an existing iterator.
|
||||
|
||||
* The iterators of the View Template Library[14], which adapts
|
||||
containers, are themselves adaptors over the underlying iterators.
|
||||
|
||||
* Smart iterators [5] adapt an iterator's dereferencing behavior by
|
||||
applying a function object to the object being referenced and
|
||||
returning the result.
|
||||
|
||||
* Custom iterators [4], in which a variety of adaptor types are enumerated.
|
||||
|
||||
* Compound iterators [1], which access a slice out of a container of containers.
|
||||
|
||||
* Several iterator adaptors from the MTL [12]. The MTL contains a
|
||||
strided iterator, where each call to ``operator++()`` moves the
|
||||
iterator ahead by some constant factor, and a scaled iterator, which
|
||||
multiplies the dereferenced value by some constant.
|
||||
|
||||
.. [#concept] We use the term concept to mean a set of requirements
|
||||
that a type must satisfy to be used with a particular template
|
||||
parameter.
|
||||
|
||||
.. [#mutable] The term mutable iterator refers to iterators over objects that
|
||||
can be changed by assigning to the dereferenced iterator, while
|
||||
constant iterator refers to iterators over objects that cannot be
|
||||
modified.
|
||||
|
||||
To fulfill the need for constructing adaptors, we propose the
|
||||
``iterator_adaptor`` class template. Instantiations of
|
||||
``iterator_adaptor`` serve as a base classes for new iterators,
|
||||
providing the default behavior of forwarding all operations to the
|
||||
underlying iterator. The user can selectively replace these features
|
||||
in the derived iterator class. This proposal also includes a number
|
||||
of more specialized adaptors, such as the ``transform_iterator`` that
|
||||
applies some user-specified function during the dereference of the
|
||||
iterator.
|
||||
|
||||
========================
|
||||
Impact on the Standard
|
||||
========================
|
||||
|
||||
This proposal is purely an addition to the C++ standard library.
|
||||
However, note that this proposal relies on the proposal for New
|
||||
Iterator Concepts.
|
||||
|
||||
========
|
||||
Design
|
||||
========
|
||||
|
||||
Iterator Concepts
|
||||
=================
|
||||
|
||||
This proposal is formulated in terms of the new ``iterator concepts``
|
||||
as proposed in `n1477`_, since user-defined and especially adapted
|
||||
iterators suffer from the well known categorization problems that are
|
||||
inherent to the current iterator categories.
|
||||
|
||||
.. _`n1477`: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html
|
||||
|
||||
This proposal does not strictly depend on proposal `n1477`_, as there
|
||||
is a direct mapping between new and old categories. This proposal
|
||||
could be reformulated using this mapping if `n1477`_ was not accepted.
|
||||
|
||||
Interoperability
|
||||
================
|
||||
|
||||
The question of iterator interoperability is poorly addressed in the
|
||||
current standard. There are currently two defect reports that are
|
||||
concerned with interoperability issues.
|
||||
|
||||
Issue `179`_ concerns the fact that mutable container iterator types
|
||||
are only required to be convertible to the corresponding constant
|
||||
iterator types, but objects of these types are not required to
|
||||
interoperate in comparison or subtraction expressions. This situation
|
||||
is tedious in practice and out of line with the way built in types
|
||||
work. This proposal implements the proposed resolution to issue
|
||||
`179`_, as most standard library implementations do nowadays. In other
|
||||
words, if an iterator type A has an implicit or user defined
|
||||
conversion to an iterator type B, the iterator types are interoperable
|
||||
and the usual set of operators are available.
|
||||
|
||||
Issue `280`_ concerns the current lack of interoperability between
|
||||
reverse iterator types. The proposed new reverse_iterator template
|
||||
fixes the issues raised in 280. It provides the desired
|
||||
interoperability without introducing unwanted overloads.
|
||||
|
||||
.. _`179`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
|
||||
.. _`280`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
|
||||
|
||||
|
||||
Iterator Facade
|
||||
===============
|
||||
|
||||
.. include:: iterator_facade_body.rst
|
||||
|
||||
Iterator Adaptor
|
||||
================
|
||||
|
||||
.. include:: iterator_adaptor_body.rst
|
||||
|
||||
Specialized Adaptors
|
||||
====================
|
||||
|
||||
This proposal also contains several examples of specialized adaptors
|
||||
which were easily implemented using ``iterator_adaptor``:
|
||||
|
||||
* ``indirect_iterator``, which iterates over iterators, pointers,
|
||||
or smart pointers and applies an extra level of dereferencing.
|
||||
|
||||
* A new ``reverse_iterator``, which inverts the direction of a Base
|
||||
iterator's motion, while allowing adapted constant and mutable
|
||||
iterators to interact in the expected ways (unlike those in most
|
||||
implementations of C++98).
|
||||
|
||||
* ``transform_iterator``, which applies a user-defined function object
|
||||
to the underlying values when dereferenced.
|
||||
|
||||
* ``projection_iterator``, which is similar to ``transform_iterator``
|
||||
except that when dereferenced it returns a reference instead of
|
||||
a value.
|
||||
|
||||
* ``filter_iterator``, which provides a view of an iterator range in
|
||||
which some elements of the underlying range are skipped.
|
||||
|
||||
.. _counting_iterator:
|
||||
|
||||
* ``counting_iterator``, which adapts any incrementable type
|
||||
(e.g. integers, iterators) so that incrementing/decrementing the
|
||||
adapted iterator and dereferencing it produces successive values of
|
||||
the Base type.
|
||||
|
||||
* ``function_output_iterator``, which makes it easier to create custom
|
||||
output iterators.
|
||||
|
||||
Based on examples in the Boost library, users have generated many new
|
||||
adaptors, among them a permutation adaptor which applies some
|
||||
permutation to a random access iterator, and a strided adaptor, which
|
||||
adapts a random access iterator by multiplying its unit of motion by a
|
||||
constant factor. In addition, the Boost Graph Library (BGL) uses
|
||||
iterator adaptors to adapt other graph libraries, such as LEDA [10]
|
||||
and Stanford GraphBase [8], to the BGL interface (which requires C++
|
||||
Standard compliant iterators).
|
||||
|
||||
===============
|
||||
Proposed Text
|
||||
===============
|
||||
|
||||
|
||||
Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
||||
=======================================================================
|
||||
|
||||
|
||||
::
|
||||
|
||||
struct use_default;
|
||||
|
||||
struct iterator_core_access { /* implementation detail */ };
|
||||
|
||||
template <
|
||||
class Derived
|
||||
, class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference = Value&
|
||||
, class Difference = ptrdiff_t
|
||||
>
|
||||
class iterator_facade;
|
||||
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor;
|
||||
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class indirect_iterator;
|
||||
|
||||
template <class Iterator>
|
||||
class reverse_iterator;
|
||||
|
||||
template <
|
||||
class UnaryFunction
|
||||
, class Iterator
|
||||
, class Reference = use_default
|
||||
, class Value = use_default
|
||||
>
|
||||
class transform_iterator;
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator;
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
, class Category = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class counting_iterator
|
||||
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator;
|
||||
|
||||
|
||||
|
||||
Iterator facade [lib.iterator.facade]
|
||||
=====================================
|
||||
|
||||
.. include:: iterator_facade_abstract.rst
|
||||
|
||||
Class template ``iterator_facade``
|
||||
----------------------------------
|
||||
|
||||
.. include:: iterator_facade_ref.rst
|
||||
|
||||
Iterator adaptor [lib.iterator.adaptor]
|
||||
=======================================
|
||||
|
||||
.. include:: iterator_adaptor_abstract.rst
|
||||
|
||||
Class template ``iterator_adaptor``
|
||||
-----------------------------------
|
||||
|
||||
.. include:: iterator_adaptor_ref.rst
|
||||
|
||||
|
||||
Specialized adaptors [lib.iterator.special.adaptors]
|
||||
====================================================
|
||||
|
||||
.. The requirements for all of these need to be written *much* more
|
||||
formally -DWA
|
||||
|
||||
|
||||
[*Note:* The ``enable_if_convertible<X,Y>::type`` expression used in
|
||||
this section is for exposition purposes. The converting constructors
|
||||
for specialized adaptors should be only be in an overload set provided
|
||||
that an object of type ``X`` is implicitly convertible to an object of
|
||||
type ``Y``. The ``enable_if_convertible`` approach uses SFINAE to
|
||||
take the constructor out of the overload set when the types are not
|
||||
implicitly convertible.]
|
||||
|
||||
|
||||
Indirect iterator
|
||||
-----------------
|
||||
|
||||
.. include:: indirect_iterator_abstract.rst
|
||||
|
||||
Class template ``indirect_iterator``
|
||||
....................................
|
||||
|
||||
.. include:: indirect_iterator_ref.rst
|
||||
|
||||
Reverse iterator
|
||||
----------------
|
||||
|
||||
.. include:: reverse_iterator_abstract.rst
|
||||
|
||||
Class template ``reverse_iterator``
|
||||
...................................
|
||||
|
||||
.. include:: reverse_iterator_ref.rst
|
||||
|
||||
|
||||
Transform iterator
|
||||
------------------
|
||||
|
||||
.. include:: transform_iterator_abstract.rst
|
||||
|
||||
Class template ``transform_iterator``
|
||||
.....................................
|
||||
|
||||
.. include:: transform_iterator_ref.rst
|
||||
|
||||
|
||||
Filter iterator
|
||||
---------------
|
||||
|
||||
.. include:: filter_iterator_abstract.rst
|
||||
|
||||
|
||||
Class template ``filter_iterator``
|
||||
..................................
|
||||
|
||||
.. include:: filter_iterator_ref.rst
|
||||
|
||||
|
||||
Counting iterator
|
||||
-----------------
|
||||
|
||||
.. include:: counting_iterator_abstract.rst
|
||||
|
||||
Class template ``counting_iterator``
|
||||
....................................
|
||||
|
||||
.. include:: counting_iterator_ref.rst
|
||||
|
||||
|
||||
Function output iterator
|
||||
------------------------
|
||||
|
||||
.. include:: function_output_iterator_abstract.rst
|
||||
|
||||
Class template ``function_output_iterator``
|
||||
...........................................
|
||||
|
||||
.. include:: function_output_iterator_ref.rst
|
||||
|
||||
|
||||
|
||||
|
||||
..
|
||||
LocalWords: Abrahams Siek Witt istream ostream iter MTL strided interoperate
|
||||
LocalWords: CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
|
||||
LocalWords: GraphBase struct ptrdiff UnaryFunction const int typename bool pp
|
||||
LocalWords: lhs rhs SFINAE markup iff tmp OtherDerived OtherIterator DWA foo
|
||||
LocalWords: dereferenceable subobject AdaptableUnaryFunction impl pre ifdef'd
|
||||
LocalWords: OtherIncrementable Coplien
|
@ -1,196 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Filter Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="filter-iterator">
|
||||
<h1 class="title">Filter Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The filter iterator adaptor creates a view of an iterator range in
|
||||
which some elements of the range are skipped over. A predicate
|
||||
function object controls which elements are skipped. When the
|
||||
predicate is applied to an element, if it returns <tt class="literal"><span class="pre">true</span></tt> then the
|
||||
element is retained and if it returns <tt class="literal"><span class="pre">false</span></tt> then the element is
|
||||
skipped over. When skipping over elements, it is necessary for the
|
||||
filter adaptor to know when to stop so as to avoid going past the end
|
||||
of the underlying range. Therefore the constructor of the filter
|
||||
iterator takes two iterator parameters: the position for the filtered
|
||||
iterator and the end of the range.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#filter-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#filter-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, /* see details */
|
||||
>
|
||||
{
|
||||
public:
|
||||
filter_iterator();
|
||||
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
|
||||
filter_iterator(Iterator x, Iterator end = Iterator());
|
||||
template<class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
Predicate predicate() const;
|
||||
Iterator end() const;
|
||||
|
||||
private: // as-if specification
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
void satisfy_predicate()
|
||||
{
|
||||
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
Predicate m_predicate;
|
||||
Iterator m_end;
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="filter-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="filter-iterator-requirements"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></h1>
|
||||
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> parameter must be a model of Readable Iterator
|
||||
and Single Pass Iterator. The resulting <tt class="literal"><span class="pre">filter_iterator</span></tt> will be a
|
||||
model of Forward Traversal Iterator if <tt class="literal"><span class="pre">Iterator</span></tt> is, otherwise the
|
||||
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be a model of Single Pass Iterator. The
|
||||
access category of the <tt class="literal"><span class="pre">filter_iterator</span></tt> will be the most refined
|
||||
standard access category that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
||||
<!-- Thomas is going to try implementing filter_iterator so that
|
||||
it will be bidirectional if the underlying iterator is. -JGS -->
|
||||
<p>The <tt class="literal"><span class="pre">Predicate</span></tt> must be Assignable, Copy Constructible, and the
|
||||
expression <tt class="literal"><span class="pre">p(x)</span></tt> must be valid where <tt class="literal"><span class="pre">p</span></tt> is an object of type
|
||||
<tt class="literal"><span class="pre">Predicate</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of type
|
||||
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt>, and where the type of
|
||||
<tt class="literal"><span class="pre">p(x)</span></tt> must be convertible to <tt class="literal"><span class="pre">bool</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="filter-iterator-operations">
|
||||
<h1><a class="toc-backref" href="#id2" name="filter-iterator-operations"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">filter_iterator();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> and <tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose
|
||||
predicate is a default constructed <tt class="literal"><span class="pre">Predicate</span></tt> and
|
||||
whose <tt class="literal"><span class="pre">end</span></tt> is a default constructed <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">filter_iterator(Predicate</span> <span class="pre">f,</span> <span class="pre">Iterator</span> <span class="pre">x,</span> <span class="pre">Iterator</span> <span class="pre">end</span> <span class="pre">=</span> <span class="pre">Iterator());</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters according
|
||||
to predicate <tt class="literal"><span class="pre">f</span></tt> and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">filter_iterator(Iterator</span> <span class="pre">x,</span> <span class="pre">Iterator</span> <span class="pre">end</span> <span class="pre">=</span> <span class="pre">Iterator());</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> must be Default Constructible.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters
|
||||
according to a default constructed <tt class="literal"><span class="pre">Predicate</span></tt>
|
||||
and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template <class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);``
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of iterator <tt class="literal"><span class="pre">t</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Predicate</span> <span class="pre">predicate()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of the predicate object used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">end()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">The object <tt class="literal"><span class="pre">end</span></tt> used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="filter_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
+++++++++++++++++
|
||||
Filter Iterator
|
||||
+++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: filter_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: filter_iterator_ref.rst
|
@ -1,10 +0,0 @@
|
||||
The filter iterator adaptor creates a view of an iterator range in
|
||||
which some elements of the range are skipped over. A predicate
|
||||
function object controls which elements are skipped. When the
|
||||
predicate is applied to an element, if it returns ``true`` then the
|
||||
element is retained and if it returns ``false`` then the element is
|
||||
skipped over. When skipping over elements, it is necessary for the
|
||||
filter adaptor to know when to stop so as to avoid going past the end
|
||||
of the underlying range. Therefore the constructor of the filter
|
||||
iterator takes two iterator parameters: the position for the filtered
|
||||
iterator and the end of the range.
|
@ -1,108 +0,0 @@
|
||||
::
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, /* see details */
|
||||
>
|
||||
{
|
||||
public:
|
||||
filter_iterator();
|
||||
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
|
||||
filter_iterator(Iterator x, Iterator end = Iterator());
|
||||
template<class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
Predicate predicate() const;
|
||||
Iterator end() const;
|
||||
|
||||
private: // as-if specification
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
void satisfy_predicate()
|
||||
{
|
||||
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
Predicate m_predicate;
|
||||
Iterator m_end;
|
||||
};
|
||||
|
||||
|
||||
``filter_iterator`` requirements
|
||||
--------------------------------
|
||||
|
||||
The base ``Iterator`` parameter must be a model of Readable Iterator
|
||||
and Single Pass Iterator. The resulting ``filter_iterator`` will be a
|
||||
model of Forward Traversal Iterator if ``Iterator`` is, otherwise the
|
||||
``filter_iterator`` will be a model of Single Pass Iterator. The
|
||||
access category of the ``filter_iterator`` will be the most refined
|
||||
standard access category that is modeled by ``Iterator``.
|
||||
|
||||
.. Thomas is going to try implementing filter_iterator so that
|
||||
it will be bidirectional if the underlying iterator is. -JGS
|
||||
|
||||
|
||||
The ``Predicate`` must be Assignable, Copy Constructible, and the
|
||||
expression ``p(x)`` must be valid where ``p`` is an object of type
|
||||
``Predicate``, ``x`` is an object of type
|
||||
``iterator_traits<Iterator>::value_type``, and where the type of
|
||||
``p(x)`` must be convertible to ``bool``.
|
||||
|
||||
|
||||
|
||||
``filter_iterator`` operations
|
||||
------------------------------
|
||||
|
||||
``filter_iterator();``
|
||||
|
||||
:Requires: ``Predicate`` and ``Iterator`` must be Default Constructible.
|
||||
:Returns: a ``filter_iterator`` whose
|
||||
predicate is a default constructed ``Predicate`` and
|
||||
whose ``end`` is a default constructed ``Iterator``.
|
||||
|
||||
|
||||
``filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());``
|
||||
|
||||
:Returns: A ``filter_iterator`` at position ``x`` that filters according
|
||||
to predicate ``f`` and that will not increment past ``end``.
|
||||
|
||||
|
||||
``filter_iterator(Iterator x, Iterator end = Iterator());``
|
||||
|
||||
:Requires: ``Predicate`` must be Default Constructible.
|
||||
:Returns: A ``filter_iterator`` at position ``x`` that filters
|
||||
according to a default constructed ``Predicate``
|
||||
and that will not increment past ``end``.
|
||||
|
||||
|
||||
::
|
||||
|
||||
template <class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);``
|
||||
|
||||
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
|
||||
:Returns: A copy of iterator ``t``.
|
||||
|
||||
|
||||
``Predicate predicate() const;``
|
||||
|
||||
:Returns: A copy of the predicate object used to construct ``*this``.
|
||||
|
||||
|
||||
``Iterator end() const;``
|
||||
|
||||
:Returns: The object ``end`` used to construct ``*this``.
|
||||
|
@ -1,165 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Function Output Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="function-output-iterator">
|
||||
<h1 class="title">Function Output Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The function output iterator adaptor makes it easier to create custom
|
||||
output iterators. The adaptor takes a unary function and creates a
|
||||
model of Output Iterator. Each item assigned to the output iterator is
|
||||
passed as an argument to the unary function. The motivation for this
|
||||
iterator is that creating a conforming output iterator is non-trivial,
|
||||
particularly because the proper implementation usually requires a
|
||||
proxy object.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#function-output-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#function-output-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></li>
|
||||
<li><a class="reference" href="#function-output-iterator-output-proxy-operations" id="id3" name="id3"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator {
|
||||
public:
|
||||
typedef iterator_tag<
|
||||
writable_iterator_tag
|
||||
, incrementable_traversal_tag
|
||||
> iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
|
||||
|
||||
struct output_proxy {
|
||||
output_proxy(UnaryFunction& f);
|
||||
template <class T> output_proxy& operator=(const T& value);
|
||||
};
|
||||
output_proxy operator*();
|
||||
function_output_iterator& operator++();
|
||||
function_output_iterator& operator++(int);
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="function-output-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="function-output-iterator-requirements"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></h1>
|
||||
<p>The <tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and the
|
||||
expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid, where <tt class="literal"><span class="pre">f</span></tt> is an object of type
|
||||
<tt class="literal"><span class="pre">UnaryFunction</span></tt> and <tt class="literal"><span class="pre">x</span></tt> is an object of a type accepted by <tt class="literal"><span class="pre">f</span></tt>.
|
||||
The resulting <tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable
|
||||
and Incrementable Iterator concepts.</p>
|
||||
</div>
|
||||
<div class="section" id="function-output-iterator-operations">
|
||||
<h1><a class="toc-backref" href="#id2" name="function-output-iterator-operations"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">function_output_iterator(const</span> <span class="pre">UnaryFunction&</span> <span class="pre">f</span> <span class="pre">=</span> <span class="pre">UnaryFunction());</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">function_output_iterator</span></tt> with
|
||||
<tt class="literal"><span class="pre">f</span></tt> stored as a data member.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">output_proxy</span> <span class="pre">operator*();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">output_proxy</span></tt> constructed with
|
||||
a copy of the unary function <tt class="literal"><span class="pre">f</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">function_output_iterator&</span> <span class="pre">operator++();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">function_output_iterator&</span> <span class="pre">operator++(int);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="function-output-iterator-output-proxy-operations">
|
||||
<h1><a class="toc-backref" href="#id3" name="function-output-iterator-output-proxy-operations"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">output_proxy(UnaryFunction&</span> <span class="pre">f);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">output_proxy</span></tt> with <tt class="literal"><span class="pre">f</span></tt> stored as
|
||||
a data member.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span> <span class="pre">output_proxy&</span> <span class="pre">operator=(const</span> <span class="pre">T&</span> <span class="pre">value);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
m_f(value);
|
||||
return *this;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="function_output_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
++++++++++++++++++++++++++
|
||||
Function Output Iterator
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: function_output_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: function_output_iterator_ref.rst
|
@ -1,8 +0,0 @@
|
||||
The function output iterator adaptor makes it easier to create custom
|
||||
output iterators. The adaptor takes a unary function and creates a
|
||||
model of Output Iterator. Each item assigned to the output iterator is
|
||||
passed as an argument to the unary function. The motivation for this
|
||||
iterator is that creating a conforming output iterator is non-trivial,
|
||||
particularly because the proper implementation usually requires a
|
||||
proxy object.
|
||||
|
@ -1,77 +0,0 @@
|
||||
::
|
||||
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator {
|
||||
public:
|
||||
typedef iterator_tag<
|
||||
writable_iterator_tag
|
||||
, incrementable_traversal_tag
|
||||
> iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
|
||||
|
||||
struct output_proxy {
|
||||
output_proxy(UnaryFunction& f);
|
||||
template <class T> output_proxy& operator=(const T& value);
|
||||
};
|
||||
output_proxy operator*();
|
||||
function_output_iterator& operator++();
|
||||
function_output_iterator& operator++(int);
|
||||
};
|
||||
|
||||
|
||||
``function_output_iterator`` requirements
|
||||
-----------------------------------------
|
||||
|
||||
The ``UnaryFunction`` must be Assignable, Copy Constructible, and the
|
||||
expression ``f(x)`` must be valid, where ``f`` is an object of type
|
||||
``UnaryFunction`` and ``x`` is an object of a type accepted by ``f``.
|
||||
The resulting ``function_output_iterator`` is a model of the Writable
|
||||
and Incrementable Iterator concepts.
|
||||
|
||||
|
||||
``function_output_iterator`` operations
|
||||
---------------------------------------
|
||||
|
||||
``explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());``
|
||||
|
||||
:Returns: An instance of ``function_output_iterator`` with
|
||||
``f`` stored as a data member.
|
||||
|
||||
|
||||
``output_proxy operator*();``
|
||||
|
||||
:Returns: An instance of ``output_proxy`` constructed with
|
||||
a copy of the unary function ``f``.
|
||||
|
||||
|
||||
``function_output_iterator& operator++();``
|
||||
|
||||
:Returns: ``*this``
|
||||
|
||||
|
||||
``function_output_iterator& operator++(int);``
|
||||
|
||||
:Returns: ``*this``
|
||||
|
||||
|
||||
``function_output_iterator::output_proxy`` operations
|
||||
-----------------------------------------------------
|
||||
|
||||
``output_proxy(UnaryFunction& f);``
|
||||
|
||||
:Returns: An instance of ``output_proxy`` with ``f`` stored as
|
||||
a data member.
|
||||
|
||||
|
||||
``template <class T> output_proxy& operator=(const T& value);``
|
||||
|
||||
:Effects:
|
||||
::
|
||||
|
||||
m_f(value);
|
||||
return *this;
|
188
doc/index.html
188
doc/index.html
@ -1,188 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>The Boost Iterator Library Boost</title>
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="the-boost-iterator-library-logo">
|
||||
<h1 class="title">The Boost Iterator Library <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
|
||||
<hr />
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Jeremy Siek, Thomas Witt</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. All rights reserved</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body">The Boost Iterator Library contains two parts. The first
|
||||
is a system of <a class="reference" href="../../../more/generic_programming.html#concept">concepts</a> which extend the C++ standard
|
||||
iterator requirements. The second is a framework
|
||||
of components for building iterators based on these
|
||||
extended concepts and includes several useful iterator
|
||||
adaptors. The extended iterator concepts have
|
||||
been carefully designed so that new-style iterators will be
|
||||
compatible with old-style algorithms, though algorithms may
|
||||
need to be updated if they want to take full advantage of
|
||||
the new-style iterators. Several components of this
|
||||
library have been proposed for the C++ standard technical
|
||||
report. The components of the Boost Iterator Library
|
||||
replace the older Boost Iterator Adaptor Library.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents"><strong>Table of Contents</strong></a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#new-style-iterators" id="id5" name="id5">New-Style Iterators</a></li>
|
||||
<li><a class="reference" href="#iterator-facade-and-adaptor" id="id6" name="id6">Iterator Facade and Adaptor</a></li>
|
||||
<li><a class="reference" href="#specialized-adaptors" id="id7" name="id7">Specialized Adaptors</a></li>
|
||||
<li><a class="reference" href="#iterator-utilities" id="id8" name="id8">Iterator Utilities</a><ul>
|
||||
<li><a class="reference" href="#traits" id="id9" name="id9">Traits</a></li>
|
||||
<li><a class="reference" href="#testing-and-concept-checking" id="id10" name="id10">Testing and Concept Checking</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id11" name="id11">Upgrading from the old Boost Iterator Adaptor Library</a></li>
|
||||
<li><a class="reference" href="#history" id="id12" name="id12">History</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="section" id="new-style-iterators">
|
||||
<h1><a class="toc-backref" href="#id5" name="new-style-iterators">New-Style Iterators</a></h1>
|
||||
<p>The iterator categories defined in C++98 are extremely limiting
|
||||
because they bind together two orthogonal concepts: traversal and
|
||||
element access. For example, because a random access iterator is
|
||||
required to return a reference (and not a proxy) when dereferenced,
|
||||
it is impossible to capture the capabilities of
|
||||
<tt class="literal"><span class="pre">vector<bool>::iterator</span></tt> using the C++98 categories. This is the
|
||||
infamous "<tt class="literal"><span class="pre">vector<bool></span></tt> is not a container, and its iterators
|
||||
aren't random access iterators", debacle about which Herb Sutter
|
||||
wrote two papers for the standards comittee (<a class="reference" href="http://www.gotw.ca/publications/N1185.pdf">n1185</a> and <a class="reference" href="http://www.gotw.ca/publications/N1211.pdf">n1211</a>),
|
||||
and a <a class="reference" href="http://www.gotw.ca/gotw/050.htm">Guru of the Week</a>. New-style iterators go well beyond
|
||||
patching up <tt class="literal"><span class="pre">vector<bool></span></tt>, though: there are lots of other
|
||||
iterators already in use which can't be adequately represented by
|
||||
the existing concepts. For details about the new iterator
|
||||
concepts, see our</p>
|
||||
<blockquote>
|
||||
<a class="reference" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a></blockquote>
|
||||
</div>
|
||||
<div class="section" id="iterator-facade-and-adaptor">
|
||||
<h1><a class="toc-backref" href="#id6" name="iterator-facade-and-adaptor">Iterator Facade and Adaptor</a></h1>
|
||||
<p>Writing standard-conforming iterators is tricky. In order to ease the
|
||||
implementation of new iterators, the iterator library provides the
|
||||
<a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> class template, which implements many useful
|
||||
defaults and compile-time checks designed to help the author iterator
|
||||
ensure that his iterator is correct. It is common to define a new
|
||||
iterator which behaves like another iterator, but modifies some aspect
|
||||
of its behavior. For that purpose, the library supplies the
|
||||
<a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> class template, which is specially designed to
|
||||
take advantage of as much of the underlying iterator's behavior as
|
||||
possible.</p>
|
||||
<p>Both <a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> and <a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> as well as many of
|
||||
the <a class="reference" href="#specialized-adaptors">specialized adaptors</a> mentioned below have been proposed for
|
||||
standardization; see our</p>
|
||||
<blockquote>
|
||||
<a class="reference" href="facade-and-adaptor.html">Standard Proposal For Iterator Facade and Adaptor</a></blockquote>
|
||||
<p>for more details.</p>
|
||||
</div>
|
||||
<div class="section" id="specialized-adaptors">
|
||||
<h1><a class="toc-backref" href="#id7" name="specialized-adaptors">Specialized Adaptors</a></h1>
|
||||
<p>The iterator library supplies a useful suite of standard-conforming
|
||||
iterator templates based on the Boost <a class="reference" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="counting_iterator.html"><tt class="literal"><span class="pre">counting_iterator</span></tt></a>: an iterator over a sequence of consecutive values.
|
||||
Implements a "lazy sequence"</li>
|
||||
<li><a class="reference" href="filter_iterator.html"><tt class="literal"><span class="pre">filter_iterator</span></tt></a>: an iterator over the subset of elements of some
|
||||
sequence which satisfy a given predicate</li>
|
||||
<li><a class="reference" href="indirect_iterator.html"><tt class="literal"><span class="pre">indirect_iterator</span></tt></a>: an iterator over the objects <em>pointed-to</em> by the
|
||||
elements of some sequence.</li>
|
||||
<li><a class="reference" href="permutation_iterator.html"><tt class="literal"><span class="pre">permutation_iterator</span></tt></a>: an iterator over the elements of some random-access
|
||||
sequence, rearranged according to some sequence of integer indices.</li>
|
||||
<li><a class="reference" href="reverse_iterator.html"><tt class="literal"><span class="pre">reverse_iterator</span></tt></a>: an iterator which traverses the elements of some
|
||||
bidirectional sequence in reverse. Corrects many of the
|
||||
shortcomings of C++98's <tt class="literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
|
||||
<li><a class="reference" href="transform_iterator.html"><tt class="literal"><span class="pre">transform_iterator</span></tt></a>: an iterator over elements which are the result of
|
||||
applying some functional transformation to the elements of an
|
||||
underlying sequence. This component also replaces the old
|
||||
<tt class="literal"><span class="pre">projection_iterator_adaptor</span></tt>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="iterator-utilities">
|
||||
<h1><a class="toc-backref" href="#id8" name="iterator-utilities">Iterator Utilities</a></h1>
|
||||
<div class="section" id="traits">
|
||||
<h2><a class="toc-backref" href="#id9" name="traits">Traits</a></h2>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="iterator_traits.html"><tt class="literal"><span class="pre">iterator_traits.hpp</span></tt></a>: Provides <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunctions which
|
||||
retrieve an iterator's traits. Also corrects for the deficiencies
|
||||
of broken implementations of <tt class="literal"><span class="pre">std::iterator_traits</span></tt>.</li>
|
||||
<li><a class="reference" href="interoperable.html"><tt class="literal"><span class="pre">interoperable.hpp</span></tt></a>: Provides an <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunction for
|
||||
testing iterator interoperability</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="testing-and-concept-checking">
|
||||
<h2><a class="toc-backref" href="#id10" name="testing-and-concept-checking">Testing and Concept Checking</a></h2>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="iterator_archetypes.html"><tt class="literal"><span class="pre">iterator_archetypes.hpp</span></tt></a>: Add summary here</li>
|
||||
<li><a class="reference" href="iterator_concepts.html"><tt class="literal"><span class="pre">iterator_concepts.hpp</span></tt></a>: Add summary</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
|
||||
<h1><a class="toc-backref" href="#id11" name="upgrading-from-the-old-boost-iterator-adaptor-library">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
|
||||
<p>Turn your policy class into the body of the iterator</p>
|
||||
<p>Use transform_iterator with a true reference type for
|
||||
projection_iterator.</p>
|
||||
</div>
|
||||
<div class="section" id="history">
|
||||
<h1><a class="toc-backref" href="#id12" name="history">History</a></h1>
|
||||
<p>In 2000 Dave Abrahams was writing an iterator for a container of
|
||||
pointers, which would access the pointed-to elements when
|
||||
dereferenced. Naturally, being a library writer, he decided to
|
||||
generalize the idea and the Boost Iterator Adaptor library was born.
|
||||
Dave was inspired by some writings of Andrei Alexandrescu and chose a
|
||||
policy based design (though he probably didn't capture Andrei's idea
|
||||
very well - there was only one policy class for all the iterator's
|
||||
orthogonal properties). Soon Jeremy Siek realized he would need the
|
||||
library and they worked together to produce a "Boostified" version,
|
||||
which was reviewed and accepted into the library. They wrote a paper
|
||||
and made several important revisions of the code.</p>
|
||||
<p>Eventually, several shortcomings of the older library began to make
|
||||
the need for a rewrite apparent. Dave and Jeremy started working at
|
||||
the Santa Cruz C++ committee meeting in 2002, and had quickly
|
||||
generated a working prototype. Thomas Witt expressed interest and
|
||||
became the voice of compile-time checking for the project...</p>
|
||||
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
|
||||
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
|
||||
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
|
||||
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
|
||||
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
|
||||
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="index.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
226
doc/index.rst
226
doc/index.rst
@ -1,226 +0,0 @@
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
The Boost Iterator Library |(logo)|__
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
.. |(logo)| image:: ../../../c++boost.gif
|
||||
:alt: Boost
|
||||
|
||||
__ ../../../index.htm
|
||||
|
||||
|
||||
-------------------------------------
|
||||
|
||||
|
||||
:Authors: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organizations: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:Abstract: The Boost Iterator Library contains two parts. The first
|
||||
is a system of concepts_ which extend the C++ standard
|
||||
iterator requirements. The second is a framework
|
||||
of components for building iterators based on these
|
||||
extended concepts and includes several useful iterator
|
||||
adaptors. The extended iterator concepts have
|
||||
been carefully designed so that new-style iterators will be
|
||||
compatible with old-style algorithms, though algorithms may
|
||||
need to be updated if they want to take full advantage of
|
||||
the new-style iterators. Several components of this
|
||||
library have been proposed for the C++ standard technical
|
||||
report. The components of the Boost Iterator Library
|
||||
replace the older Boost Iterator Adaptor Library.
|
||||
|
||||
.. _concepts: ../../../more/generic_programming.html#concept
|
||||
|
||||
.. contents:: **Table of Contents**
|
||||
|
||||
|
||||
-------------------------------------
|
||||
|
||||
|
||||
=====================
|
||||
New-Style Iterators
|
||||
=====================
|
||||
|
||||
The iterator categories defined in C++98 are extremely limiting
|
||||
because they bind together two orthogonal concepts: traversal and
|
||||
element access. For example, because a random access iterator is
|
||||
required to return a reference (and not a proxy) when dereferenced,
|
||||
it is impossible to capture the capabilities of
|
||||
``vector<bool>::iterator`` using the C++98 categories. This is the
|
||||
infamous "``vector<bool>`` is not a container, and its iterators
|
||||
aren't random access iterators", debacle about which Herb Sutter
|
||||
wrote two papers for the standards comittee (n1185_ and n1211_),
|
||||
and a `Guru of the Week`__. New-style iterators go well beyond
|
||||
patching up ``vector<bool>``, though: there are lots of other
|
||||
iterators already in use which can't be adequately represented by
|
||||
the existing concepts. For details about the new iterator
|
||||
concepts, see our
|
||||
|
||||
.. _n1185: http://www.gotw.ca/publications/N1185.pdf
|
||||
.. _n1211: http://www.gotw.ca/publications/N1211.pdf
|
||||
__ http://www.gotw.ca/gotw/050.htm
|
||||
|
||||
|
||||
`Standard Proposal For New-Style Iterators`__
|
||||
|
||||
__ new-iter-concepts.html
|
||||
|
||||
=============================
|
||||
Iterator Facade and Adaptor
|
||||
=============================
|
||||
|
||||
Writing standard-conforming iterators is tricky. In order to ease the
|
||||
implementation of new iterators, the iterator library provides the
|
||||
|facade|_ class template, which implements many useful
|
||||
defaults and compile-time checks designed to help the author iterator
|
||||
ensure that his iterator is correct. It is common to define a new
|
||||
iterator which behaves like another iterator, but modifies some aspect
|
||||
of its behavior. For that purpose, the library supplies the
|
||||
|adaptor|_ class template, which is specially designed to
|
||||
take advantage of as much of the underlying iterator's behavior as
|
||||
possible.
|
||||
|
||||
.. |facade| replace:: ``iterator_facade``
|
||||
.. _facade: iterator_facade.html
|
||||
.. |adaptor| replace:: ``iterator_adaptor``
|
||||
.. _adaptor: iterator_adaptor.html
|
||||
|
||||
Both |facade|_ and |adaptor|_ as well as many of
|
||||
the `specialized adaptors`_ mentioned below have been proposed for
|
||||
standardization; see our
|
||||
|
||||
`Standard Proposal For Iterator Facade and Adaptor`__
|
||||
|
||||
for more details.
|
||||
|
||||
__ facade-and-adaptor.html
|
||||
|
||||
======================
|
||||
Specialized Adaptors
|
||||
======================
|
||||
|
||||
The iterator library supplies a useful suite of standard-conforming
|
||||
iterator templates based on the Boost `iterator facade and adaptor`_.
|
||||
|
||||
* |counting|_: an iterator over a sequence of consecutive values.
|
||||
Implements a "lazy sequence"
|
||||
|
||||
* |filter|_: an iterator over the subset of elements of some
|
||||
sequence which satisfy a given predicate
|
||||
|
||||
* |indirect|_: an iterator over the objects *pointed-to* by the
|
||||
elements of some sequence.
|
||||
|
||||
* |permutation|_: an iterator over the elements of some random-access
|
||||
sequence, rearranged according to some sequence of integer indices.
|
||||
|
||||
* |reverse|_: an iterator which traverses the elements of some
|
||||
bidirectional sequence in reverse. Corrects many of the
|
||||
shortcomings of C++98's ``std::reverse_iterator``.
|
||||
|
||||
* |transform|_: an iterator over elements which are the result of
|
||||
applying some functional transformation to the elements of an
|
||||
underlying sequence. This component also replaces the old
|
||||
``projection_iterator_adaptor``.
|
||||
|
||||
.. |counting| replace:: ``counting_iterator``
|
||||
.. _counting: counting_iterator.html
|
||||
|
||||
.. |filter| replace:: ``filter_iterator``
|
||||
.. _filter: filter_iterator.html
|
||||
|
||||
.. |indirect| replace:: ``indirect_iterator``
|
||||
.. _indirect: indirect_iterator.html
|
||||
|
||||
.. |permutation| replace:: ``permutation_iterator``
|
||||
.. _permutation: permutation_iterator.html
|
||||
|
||||
.. |reverse| replace:: ``reverse_iterator``
|
||||
.. _reverse: reverse_iterator.html
|
||||
|
||||
.. |transform| replace:: ``transform_iterator``
|
||||
.. _transform: transform_iterator.html
|
||||
|
||||
====================
|
||||
Iterator Utilities
|
||||
====================
|
||||
|
||||
Traits
|
||||
------
|
||||
|
||||
* |iterator_traits|_: Provides MPL_\ -compatible metafunctions which
|
||||
retrieve an iterator's traits. Also corrects for the deficiencies
|
||||
of broken implementations of ``std::iterator_traits``.
|
||||
|
||||
* |interoperable|_: Provides an MPL_\ -compatible metafunction for
|
||||
testing iterator interoperability
|
||||
|
||||
.. |iterator_traits| replace:: ``iterator_traits.hpp``
|
||||
.. _iterator_traits: iterator_traits.html
|
||||
|
||||
.. |interoperable| replace:: ``interoperable.hpp``
|
||||
.. _interoperable: interoperable.html
|
||||
|
||||
.. _MPL: ../../mpl/doc/index.html
|
||||
|
||||
Testing and Concept Checking
|
||||
----------------------------
|
||||
|
||||
* |iterator_archetypes|_: Add summary here
|
||||
|
||||
* |iterator_concepts|_: Add summary
|
||||
|
||||
.. |iterator_archetypes| replace:: ``iterator_archetypes.hpp``
|
||||
.. _iterator_archetypes: iterator_archetypes.html
|
||||
|
||||
.. |iterator_concepts| replace:: ``iterator_concepts.hpp``
|
||||
.. _iterator_concepts: iterator_concepts.html
|
||||
|
||||
|
||||
=======================================================
|
||||
Upgrading from the old Boost Iterator Adaptor Library
|
||||
=======================================================
|
||||
|
||||
Turn your policy class into the body of the iterator
|
||||
|
||||
Use transform_iterator with a true reference type for
|
||||
projection_iterator.
|
||||
|
||||
=========
|
||||
History
|
||||
=========
|
||||
|
||||
In 2000 Dave Abrahams was writing an iterator for a container of
|
||||
pointers, which would access the pointed-to elements when
|
||||
dereferenced. Naturally, being a library writer, he decided to
|
||||
generalize the idea and the Boost Iterator Adaptor library was born.
|
||||
Dave was inspired by some writings of Andrei Alexandrescu and chose a
|
||||
policy based design (though he probably didn't capture Andrei's idea
|
||||
very well - there was only one policy class for all the iterator's
|
||||
orthogonal properties). Soon Jeremy Siek realized he would need the
|
||||
library and they worked together to produce a "Boostified" version,
|
||||
which was reviewed and accepted into the library. They wrote a paper
|
||||
and made several important revisions of the code.
|
||||
|
||||
Eventually, several shortcomings of the older library began to make
|
||||
the need for a rewrite apparent. Dave and Jeremy started working at
|
||||
the Santa Cruz C++ committee meeting in 2002, and had quickly
|
||||
generated a working prototype. Thomas Witt expressed interest and
|
||||
became the voice of compile-time checking for the project...
|
||||
|
||||
..
|
||||
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
|
||||
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
|
||||
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
|
||||
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
|
||||
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
|
||||
LocalWords: TraversalTag typename lvalues DWA Hmm JGS
|
@ -1,169 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Indirect Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="indirect-iterator">
|
||||
<h1 class="title">Indirect Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The indirect iterator adapts an iterator by applying an <em>extra</em>
|
||||
dereference inside of <tt class="literal"><span class="pre">operator*()</span></tt>. For example, this iterator
|
||||
adaptor makes it possible to view a container of pointers
|
||||
(e.g. <tt class="literal"><span class="pre">list<foo*></span></tt>) as if it were a container of the pointed-to type
|
||||
(e.g. <tt class="literal"><span class="pre">list<foo></span></tt>) .</p>
|
||||
<!-- At some point we should add the capability to handle
|
||||
iterators over smart pointers, which the impl handles. -JGS -->
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#indirect-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#indirect-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class indirect_iterator
|
||||
: public iterator_adaptor</* see discussion */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
indirect_iterator();
|
||||
indirect_iterator(Iterator x);
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
private: // as-if specification
|
||||
typename indirect_iterator::reference dereference() const
|
||||
{
|
||||
return **this->base();
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="indirect-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="indirect-iterator-requirements"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></h1>
|
||||
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of the <tt class="literal"><span class="pre">Iterator</span></tt> template parameter should
|
||||
itself be dereferenceable. The return type of the <tt class="literal"><span class="pre">operator*</span></tt> for
|
||||
the <tt class="literal"><span class="pre">value_type</span></tt> must be the same type as the <tt class="literal"><span class="pre">Reference</span></tt> template
|
||||
parameter. The <tt class="literal"><span class="pre">Value</span></tt> template parameter will be the <tt class="literal"><span class="pre">value_type</span></tt>
|
||||
for the <tt class="literal"><span class="pre">indirect_iterator</span></tt>, unless <tt class="literal"><span class="pre">Value</span></tt> is const. If <tt class="literal"><span class="pre">Value</span></tt>
|
||||
is <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>, then <tt class="literal"><span class="pre">value_type</span></tt> will be <em>non-</em> <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>. The
|
||||
default for <tt class="literal"><span class="pre">Value</span></tt> is</p>
|
||||
<pre class="literal-block">
|
||||
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
|
||||
</pre>
|
||||
<p>If the default is used for <tt class="literal"><span class="pre">Value</span></tt>, then there must be a valid
|
||||
specialization of <tt class="literal"><span class="pre">iterator_traits</span></tt> for the value type of the base
|
||||
iterator.</p>
|
||||
<p>The <tt class="literal"><span class="pre">Reference</span></tt> parameter will be the <tt class="literal"><span class="pre">reference</span></tt> type of the
|
||||
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is <tt class="literal"><span class="pre">Value&</span></tt>.</p>
|
||||
<p>The <tt class="literal"><span class="pre">Category</span></tt> parameter is the <tt class="literal"><span class="pre">iterator_category</span></tt> type for the
|
||||
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is
|
||||
<tt class="literal"><span class="pre">iterator_traits<Iterator>::iterator_category</span></tt>.</p>
|
||||
<p>The indirect iterator will model the most refined standard traversal
|
||||
concept that is modeled by the <tt class="literal"><span class="pre">Iterator</span></tt> type. The indirect
|
||||
iterator will model the most refined standard access concept that is
|
||||
modeled by the value type of <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="indirect-iterator-operations">
|
||||
<h1><a class="toc-backref" href="#id2" name="indirect-iterator-operations"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">indirect_iterator();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
||||
a default constructed base object.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">indirect_iterator(Iterator</span> <span class="pre">x);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
||||
the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> subobject copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator2</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">y</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="indirect_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
+++++++++++++++++++
|
||||
Indirect Iterator
|
||||
+++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: indirect_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: indirect_iterator_ref.rst
|
@ -1,8 +0,0 @@
|
||||
The indirect iterator adapts an iterator by applying an *extra*
|
||||
dereference inside of ``operator*()``. For example, this iterator
|
||||
adaptor makes it possible to view a container of pointers
|
||||
(e.g. ``list<foo*>``) as if it were a container of the pointed-to type
|
||||
(e.g. ``list<foo>``) .
|
||||
|
||||
.. At some point we should add the capability to handle
|
||||
iterators over smart pointers, which the impl handles. -JGS
|
@ -1,96 +0,0 @@
|
||||
::
|
||||
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class indirect_iterator
|
||||
: public iterator_adaptor</* see discussion */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
indirect_iterator();
|
||||
indirect_iterator(Iterator x);
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
private: // as-if specification
|
||||
typename indirect_iterator::reference dereference() const
|
||||
{
|
||||
return **this->base();
|
||||
}
|
||||
};
|
||||
|
||||
``indirect_iterator`` requirements
|
||||
..................................
|
||||
|
||||
The ``value_type`` of the ``Iterator`` template parameter should
|
||||
itself be dereferenceable. The return type of the ``operator*`` for
|
||||
the ``value_type`` must be the same type as the ``Reference`` template
|
||||
parameter. The ``Value`` template parameter will be the ``value_type``
|
||||
for the ``indirect_iterator``, unless ``Value`` is const. If ``Value``
|
||||
is ``const X``, then ``value_type`` will be *non-* ``const X``. The
|
||||
default for ``Value`` is
|
||||
|
||||
::
|
||||
|
||||
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
|
||||
|
||||
If the default is used for ``Value``, then there must be a valid
|
||||
specialization of ``iterator_traits`` for the value type of the base
|
||||
iterator.
|
||||
|
||||
The ``Reference`` parameter will be the ``reference`` type of the
|
||||
``indirect_iterator``. The default is ``Value&``.
|
||||
|
||||
The ``Category`` parameter is the ``iterator_category`` type for the
|
||||
``indirect_iterator``. The default is
|
||||
``iterator_traits<Iterator>::iterator_category``.
|
||||
|
||||
The indirect iterator will model the most refined standard traversal
|
||||
concept that is modeled by the ``Iterator`` type. The indirect
|
||||
iterator will model the most refined standard access concept that is
|
||||
modeled by the value type of ``Iterator``.
|
||||
|
||||
|
||||
``indirect_iterator`` operations
|
||||
................................
|
||||
|
||||
``indirect_iterator();``
|
||||
|
||||
:Requires: ``Iterator`` must be Default Constructible.
|
||||
:Returns: An instance of ``indirect_iterator`` with
|
||||
a default constructed base object.
|
||||
|
||||
|
||||
``indirect_iterator(Iterator x);``
|
||||
|
||||
:Returns: An instance of ``indirect_iterator`` with
|
||||
the ``iterator_adaptor`` subobject copy constructed from ``x``.
|
||||
|
||||
::
|
||||
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
:Requires: ``Iterator2`` is implicitly convertible to ``Iterator``.
|
||||
:Returns: An instance of ``indirect_iterator`` that is a copy of ``y``.
|
||||
|
@ -1,335 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Iterator Adaptor</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="iterator-adaptor">
|
||||
<h1 class="title">Iterator Adaptor</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The <tt class="literal"><span class="pre">iterator_adaptor</span></tt> is a base class template derived from an
|
||||
instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt>. The core interface functions
|
||||
expected by <tt class="literal"><span class="pre">iterator_facade</span></tt> are implemented in terms of the
|
||||
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">Base</span></tt> template parameter. A class derived
|
||||
from <tt class="literal"><span class="pre">iterator_adaptor</span></tt> typically redefines some of the core
|
||||
interface functions to adapt the behavior of the <tt class="literal"><span class="pre">Base</span></tt> type.
|
||||
Whether the derived class models any of the standard iterator concepts
|
||||
depends on the operations supported by the <tt class="literal"><span class="pre">Base</span></tt> type and which
|
||||
core interface functions of <tt class="literal"><span class="pre">iterator_facade</span></tt> are redefined in the
|
||||
<tt class="literal"><span class="pre">Derived</span></tt> class.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id3" name="id3">Introduction</a></li>
|
||||
<li><a class="reference" href="#reference" id="id4" name="id4">Reference</a><ul>
|
||||
<li><a class="reference" href="#iterator-adaptor-requirements" id="id5" name="id5"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#iterator-adaptor-public-operations" id="id6" name="id6"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></li>
|
||||
<li><a class="reference" href="#iterator-adaptor-protected-member-functions" id="id7" name="id7"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></li>
|
||||
<li><a class="reference" href="#iterator-adaptor-private-member-functions" id="id8" name="id8"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
<h1><a class="toc-backref" href="#id3" name="introduction">Introduction</a></h1>
|
||||
<p>The <tt class="literal"><span class="pre">iterator_adaptor</span></tt> class template adapts some <tt class="literal"><span class="pre">Base</span></tt> <a class="footnote-reference" href="#base" id="id1" name="id1"><sup>1</sup></a>
|
||||
type to create a new iterator. Instantiations of <tt class="literal"><span class="pre">iterator_adaptor</span></tt>
|
||||
are derived from a corresponding instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
||||
and implement the core behaviors in terms of the <tt class="literal"><span class="pre">Base</span></tt> type. In
|
||||
essence, <tt class="literal"><span class="pre">iterator_adaptor</span></tt> merely forwards all operations to an
|
||||
instance of the <tt class="literal"><span class="pre">Base</span></tt> type, which it stores as a member.</p>
|
||||
<table class="footnote" frame="void" id="base" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id1" name="base">[1]</a></td><td>The term "Base" here does not refer to a base class and is
|
||||
not meant to imply the use of derivation. We have followed the lead
|
||||
of the standard library, which provides a base() function to access
|
||||
the underlying iterator object of a <tt class="literal"><span class="pre">reverse_iterator</span></tt> adaptor.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The user of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> creates a class derived from an
|
||||
instantiation of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> and then selectively
|
||||
redefines some of the core member functions described in the table
|
||||
above. The <tt class="literal"><span class="pre">Base</span></tt> type need not meet the full requirements for an
|
||||
iterator. It need only support the operations used by the core
|
||||
interface functions of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> that have not been
|
||||
redefined in the user's derived class.</p>
|
||||
<p>Several of the template parameters of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> default to
|
||||
<tt class="literal"><span class="pre">use_default</span></tt>. This allows the user to make use of a default
|
||||
parameter even when the user wants to specify a parameter later in the
|
||||
parameter list. Also, the defaults for the corresponding associated
|
||||
types are fairly complicated, so metaprogramming is required to
|
||||
compute them, and <tt class="literal"><span class="pre">use_default</span></tt> can help to simplify the
|
||||
implementation. Finally, <tt class="literal"><span class="pre">use_default</span></tt> is not left unspecified
|
||||
because specification helps to highlight that the <tt class="literal"><span class="pre">Reference</span></tt>
|
||||
template parameter may not always be identical to the iterator's
|
||||
<tt class="literal"><span class="pre">reference</span></tt> type, and will keep users making mistakes based on that
|
||||
assumption.</p>
|
||||
</div>
|
||||
<div class="section" id="reference">
|
||||
<h1><a class="toc-backref" href="#id4" name="reference">Reference</a></h1>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public iterator_facade<Derived, /* see <a class="reference" href=":">details</a> ...*/>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
iterator_adaptor();
|
||||
explicit iterator_adaptor(Base iter);
|
||||
Base base() const;
|
||||
protected:
|
||||
Base const& base_reference() const;
|
||||
Base& base_reference();
|
||||
private: // Core iterator interface for iterator_facade.
|
||||
typename iterator_adaptor::reference dereference() const;
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||
|
||||
void advance(typename iterator_adaptor::difference_type n);
|
||||
void increment();
|
||||
void decrement();
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
typename iterator_adaptor::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||
|
||||
private:
|
||||
Base m_iterator;
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="iterator-adaptor-requirements">
|
||||
<h2><a class="toc-backref" href="#id5" name="iterator-adaptor-requirements"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></h2>
|
||||
<p>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a derived class of
|
||||
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. The <tt class="literal"><span class="pre">Base</span></tt> type must implement the
|
||||
expressions involving <tt class="literal"><span class="pre">m_iterator</span></tt> in the specifications of those
|
||||
private member functions of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> that are not
|
||||
redefined by the <tt class="literal"><span class="pre">Derived</span></tt> class and that are needed to model the
|
||||
concept corresponding to the <tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">category</span></tt>
|
||||
typedef according to the requirements of <tt class="literal"><span class="pre">iterator_facade</span></tt>. The
|
||||
rest of the template parameters specify the types for the member
|
||||
typedefs in <tt class="literal"><span class="pre">iterator_facade</span></tt>. The following pseudo-code
|
||||
specifies the traits types for <tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</p>
|
||||
<pre class="literal-block">
|
||||
if (Value == use_default)
|
||||
value_type = iterator_traits<Base>::value_type;
|
||||
else
|
||||
value_type = remove_cv<Value>::type;
|
||||
|
||||
if (Reference == use_default) {
|
||||
if (Value == use_default)
|
||||
reference = iterator_traits<Base>::reference;
|
||||
else
|
||||
reference = Value&;
|
||||
} else
|
||||
reference = Reference;
|
||||
|
||||
if (Distance == use_default)
|
||||
difference_type = iterator_traits<Base>::difference_type;
|
||||
else
|
||||
difference_type = Distance;
|
||||
|
||||
if (Category == use_default)
|
||||
iterator_category = iterator_tag<
|
||||
access_category< Base >,
|
||||
traversal_category< Base >
|
||||
>
|
||||
else if (Category is an access tag)
|
||||
iterator_category = iterator_tag<
|
||||
Category
|
||||
...
|
||||
|
||||
else if (Category is a traversal tag)
|
||||
...
|
||||
else
|
||||
iterator_category = Category;
|
||||
// Actually the above is wrong. See the use of
|
||||
// access_category_tag and
|
||||
// new_category_to_access/iter_category_to_access.
|
||||
</pre>
|
||||
<!-- Replaced with new semantics - -thw
|
||||
if (Category == use_default)
|
||||
iterator_category = iterator_traits<Base>::iterator_category;
|
||||
else
|
||||
iterator_category = Category;
|
||||
|
||||
Fix this up!! -->
|
||||
</div>
|
||||
<div class="section" id="iterator-adaptor-public-operations">
|
||||
<h2><a class="toc-backref" href="#id6" name="iterator-adaptor-public-operations"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></h2>
|
||||
<p><tt class="literal"><span class="pre">iterator_adaptor();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body">The <tt class="literal"><span class="pre">Base</span></tt> type must be Default Constructible.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> with
|
||||
<tt class="literal"><span class="pre">m_iterator</span></tt> default constructed.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">iterator_adaptor(Base</span> <span class="pre">iter);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> with
|
||||
<tt class="literal"><span class="pre">m_iterator</span></tt> copy constructed from <tt class="literal"><span class="pre">iter</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="iterator-adaptor-protected-member-functions">
|
||||
<h2><a class="toc-backref" href="#id7" name="iterator-adaptor-protected-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></h2>
|
||||
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">const&</span> <span class="pre">base_reference()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A const reference to <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Base&</span> <span class="pre">base_reference();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A non-const reference to <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="iterator-adaptor-private-member-functions">
|
||||
<h2><a class="toc-backref" href="#id8" name="iterator-adaptor-private-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></h2>
|
||||
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">iterator_adaptor::reference</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*m_iterator</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</span> <span class="pre">==</span> <span class="pre">x.base()</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">void</span> <span class="pre">advance(typename</span> <span class="pre">iterator_adaptor::difference_type</span> <span class="pre">n);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</span> <span class="pre">+=</span> <span class="pre">n;</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">void</span> <span class="pre">increment();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">++m_iterator;</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">void</span> <span class="pre">decrement();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">--m_iterator;</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
typename iterator_adaptor::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">y.base()</span> <span class="pre">-</span> <span class="pre">m_iterator</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="iterator_adaptor.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,32 +0,0 @@
|
||||
+++++++++++++++++
|
||||
Iterator Adaptor
|
||||
+++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: iterator_adaptor_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. include:: iterator_adaptor_body.rst
|
||||
|
||||
|
||||
Reference
|
||||
=========
|
||||
|
||||
.. include:: iterator_adaptor_ref.rst
|
@ -1,10 +0,0 @@
|
||||
The ``iterator_adaptor`` is a base class template derived from an
|
||||
instantiation of ``iterator_facade``. The core interface functions
|
||||
expected by ``iterator_facade`` are implemented in terms of the
|
||||
``iterator_adaptor``\ 's ``Base`` template parameter. A class derived
|
||||
from ``iterator_adaptor`` typically redefines some of the core
|
||||
interface functions to adapt the behavior of the ``Base`` type.
|
||||
Whether the derived class models any of the standard iterator concepts
|
||||
depends on the operations supported by the ``Base`` type and which
|
||||
core interface functions of ``iterator_facade`` are redefined in the
|
||||
``Derived`` class.
|
@ -1,32 +0,0 @@
|
||||
The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_
|
||||
type to create a new iterator. Instantiations of ``iterator_adaptor``
|
||||
are derived from a corresponding instantiation of ``iterator_facade``
|
||||
and implement the core behaviors in terms of the ``Base`` type. In
|
||||
essence, ``iterator_adaptor`` merely forwards all operations to an
|
||||
instance of the ``Base`` type, which it stores as a member.
|
||||
|
||||
.. [#base] The term "Base" here does not refer to a base class and is
|
||||
not meant to imply the use of derivation. We have followed the lead
|
||||
of the standard library, which provides a base() function to access
|
||||
the underlying iterator object of a ``reverse_iterator`` adaptor.
|
||||
|
||||
The user of ``iterator_adaptor`` creates a class derived from an
|
||||
instantiation of ``iterator_adaptor`` and then selectively
|
||||
redefines some of the core member functions described in the table
|
||||
above. The ``Base`` type need not meet the full requirements for an
|
||||
iterator. It need only support the operations used by the core
|
||||
interface functions of ``iterator_adaptor`` that have not been
|
||||
redefined in the user's derived class.
|
||||
|
||||
Several of the template parameters of ``iterator_adaptor`` default to
|
||||
``use_default``. This allows the user to make use of a default
|
||||
parameter even when the user wants to specify a parameter later in the
|
||||
parameter list. Also, the defaults for the corresponding associated
|
||||
types are fairly complicated, so metaprogramming is required to
|
||||
compute them, and ``use_default`` can help to simplify the
|
||||
implementation. Finally, ``use_default`` is not left unspecified
|
||||
because specification helps to highlight that the ``Reference``
|
||||
template parameter may not always be identical to the iterator's
|
||||
``reference`` type, and will keep users making mistakes based on that
|
||||
assumption.
|
||||
|
@ -1,178 +0,0 @@
|
||||
.. parsed-literal::
|
||||
|
||||
template <
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public iterator_facade<Derived, /* see details__ ...\*/>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
iterator_adaptor();
|
||||
explicit iterator_adaptor(Base iter);
|
||||
Base base() const;
|
||||
protected:
|
||||
Base const& base_reference() const;
|
||||
Base& base_reference();
|
||||
private: // Core iterator interface for iterator_facade.
|
||||
typename iterator_adaptor::reference dereference() const;
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||
|
||||
void advance(typename iterator_adaptor::difference_type n);
|
||||
void increment();
|
||||
void decrement();
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
typename iterator_adaptor::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||
|
||||
private:
|
||||
Base m_iterator;
|
||||
};
|
||||
|
||||
__ :
|
||||
|
||||
``iterator_adaptor`` requirements
|
||||
---------------------------------
|
||||
|
||||
The ``Derived`` template parameter must be a derived class of
|
||||
``iterator_adaptor``. The ``Base`` type must implement the
|
||||
expressions involving ``m_iterator`` in the specifications of those
|
||||
private member functions of ``iterator_adaptor`` that are not
|
||||
redefined by the ``Derived`` class and that are needed to model the
|
||||
concept corresponding to the ``iterator_adaptor``\ 's ``category``
|
||||
typedef according to the requirements of ``iterator_facade``. The
|
||||
rest of the template parameters specify the types for the member
|
||||
typedefs in ``iterator_facade``. The following pseudo-code
|
||||
specifies the traits types for ``iterator_adaptor``.
|
||||
|
||||
::
|
||||
|
||||
if (Value == use_default)
|
||||
value_type = iterator_traits<Base>::value_type;
|
||||
else
|
||||
value_type = remove_cv<Value>::type;
|
||||
|
||||
if (Reference == use_default) {
|
||||
if (Value == use_default)
|
||||
reference = iterator_traits<Base>::reference;
|
||||
else
|
||||
reference = Value&;
|
||||
} else
|
||||
reference = Reference;
|
||||
|
||||
if (Distance == use_default)
|
||||
difference_type = iterator_traits<Base>::difference_type;
|
||||
else
|
||||
difference_type = Distance;
|
||||
|
||||
if (Category == use_default)
|
||||
iterator_category = iterator_tag<
|
||||
access_category< Base >,
|
||||
traversal_category< Base >
|
||||
>
|
||||
else if (Category is an access tag)
|
||||
iterator_category = iterator_tag<
|
||||
Category
|
||||
...
|
||||
|
||||
else if (Category is a traversal tag)
|
||||
...
|
||||
else
|
||||
iterator_category = Category;
|
||||
// Actually the above is wrong. See the use of
|
||||
// access_category_tag and
|
||||
// new_category_to_access/iter_category_to_access.
|
||||
|
||||
|
||||
.. Replaced with new semantics --thw
|
||||
if (Category == use_default)
|
||||
iterator_category = iterator_traits<Base>::iterator_category;
|
||||
else
|
||||
iterator_category = Category;
|
||||
|
||||
Fix this up!!
|
||||
|
||||
|
||||
``iterator_adaptor`` public operations
|
||||
--------------------------------------
|
||||
|
||||
``iterator_adaptor();``
|
||||
|
||||
:Requires: The ``Base`` type must be Default Constructible.
|
||||
:Returns: An instance of ``iterator_adaptor`` with
|
||||
``m_iterator`` default constructed.
|
||||
|
||||
|
||||
``explicit iterator_adaptor(Base iter);``
|
||||
|
||||
:Returns: An instance of ``iterator_adaptor`` with
|
||||
``m_iterator`` copy constructed from ``iter``.
|
||||
|
||||
``Base base() const;``
|
||||
|
||||
:Returns: ``m_iterator``
|
||||
|
||||
|
||||
``iterator_adaptor`` protected member functions
|
||||
-----------------------------------------------
|
||||
|
||||
``Base const& base_reference() const;``
|
||||
|
||||
:Returns: A const reference to ``m_iterator``.
|
||||
|
||||
|
||||
``Base& base_reference();``
|
||||
|
||||
:Returns: A non-const reference to ``m_iterator``.
|
||||
|
||||
|
||||
``iterator_adaptor`` private member functions
|
||||
---------------------------------------------
|
||||
|
||||
``typename iterator_adaptor::reference dereference() const;``
|
||||
|
||||
:Returns: ``*m_iterator``
|
||||
|
||||
::
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||
|
||||
:Returns: ``m_iterator == x.base()``
|
||||
|
||||
|
||||
``void advance(typename iterator_adaptor::difference_type n);``
|
||||
|
||||
:Effects: ``m_iterator += n;``
|
||||
|
||||
``void increment();``
|
||||
|
||||
:Effects: ``++m_iterator;``
|
||||
|
||||
``void decrement();``
|
||||
|
||||
:Effects: ``--m_iterator;``
|
||||
|
||||
::
|
||||
|
||||
template <
|
||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||
>
|
||||
typename iterator_adaptor::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||
|
||||
:Returns: ``y.base() - m_iterator``
|
@ -1,580 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Iterator Facade</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="iterator-facade">
|
||||
<h1 class="title">Iterator Facade</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">iterator_facade</span></tt> is a base class template that implements the
|
||||
interface of standard iterators in terms of a few core functions
|
||||
and associated types, to be supplied by a derived iterator class.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#motivation" id="id10" name="id10">Motivation</a></li>
|
||||
<li><a class="reference" href="#usage" id="id11" name="id11">Usage</a></li>
|
||||
<li><a class="reference" href="#iterator-core-access" id="id12" name="id12">Iterator Core Access</a></li>
|
||||
<li><a class="reference" href="#operator" id="id13" name="id13"><tt class="literal"><span class="pre">operator[]</span></tt></a></li>
|
||||
<li><a class="reference" href="#id3" id="id14" name="id14"><tt class="literal"><span class="pre">operator-></span></tt></a></li>
|
||||
<li><a class="reference" href="#reference" id="id15" name="id15">Reference</a><ul>
|
||||
<li><a class="reference" href="#id8" id="id16" name="id16"><tt class="literal"><span class="pre">iterator_facade</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#iterator-facade-operations" id="id17" name="id17"><tt class="literal"><span class="pre">iterator_facade</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="motivation">
|
||||
<h1><a class="toc-backref" href="#id10" name="motivation">Motivation</a></h1>
|
||||
<p>While the iterator interface is rich, there is a core subset of the
|
||||
interface that is necessary for all the functionality. We have
|
||||
identified the following core behaviors for iterators:</p>
|
||||
<ul class="simple">
|
||||
<li>dereferencing</li>
|
||||
<li>incrementing</li>
|
||||
<li>decrementing</li>
|
||||
<li>equality comparison</li>
|
||||
<li>random-access motion</li>
|
||||
<li>distance measurement</li>
|
||||
</ul>
|
||||
<p>In addition to the behaviors listed above, the core interface elements
|
||||
include the associated types exposed through iterator traits:
|
||||
<tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, <tt class="literal"><span class="pre">difference_type</span></tt>, and
|
||||
<tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
|
||||
<p>Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
||||
<a class="citation-reference" href="#cop95" id="id1" name="id1">[Cop95]</a> so that the user can specify the behavior of
|
||||
<tt class="literal"><span class="pre">iterator_facade</span></tt> in a derived class. Former designs used policy
|
||||
objects to specify the behavior. <tt class="literal"><span class="pre">iterator_facade</span></tt> does not use policy
|
||||
objects for several reasons:</p>
|
||||
<blockquote>
|
||||
<ol class="arabic simple">
|
||||
<li>the creation and eventual copying of the policy object may create
|
||||
overhead that can be avoided with the current approach.</li>
|
||||
<li>The policy object approach does not allow for custom constructors
|
||||
on the created iterator types, an essential feature if
|
||||
<tt class="literal"><span class="pre">iterator_facade</span></tt> should be used in other library
|
||||
implementations.</li>
|
||||
<li>Without the use of CRTP, the standard requirement that an
|
||||
iterator's <tt class="literal"><span class="pre">operator++</span></tt> returns the iterator type itself means
|
||||
that all iterators generated by <tt class="literal"><span class="pre">iterator_facade</span></tt> would be
|
||||
instantiations of <tt class="literal"><span class="pre">iterator_facade</span></tt>. Cumbersome type generator
|
||||
metafunctions would be needed to build new parameterized
|
||||
iterators, and a separate <tt class="literal"><span class="pre">iterator_adaptor</span></tt> layer would be
|
||||
impossible.</li>
|
||||
</ol>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h1><a class="toc-backref" href="#id11" name="usage">Usage</a></h1>
|
||||
<p>The user of <tt class="literal"><span class="pre">iterator_facade</span></tt> derives his iterator class from an
|
||||
instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt> which takes the derived iterator
|
||||
class as the first template parameter. The order of the other
|
||||
template parameters to <tt class="literal"><span class="pre">iterator_facade</span></tt> have been carefully chosen
|
||||
to take advantage of useful defaults. For example, when defining a
|
||||
constant lvalue iterator, the user can pass a const-qualified version
|
||||
of the iterator's <tt class="literal"><span class="pre">value_type</span></tt> as <tt class="literal"><span class="pre">iterator_facade</span></tt>'s <tt class="literal"><span class="pre">Value</span></tt>
|
||||
parameter and omit the <tt class="literal"><span class="pre">Reference</span></tt> parameter which follows.</p>
|
||||
<p>The derived iterator class must define member functions implementing
|
||||
the iterator's core behaviors. The following table describes
|
||||
expressions which are required to be valid depending on the category
|
||||
of the derived iterator type. These member functions are described
|
||||
briefly below and in more detail in the iterator facade
|
||||
requirements.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="44%" />
|
||||
<col width="56%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>Expression</th>
|
||||
<th>Effects</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">i.dereference()</span></tt></td>
|
||||
<td>Access the value referred to</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">i.equal(j)</span></tt></td>
|
||||
<td>Compare for equality with <tt class="literal"><span class="pre">j</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">i.increment()</span></tt></td>
|
||||
<td>Advance by one position</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">i.decrement()</span></tt></td>
|
||||
<td>Retreat by one position</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">i.advance(n)</span></tt></td>
|
||||
<td>Advance by <tt class="literal"><span class="pre">n</span></tt> positions</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">i.distance_to(j)</span></tt></td>
|
||||
<td>Measure the distance to <tt class="literal"><span class="pre">j</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
<!-- Should we add a comment that a zero overhead implementation of iterator_facade
|
||||
is possible with proper inlining? -->
|
||||
<p>In addition to implementing the core interface functions, an iterator
|
||||
derived from <tt class="literal"><span class="pre">iterator_facade</span></tt> typically defines several
|
||||
constructors. To model any of the standard iterator concepts, the
|
||||
iterator must at least have a copy constructor. Also, if the iterator
|
||||
type <tt class="literal"><span class="pre">X</span></tt> is meant to be automatically interoperate with another
|
||||
iterator type <tt class="literal"><span class="pre">Y</span></tt> (as with constant and mutable iterators) then
|
||||
there must be an implicit conversion from <tt class="literal"><span class="pre">X</span></tt> to <tt class="literal"><span class="pre">Y</span></tt> or from <tt class="literal"><span class="pre">Y</span></tt>
|
||||
to <tt class="literal"><span class="pre">X</span></tt> (but not both), typically implemented as a conversion
|
||||
constructor. Finally, if the iterator is to model Forward Traversal
|
||||
Iterator or a more-refined iterator concept, a default constructor is
|
||||
required.</p>
|
||||
</div>
|
||||
<div class="section" id="iterator-core-access">
|
||||
<h1><a class="toc-backref" href="#id12" name="iterator-core-access">Iterator Core Access</a></h1>
|
||||
<p><tt class="literal"><span class="pre">iterator_facade</span></tt> and the operator implementations need to be able
|
||||
to access the core member functions in the derived class. Making the
|
||||
core member functions public would expose an implementation detail to
|
||||
the user. The design used here ensures that implementation details do
|
||||
not appear in the public interface of the derived iterator type.</p>
|
||||
<p>Preventing direct access to the core member functions has two
|
||||
advantages. First, there is no possibility for the user to accidently
|
||||
use a member function of the iterator when a member of the value_type
|
||||
was intended. This has been an issue with smart pointer
|
||||
implementations in the past. The second and main advantage is that
|
||||
library implementers can freely exchange a hand-rolled iterator
|
||||
implementation for one based on <tt class="literal"><span class="pre">iterator_facade</span></tt> without fear of
|
||||
breaking code that was accessing the public core member functions
|
||||
directly.</p>
|
||||
<p>In a naive implementation, keeping the derived class' core member
|
||||
functions private would require it to grant friendship to
|
||||
<tt class="literal"><span class="pre">iterator_facade</span></tt> and each of the seven operators. In order to
|
||||
reduce the burden of limiting access, <tt class="literal"><span class="pre">iterator_core_access</span></tt> is
|
||||
provided, a class that acts as a gateway to the core member functions
|
||||
in the derived iterator class. The author of the derived class only
|
||||
needs to grant friendship to <tt class="literal"><span class="pre">iterator_core_access</span></tt> to make his core
|
||||
member functions available to the library.</p>
|
||||
<!-- This is no long uptodate -thw -->
|
||||
<!-- Yes it is; I made sure of it! -DWA -->
|
||||
<p><tt class="literal"><span class="pre">iterator_core_access</span></tt> will be typically implemented as an empty
|
||||
class containing only private static member functions which invoke the
|
||||
iterator core member functions. There is, however, no need to
|
||||
standardize the gateway protocol. Note that even if
|
||||
<tt class="literal"><span class="pre">iterator_core_access</span></tt> used public member functions it would not
|
||||
open a safety loophole, as every core member function preserves the
|
||||
invariants of the iterator.</p>
|
||||
</div>
|
||||
<div class="section" id="operator">
|
||||
<h1><a class="toc-backref" href="#id13" name="operator"><tt class="literal"><span class="pre">operator[]</span></tt></a></h1>
|
||||
<p>The indexing operator for a generalized iterator presents special
|
||||
challenges. A random access iterator's <tt class="literal"><span class="pre">operator[]</span></tt> is only
|
||||
required to return something convertible to its <tt class="literal"><span class="pre">value_type</span></tt>.
|
||||
Requiring that it return an lvalue would rule out currently-legal
|
||||
random-access iterators which hold the referenced value in a data
|
||||
member (e.g. <a class="reference" href="counting_iterator.html">counting_iterator</a>), because <tt class="literal"><span class="pre">*(p+n)</span></tt> is a reference
|
||||
into the temporary iterator <tt class="literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
||||
<tt class="literal"><span class="pre">operator[]</span></tt> returns.</p>
|
||||
<p>Writable iterators built with <tt class="literal"><span class="pre">iterator_facade</span></tt> implement the
|
||||
semantics required by the preferred resolution to <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
||||
adopted by proposal <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html">n1477</a>: the result of <tt class="literal"><span class="pre">p[n]</span></tt> is a proxy object
|
||||
containing a copy of <tt class="literal"><span class="pre">p+n</span></tt>, and <tt class="literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is equivalent to <tt class="literal"><span class="pre">*(p</span>
|
||||
<span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt>. This approach will work properly for any random-access
|
||||
iterator regardless of the other details of its implementation. A
|
||||
user who knows more about the implementation of her iterator is free
|
||||
to implement an <tt class="literal"><span class="pre">operator[]</span></tt> which returns an lvalue in the derived
|
||||
iterator class; it will hide the one supplied by <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
||||
from clients of her iterator.</p>
|
||||
<a class="target" id="operator-arrow" name="operator-arrow"></a></div>
|
||||
<div class="section" id="id3">
|
||||
<h1><a class="toc-backref" href="#id14" name="id3"><tt class="literal"><span class="pre">operator-></span></tt></a></h1>
|
||||
<p>The <tt class="literal"><span class="pre">reference</span></tt> type of a readable iterator (and today's input
|
||||
iterator) need not in fact be a reference, so long as it is
|
||||
convertible to the iterator's <tt class="literal"><span class="pre">value_type</span></tt>. When the <tt class="literal"><span class="pre">value_type</span></tt>
|
||||
is a class, however, it must still be possible to access members
|
||||
through <tt class="literal"><span class="pre">operator-></span></tt>. Therefore, an iterator whose <tt class="literal"><span class="pre">reference</span></tt>
|
||||
type is not in fact a reference must return a proxy containing a copy
|
||||
of the referenced value from its <tt class="literal"><span class="pre">operator-></span></tt>.</p>
|
||||
<p>The return type for <tt class="literal"><span class="pre">operator-></span></tt> and <tt class="literal"><span class="pre">operator[]</span></tt> is not
|
||||
explicitly specified. Instead it requires each <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
||||
instantiation to meet the requirements of its <tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
|
||||
<table class="citation" frame="void" id="cop95" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<col />
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id1" name="cop95">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="reference">
|
||||
<h1><a class="toc-backref" href="#id15" name="reference">Reference</a></h1>
|
||||
<pre class="literal-block">
|
||||
template <
|
||||
class Derived
|
||||
, class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference = /* see <a class="reference" href="#iterator-facade-requirements">below</a> */
|
||||
, class Difference = ptrdiff_t
|
||||
>
|
||||
class iterator_facade {
|
||||
public:
|
||||
typedef remove_cv<Value>::type value_type;
|
||||
typedef Reference reference;
|
||||
typedef /* see <a class="reference" href="#operator-arrow">description of operator-></a> */ pointer;
|
||||
typedef Difference difference_type;
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
|
||||
reference operator*() const;
|
||||
/* see <a class="reference" href="#operator-arrow">below</a> */ operator->() const;
|
||||
/* see <a class="reference" href="#brackets">below</a> */ operator[](difference_type n) const;
|
||||
Derived& operator++();
|
||||
Derived operator++(int);
|
||||
Derived& operator--();
|
||||
Derived operator--(int);
|
||||
Derived& operator+=(difference_type n);
|
||||
Derived& operator-=(difference_type n);
|
||||
Derived operator-(difference_type n) const;
|
||||
};
|
||||
|
||||
// Comparison operators
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
|
||||
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
// Iterator difference
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
// Iterator addition
|
||||
template <class Derived, class V, class AC, class TC, class R, class D>
|
||||
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
|
||||
typename Derived::difference_type n)
|
||||
</pre>
|
||||
<p>[<em>Note:</em> The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt> template used above is for exposition
|
||||
purposes. The member operators should be only be in an overload set
|
||||
provided the derived types <tt class="literal"><span class="pre">Dr1</span></tt> and <tt class="literal"><span class="pre">Dr2</span></tt> are interoperable, by
|
||||
which we mean they are convertible to each other. The
|
||||
<tt class="literal"><span class="pre">enable_if_interoperable</span></tt> approach uses SFINAE to take the operators
|
||||
out of the overload set when the types are not interoperable.]</p>
|
||||
<!-- we need a new label here because the presence of markup in the
|
||||
title prevents an automatic link from being generated -->
|
||||
<a class="target" id="iterator-facade-requirements" name="iterator-facade-requirements"></a><div class="section" id="id8">
|
||||
<h2><a class="toc-backref" href="#id16" name="id8"><tt class="literal"><span class="pre">iterator_facade</span></tt> requirements</a></h2>
|
||||
<p>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a class derived from
|
||||
<tt class="literal"><span class="pre">iterator_facade</span></tt>.</p>
|
||||
<p>The default for the <tt class="literal"><span class="pre">Reference</span></tt> parameter is <tt class="literal"><span class="pre">Value&</span></tt> if the
|
||||
access category for <tt class="literal"><span class="pre">iterator_facade</span></tt> is implicitly convertible to
|
||||
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt>, and <tt class="literal"><span class="pre">const</span> <span class="pre">Value&</span></tt> otherwise.</p>
|
||||
<p>The following table describes the other requirements on the
|
||||
<tt class="literal"><span class="pre">Derived</span></tt> parameter. Depending on the resulting iterator's
|
||||
<tt class="literal"><span class="pre">iterator_category</span></tt>, a subset of the expressions listed in the table
|
||||
are required to be valid. The operations in the first column must be
|
||||
accessible to member functions of class <tt class="literal"><span class="pre">iterator_core_access</span></tt>.</p>
|
||||
<p>In the table below, <tt class="literal"><span class="pre">X</span></tt> is the derived iterator type, <tt class="literal"><span class="pre">a</span></tt> is an
|
||||
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are objects of type <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>,
|
||||
<tt class="literal"><span class="pre">n</span></tt> is an object of <tt class="literal"><span class="pre">X::difference_type</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is a constant
|
||||
object of a single pass iterator type interoperable with X, and <tt class="literal"><span class="pre">z</span></tt>
|
||||
is a constant object of a random access traversal iterator type
|
||||
interoperable with <tt class="literal"><span class="pre">X</span></tt>.</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="19%" />
|
||||
<col width="18%" />
|
||||
<col width="36%" />
|
||||
<col width="26%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Note</th>
|
||||
<th>Required to implement
|
||||
Iterator Concept(s)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">c.dereference()</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X::reference</span></tt></td>
|
||||
<td> </td>
|
||||
<td>Readable Iterator, Writable
|
||||
Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">c.equal(b)</span></tt></td>
|
||||
<td>convertible to bool</td>
|
||||
<td>true iff <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are
|
||||
equivalent.</td>
|
||||
<td>Single Pass Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">c.equal(y)</span></tt></td>
|
||||
<td>convertible to bool</td>
|
||||
<td>true iff <tt class="literal"><span class="pre">c</span></tt> and <tt class="literal"><span class="pre">y</span></tt> refer to the
|
||||
same position. Implements <tt class="literal"><span class="pre">c</span> <span class="pre">==</span> <span class="pre">y</span></tt>
|
||||
and <tt class="literal"><span class="pre">c</span> <span class="pre">!=</span> <span class="pre">y</span></tt>.</td>
|
||||
<td>Single Pass Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a.advance(n)</span></tt></td>
|
||||
<td>unused</td>
|
||||
<td> </td>
|
||||
<td>Random Access Traversal
|
||||
Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a.increment()</span></tt></td>
|
||||
<td>unused</td>
|
||||
<td> </td>
|
||||
<td>Incrementable Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a.decrement()</span></tt></td>
|
||||
<td>unused</td>
|
||||
<td> </td>
|
||||
<td>Bidirectional Traversal
|
||||
Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">c.distance_to(b)</span></tt></td>
|
||||
<td>convertible to
|
||||
X::difference_type</td>
|
||||
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">b)</span></tt></td>
|
||||
<td>Random Access Traversal
|
||||
Iterator</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
|
||||
<td>convertible to
|
||||
X::difference_type</td>
|
||||
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">z)</span></tt>.
|
||||
Implements <tt class="literal"><span class="pre">c</span> <span class="pre">-</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre"><</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span>
|
||||
<span class="pre"><=</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre">></span> <span class="pre">z</span></tt>, and <tt class="literal"><span class="pre">c</span> <span class="pre">>=</span> <span class="pre">c</span></tt>.</td>
|
||||
<td>Random Access Traversal
|
||||
Iterator</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- We should explain more about how the
|
||||
functions in the interface of iterator_facade
|
||||
are there conditionally. -JGS -->
|
||||
</div>
|
||||
<div class="section" id="iterator-facade-operations">
|
||||
<h2><a class="toc-backref" href="#id17" name="iterator-facade-operations"><tt class="literal"><span class="pre">iterator_facade</span></tt> operations</a></h2>
|
||||
<p>The operations in this section are described in terms of operations on
|
||||
the core interface of <tt class="literal"><span class="pre">Derived</span></tt> which may be inaccessible
|
||||
(i.e. private). The implementation should access these operations
|
||||
through member functions of class <tt class="literal"><span class="pre">iterator_core_access</span></tt>.</p>
|
||||
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">static_cast<Derived</span> <span class="pre">const*>(this)->dereference()</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">operator->()</span> <span class="pre">const;</span></tt> (see <a class="reference" href="#operator-arrow">below</a>)</p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">If <tt class="literal"><span class="pre">X::reference</span></tt> is a reference type, returns an object
|
||||
of type <tt class="literal"><span class="pre">X::pointer</span></tt> equal to:</p>
|
||||
<pre class="literal-block">
|
||||
&static_cast<Derived const*>(this)->dereference()
|
||||
</pre>
|
||||
<p>Otherwise returns an object of unspecified type such that, given an
|
||||
object <tt class="literal"><span class="pre">a</span></tt> of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">a->m</span></tt> is equivalent to <tt class="literal"><span class="pre">(w</span> <span class="pre">=</span> <span class="pre">*a,</span>
|
||||
<span class="pre">w.m)</span></tt> for some temporary object <tt class="literal"><span class="pre">w</span></tt> of type <tt class="literal"><span class="pre">X::value_type</span></tt>.</p>
|
||||
<p class="last">The type <tt class="literal"><span class="pre">X::pointer</span></tt> is <tt class="literal"><span class="pre">Value*</span></tt> if the access category for
|
||||
<tt class="literal"><span class="pre">X</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">writable_iterator_tag</span></tt>, and
|
||||
<tt class="literal"><span class="pre">Value</span> <span class="pre">const*</span></tt> otherwise.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<a class="target" id="brackets" name="brackets"></a><p><em>unspecified</em> <tt class="literal"><span class="pre">operator[](difference_type</span> <span class="pre">n)</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">an object convertible to <tt class="literal"><span class="pre">X::reference</span></tt> and holding a copy
|
||||
<em>p</em> of <tt class="literal"><span class="pre">a+n</span></tt> such that, for a constant object <tt class="literal"><span class="pre">v</span></tt> of type
|
||||
<tt class="literal"><span class="pre">X::value_type</span></tt>, <tt class="literal"><span class="pre">X::reference(a[n]</span> <span class="pre">=</span> <span class="pre">v)</span></tt> is equivalent
|
||||
to <tt class="literal"><span class="pre">p</span> <span class="pre">=</span> <span class="pre">v</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived&</span> <span class="pre">operator++();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
static_cast<Derived*>(this)->increment();
|
||||
return *this;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- I realize that the committee is moving away from specifying things
|
||||
like this in terms of code, but I worried about the imprecision of
|
||||
saying that a core interface function is invoked without describing
|
||||
the downcast. An alternative to what I did would be to mention it
|
||||
above where we talk about accessibility. -->
|
||||
<p><tt class="literal"><span class="pre">Derived</span> <span class="pre">operator++(int);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
Derived tmp(static_cast<Derived const*>(this));
|
||||
++*this;
|
||||
return tmp;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived&</span> <span class="pre">operator--();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
static_cast<Derived*>(this)->decrement();
|
||||
return *this;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived</span> <span class="pre">operator--(int);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
Derived tmp(static_cast<Derived const*>(this));
|
||||
--*this;
|
||||
return tmp;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived&</span> <span class="pre">operator+=(difference_type</span> <span class="pre">n);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
static_cast<Derived*>(this)->advance(n);
|
||||
return *this;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived&</span> <span class="pre">operator-=(difference_type</span> <span class="pre">n);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
||||
static_cast<Derived*>(this)->advance(-n);
|
||||
return *this;
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">Derived</span> <span class="pre">operator-(difference_type</span> <span class="pre">n)</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Derived tmp(static_cast<Derived const*>(this));
|
||||
return tmp -= n;</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">static_cast<Derived</span> <span class="pre">const*>(this)->advance(-n);</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="iterator_facade.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,33 +0,0 @@
|
||||
++++++++++++++++
|
||||
Iterator Facade
|
||||
++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: iterator_facade_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
|
||||
Motivation
|
||||
----------
|
||||
|
||||
.. include:: iterator_facade_body.rst
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. include:: iterator_facade_ref.rst
|
@ -1,4 +0,0 @@
|
||||
``iterator_facade`` is a base class template that implements the
|
||||
interface of standard iterators in terms of a few core functions
|
||||
and associated types, to be supplied by a derived iterator class.
|
||||
|
@ -1,180 +0,0 @@
|
||||
While the iterator interface is rich, there is a core subset of the
|
||||
interface that is necessary for all the functionality. We have
|
||||
identified the following core behaviors for iterators:
|
||||
|
||||
* dereferencing
|
||||
* incrementing
|
||||
* decrementing
|
||||
* equality comparison
|
||||
* random-access motion
|
||||
* distance measurement
|
||||
|
||||
In addition to the behaviors listed above, the core interface elements
|
||||
include the associated types exposed through iterator traits:
|
||||
``value_type``, ``reference``, ``difference_type``, and
|
||||
``iterator_category``.
|
||||
|
||||
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
||||
[Cop95]_ so that the user can specify the behavior of
|
||||
``iterator_facade`` in a derived class. Former designs used policy
|
||||
objects to specify the behavior. ``iterator_facade`` does not use policy
|
||||
objects for several reasons:
|
||||
|
||||
1. the creation and eventual copying of the policy object may create
|
||||
overhead that can be avoided with the current approach.
|
||||
|
||||
2. The policy object approach does not allow for custom constructors
|
||||
on the created iterator types, an essential feature if
|
||||
``iterator_facade`` should be used in other library
|
||||
implementations.
|
||||
|
||||
3. Without the use of CRTP, the standard requirement that an
|
||||
iterator's ``operator++`` returns the iterator type itself means
|
||||
that all iterators generated by ``iterator_facade`` would be
|
||||
instantiations of ``iterator_facade``. Cumbersome type generator
|
||||
metafunctions would be needed to build new parameterized
|
||||
iterators, and a separate ``iterator_adaptor`` layer would be
|
||||
impossible.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
The user of ``iterator_facade`` derives his iterator class from an
|
||||
instantiation of ``iterator_facade`` which takes the derived iterator
|
||||
class as the first template parameter. The order of the other
|
||||
template parameters to ``iterator_facade`` have been carefully chosen
|
||||
to take advantage of useful defaults. For example, when defining a
|
||||
constant lvalue iterator, the user can pass a const-qualified version
|
||||
of the iterator's ``value_type`` as ``iterator_facade``\ 's ``Value``
|
||||
parameter and omit the ``Reference`` parameter which follows.
|
||||
|
||||
The derived iterator class must define member functions implementing
|
||||
the iterator's core behaviors. The following table describes
|
||||
expressions which are required to be valid depending on the category
|
||||
of the derived iterator type. These member functions are described
|
||||
briefly below and in more detail in the iterator facade
|
||||
requirements.
|
||||
|
||||
+------------------------+-------------------------------+
|
||||
|Expression |Effects |
|
||||
+========================+===============================+
|
||||
|``i.dereference()`` |Access the value referred to |
|
||||
+------------------------+-------------------------------+
|
||||
|``i.equal(j)`` |Compare for equality with ``j``|
|
||||
+------------------------+-------------------------------+
|
||||
|``i.increment()`` |Advance by one position |
|
||||
+------------------------+-------------------------------+
|
||||
|``i.decrement()`` |Retreat by one position |
|
||||
+------------------------+-------------------------------+
|
||||
|``i.advance(n)`` |Advance by ``n`` positions |
|
||||
+------------------------+-------------------------------+
|
||||
|``i.distance_to(j)`` |Measure the distance to ``j`` |
|
||||
+------------------------+-------------------------------+
|
||||
|
||||
.. Should we add a comment that a zero overhead implementation of iterator_facade
|
||||
is possible with proper inlining?
|
||||
|
||||
In addition to implementing the core interface functions, an iterator
|
||||
derived from ``iterator_facade`` typically defines several
|
||||
constructors. To model any of the standard iterator concepts, the
|
||||
iterator must at least have a copy constructor. Also, if the iterator
|
||||
type ``X`` is meant to be automatically interoperate with another
|
||||
iterator type ``Y`` (as with constant and mutable iterators) then
|
||||
there must be an implicit conversion from ``X`` to ``Y`` or from ``Y``
|
||||
to ``X`` (but not both), typically implemented as a conversion
|
||||
constructor. Finally, if the iterator is to model Forward Traversal
|
||||
Iterator or a more-refined iterator concept, a default constructor is
|
||||
required.
|
||||
|
||||
|
||||
|
||||
Iterator Core Access
|
||||
--------------------
|
||||
|
||||
``iterator_facade`` and the operator implementations need to be able
|
||||
to access the core member functions in the derived class. Making the
|
||||
core member functions public would expose an implementation detail to
|
||||
the user. The design used here ensures that implementation details do
|
||||
not appear in the public interface of the derived iterator type.
|
||||
|
||||
Preventing direct access to the core member functions has two
|
||||
advantages. First, there is no possibility for the user to accidently
|
||||
use a member function of the iterator when a member of the value_type
|
||||
was intended. This has been an issue with smart pointer
|
||||
implementations in the past. The second and main advantage is that
|
||||
library implementers can freely exchange a hand-rolled iterator
|
||||
implementation for one based on ``iterator_facade`` without fear of
|
||||
breaking code that was accessing the public core member functions
|
||||
directly.
|
||||
|
||||
In a naive implementation, keeping the derived class' core member
|
||||
functions private would require it to grant friendship to
|
||||
``iterator_facade`` and each of the seven operators. In order to
|
||||
reduce the burden of limiting access, ``iterator_core_access`` is
|
||||
provided, a class that acts as a gateway to the core member functions
|
||||
in the derived iterator class. The author of the derived class only
|
||||
needs to grant friendship to ``iterator_core_access`` to make his core
|
||||
member functions available to the library.
|
||||
|
||||
.. This is no long uptodate -thw
|
||||
.. Yes it is; I made sure of it! -DWA
|
||||
|
||||
``iterator_core_access`` will be typically implemented as an empty
|
||||
class containing only private static member functions which invoke the
|
||||
iterator core member functions. There is, however, no need to
|
||||
standardize the gateway protocol. Note that even if
|
||||
``iterator_core_access`` used public member functions it would not
|
||||
open a safety loophole, as every core member function preserves the
|
||||
invariants of the iterator.
|
||||
|
||||
``operator[]``
|
||||
--------------
|
||||
|
||||
The indexing operator for a generalized iterator presents special
|
||||
challenges. A random access iterator's ``operator[]`` is only
|
||||
required to return something convertible to its ``value_type``.
|
||||
Requiring that it return an lvalue would rule out currently-legal
|
||||
random-access iterators which hold the referenced value in a data
|
||||
member (e.g. `counting_iterator`__), because ``*(p+n)`` is a reference
|
||||
into the temporary iterator ``p+n``, which is destroyed when
|
||||
``operator[]`` returns.
|
||||
|
||||
__ counting_iterator.html
|
||||
|
||||
Writable iterators built with ``iterator_facade`` implement the
|
||||
semantics required by the preferred resolution to `issue 299`_ and
|
||||
adopted by proposal `n1477`_: the result of ``p[n]`` is a proxy object
|
||||
containing a copy of ``p+n``, and ``p[n] = x`` is equivalent to ``*(p
|
||||
+ n) = x``. This approach will work properly for any random-access
|
||||
iterator regardless of the other details of its implementation. A
|
||||
user who knows more about the implementation of her iterator is free
|
||||
to implement an ``operator[]`` which returns an lvalue in the derived
|
||||
iterator class; it will hide the one supplied by ``iterator_facade``
|
||||
from clients of her iterator.
|
||||
|
||||
.. _`n1477`: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html
|
||||
|
||||
.. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
|
||||
|
||||
.. _`operator arrow`:
|
||||
|
||||
|
||||
``operator->``
|
||||
--------------
|
||||
|
||||
The ``reference`` type of a readable iterator (and today's input
|
||||
iterator) need not in fact be a reference, so long as it is
|
||||
convertible to the iterator's ``value_type``. When the ``value_type``
|
||||
is a class, however, it must still be possible to access members
|
||||
through ``operator->``. Therefore, an iterator whose ``reference``
|
||||
type is not in fact a reference must return a proxy containing a copy
|
||||
of the referenced value from its ``operator->``.
|
||||
|
||||
The return type for ``operator->`` and ``operator[]`` is not
|
||||
explicitly specified. Instead it requires each ``iterator_facade``
|
||||
instantiation to meet the requirements of its ``iterator_category``.
|
||||
|
||||
|
||||
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||
Patterns, C++ Report, February 1995, pp. 24-27.
|
||||
|
@ -1,284 +0,0 @@
|
||||
.. parsed-literal::
|
||||
|
||||
template <
|
||||
class Derived
|
||||
, class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference = /* see below__ \*/
|
||||
, class Difference = ptrdiff_t
|
||||
>
|
||||
class iterator_facade {
|
||||
public:
|
||||
typedef remove_cv<Value>::type value_type;
|
||||
typedef Reference reference;
|
||||
typedef /* see `description of operator->`__ \*/ pointer;
|
||||
typedef Difference difference_type;
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
|
||||
reference operator\*() const;
|
||||
/* see below__ \*/ operator->() const;
|
||||
/* see below__ \*/ operator[](difference_type n) const;
|
||||
Derived& operator++();
|
||||
Derived operator++(int);
|
||||
Derived& operator--();
|
||||
Derived operator--(int);
|
||||
Derived& operator+=(difference_type n);
|
||||
Derived& operator-=(difference_type n);
|
||||
Derived operator-(difference_type n) const;
|
||||
};
|
||||
|
||||
// Comparison operators
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
|
||||
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
// Iterator difference
|
||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||
|
||||
// Iterator addition
|
||||
template <class Derived, class V, class AC, class TC, class R, class D>
|
||||
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
|
||||
typename Derived::difference_type n)
|
||||
|
||||
|
||||
__ `iterator facade requirements`_
|
||||
|
||||
__ `operator arrow`_
|
||||
|
||||
__ `operator arrow`_
|
||||
|
||||
__ brackets_
|
||||
|
||||
[*Note:* The ``enable_if_interoperable`` template used above is for exposition
|
||||
purposes. The member operators should be only be in an overload set
|
||||
provided the derived types ``Dr1`` and ``Dr2`` are interoperable, by
|
||||
which we mean they are convertible to each other. The
|
||||
``enable_if_interoperable`` approach uses SFINAE to take the operators
|
||||
out of the overload set when the types are not interoperable.]
|
||||
|
||||
|
||||
.. we need a new label here because the presence of markup in the
|
||||
title prevents an automatic link from being generated
|
||||
|
||||
.. _iterator facade requirements:
|
||||
|
||||
``iterator_facade`` requirements
|
||||
................................
|
||||
|
||||
The ``Derived`` template parameter must be a class derived from
|
||||
``iterator_facade``.
|
||||
|
||||
The default for the ``Reference`` parameter is ``Value&`` if the
|
||||
access category for ``iterator_facade`` is implicitly convertible to
|
||||
``writable_iterator_tag``, and ``const Value&`` otherwise.
|
||||
|
||||
The following table describes the other requirements on the
|
||||
``Derived`` parameter. Depending on the resulting iterator's
|
||||
``iterator_category``, a subset of the expressions listed in the table
|
||||
are required to be valid. The operations in the first column must be
|
||||
accessible to member functions of class ``iterator_core_access``.
|
||||
|
||||
In the table below, ``X`` is the derived iterator type, ``a`` is an
|
||||
object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
|
||||
``n`` is an object of ``X::difference_type``, ``y`` is a constant
|
||||
object of a single pass iterator type interoperable with X, and ``z``
|
||||
is a constant object of a random access traversal iterator type
|
||||
interoperable with ``X``.
|
||||
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|Expression |Return Type |Assertion/Note |Required to implement |
|
||||
| | | |Iterator Concept(s) |
|
||||
+====================+===================+=====================================+===========================+
|
||||
|``c.dereference()`` |``X::reference`` | |Readable Iterator, Writable|
|
||||
| | | |Iterator |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``c.equal(b)`` |convertible to bool|true iff ``b`` and ``c`` are |Single Pass Iterator |
|
||||
| | |equivalent. | |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``c.equal(y)`` |convertible to bool|true iff ``c`` and ``y`` refer to the|Single Pass Iterator |
|
||||
| | |same position. Implements ``c == y``| |
|
||||
| | |and ``c != y``. | |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``a.advance(n)`` |unused | |Random Access Traversal |
|
||||
| | | |Iterator |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``a.increment()`` |unused | |Incrementable Iterator |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``a.decrement()`` |unused | |Bidirectional Traversal |
|
||||
| | | |Iterator |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal |
|
||||
| |X::difference_type | |Iterator |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal |
|
||||
| |X::difference_type |Implements ``c - z``, ``c < z``, ``c |Iterator |
|
||||
| | |<= z``, ``c > z``, and ``c >= c``. | |
|
||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||
|
||||
.. We should explain more about how the
|
||||
functions in the interface of iterator_facade
|
||||
are there conditionally. -JGS
|
||||
|
||||
|
||||
``iterator_facade`` operations
|
||||
..............................
|
||||
|
||||
The operations in this section are described in terms of operations on
|
||||
the core interface of ``Derived`` which may be inaccessible
|
||||
(i.e. private). The implementation should access these operations
|
||||
through member functions of class ``iterator_core_access``.
|
||||
|
||||
``reference operator*() const;``
|
||||
|
||||
:Returns: ``static_cast<Derived const*>(this)->dereference()``
|
||||
|
||||
``operator->() const;`` (see below__)
|
||||
|
||||
__ `operator arrow`_
|
||||
|
||||
:Returns: If ``X::reference`` is a reference type, returns an object
|
||||
of type ``X::pointer`` equal to::
|
||||
|
||||
&static_cast<Derived const*>(this)->dereference()
|
||||
|
||||
Otherwise returns an object of unspecified type such that, given an
|
||||
object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
|
||||
w.m)`` for some temporary object ``w`` of type ``X::value_type``.
|
||||
|
||||
The type ``X::pointer`` is ``Value*`` if the access category for
|
||||
``X`` is implicitly convertible to ``writable_iterator_tag``, and
|
||||
``Value const*`` otherwise.
|
||||
|
||||
|
||||
.. _brackets:
|
||||
|
||||
*unspecified* ``operator[](difference_type n) const;``
|
||||
|
||||
:Returns: an object convertible to ``X::reference`` and holding a copy
|
||||
*p* of ``a+n`` such that, for a constant object ``v`` of type
|
||||
``X::value_type``, ``X::reference(a[n] = v)`` is equivalent
|
||||
to ``p = v``.
|
||||
|
||||
|
||||
|
||||
``Derived& operator++();``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
static_cast<Derived*>(this)->increment();
|
||||
return *this;
|
||||
|
||||
.. I realize that the committee is moving away from specifying things
|
||||
like this in terms of code, but I worried about the imprecision of
|
||||
saying that a core interface function is invoked without describing
|
||||
the downcast. An alternative to what I did would be to mention it
|
||||
above where we talk about accessibility.
|
||||
|
||||
|
||||
``Derived operator++(int);``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
Derived tmp(static_cast<Derived const*>(this));
|
||||
++*this;
|
||||
return tmp;
|
||||
|
||||
|
||||
``Derived& operator--();``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
static_cast<Derived*>(this)->decrement();
|
||||
return *this;
|
||||
|
||||
|
||||
``Derived operator--(int);``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
Derived tmp(static_cast<Derived const*>(this));
|
||||
--*this;
|
||||
return tmp;
|
||||
|
||||
|
||||
``Derived& operator+=(difference_type n);``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
static_cast<Derived*>(this)->advance(n);
|
||||
return *this;
|
||||
|
||||
|
||||
``Derived& operator-=(difference_type n);``
|
||||
|
||||
:Effects:
|
||||
|
||||
::
|
||||
|
||||
static_cast<Derived*>(this)->advance(-n);
|
||||
return *this;
|
||||
|
||||
|
||||
``Derived operator-(difference_type n) const;``
|
||||
|
||||
:Effects:
|
||||
|
||||
Derived tmp(static_cast<Derived const*>(this));
|
||||
return tmp -= n;
|
||||
|
||||
:Returns: ``static_cast<Derived const*>(this)->advance(-n);``
|
||||
|
||||
|
@ -1,952 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>New Iterator Concepts</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-14" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="new-iterator-concepts">
|
||||
<h1 class="title">New Iterator Concepts</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-14</td></tr>
|
||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</td>
|
||||
</tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body">We propose a new system of iterator concepts that treat
|
||||
access and positioning independently. This allows the
|
||||
concepts to more closely match the requirements
|
||||
of algorithms and provides better categorizations
|
||||
of iterators that are used in practice. This proposal
|
||||
is a revision of paper <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#motivation" id="id1" name="id1">Motivation</a></li>
|
||||
<li><a class="reference" href="#impact-on-the-standard" id="id2" name="id2">Impact on the Standard</a></li>
|
||||
<li><a class="reference" href="#design" id="id3" name="id3">Design</a></li>
|
||||
<li><a class="reference" href="#proposed-text" id="id4" name="id4">Proposed Text</a><ul>
|
||||
<li><a class="reference" href="#addition-to-lib-iterator-requirements" id="id5" name="id5">Addition to [lib.iterator.requirements]</a><ul>
|
||||
<li><a class="reference" href="#iterator-value-access-concepts-lib-iterator-value-access" id="id6" name="id6">Iterator Value Access Concepts [lib.iterator.value.access]</a><ul>
|
||||
<li><a class="reference" href="#readable-iterators-lib-readable-iterators" id="id7" name="id7">Readable Iterators [lib.readable.iterators]</a></li>
|
||||
<li><a class="reference" href="#writable-iterators-lib-writable-iterators" id="id8" name="id8">Writable Iterators [lib.writable.iterators]</a></li>
|
||||
<li><a class="reference" href="#swappable-iterators-lib-swappable-iterators" id="id9" name="id9">Swappable Iterators [lib.swappable.iterators]</a></li>
|
||||
<li><a class="reference" href="#readable-lvalue-iterators-lib-readable-lvalue-iterators" id="id10" name="id10">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></li>
|
||||
<li><a class="reference" href="#writable-lvalue-iterators-lib-writable-lvalue-iterators" id="id11" name="id11">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#iterator-traversal-concepts-lib-iterator-traversal" id="id12" name="id12">Iterator Traversal Concepts [lib.iterator.traversal]</a><ul>
|
||||
<li><a class="reference" href="#incrementable-iterators-lib-incrementable-iterators" id="id13" name="id13">Incrementable Iterators [lib.incrementable.iterators]</a></li>
|
||||
<li><a class="reference" href="#single-pass-iterators-lib-single-pass-iterators" id="id14" name="id14">Single Pass Iterators [lib.single.pass.iterators]</a></li>
|
||||
<li><a class="reference" href="#forward-traversal-iterators-lib-forward-traversal-iterators" id="id15" name="id15">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></li>
|
||||
<li><a class="reference" href="#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators" id="id16" name="id16">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></li>
|
||||
<li><a class="reference" href="#random-access-traversal-iterators-lib-random-access-traversal-iterators" id="id17" name="id17">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#addition-to-lib-iterator-synopsis" id="id18" name="id18">Addition to [lib.iterator.synopsis]</a></li>
|
||||
<li><a class="reference" href="#addition-to-lib-iterator-traits" id="id19" name="id19">Addition to [lib.iterator.traits]</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="motivation">
|
||||
<h1><a class="toc-backref" href="#id1" name="motivation">Motivation</a></h1>
|
||||
<p>The standard iterator categories and requirements are flawed because
|
||||
they use a single hierarchy of concepts to address two orthogonal
|
||||
issues: <em>iterator traversal</em> and <em>value access</em>. As a result, many
|
||||
algorithms with requirements expressed in terms of the iterator
|
||||
categories are too strict. Also, many real-world iterators can not be
|
||||
accurately categorized. A proxy-based iterator with random-access
|
||||
traversal, for example, may only legally have a category of "input
|
||||
iterator", so generic algorithms are unable to take advantage of its
|
||||
random-access capabilities. The current iterator concept hierarchy is
|
||||
geared towards iterator traversal (hence the category names), while
|
||||
requirements that address value access sneak in at various places. The
|
||||
following table gives a summary of the current value access
|
||||
requirements in the iterator categories.</p>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="31%" />
|
||||
<col width="69%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td>Output Iterator</td>
|
||||
<td><tt class="literal"><span class="pre">*i</span> <span class="pre">=</span> <span class="pre">a</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>Input Iterator</td>
|
||||
<td><tt class="literal"><span class="pre">*i</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>Forward Iterator</td>
|
||||
<td><tt class="literal"><span class="pre">*i</span></tt> is <tt class="literal"><span class="pre">T&</span></tt> (or <tt class="literal"><span class="pre">const</span> <span class="pre">T&</span></tt> once <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
|
||||
is resolved)</td>
|
||||
</tr>
|
||||
<tr><td>Random Access Iterator</td>
|
||||
<td><tt class="literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt> (also <tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
||||
is required for mutable iterators once <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
|
||||
is resolved)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Because iterator traversal and value access are mixed together in a
|
||||
single hierarchy, many useful iterators can not be appropriately
|
||||
categorized. For example, <tt class="literal"><span class="pre">vector<bool>::iterator</span></tt> is almost a
|
||||
random access iterator, but the return type is not <tt class="literal"><span class="pre">bool&</span></tt> (see
|
||||
<a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
|
||||
N1185). Therefore, the iterators of <tt class="literal"><span class="pre">vector<bool></span></tt> only meet the
|
||||
requirements of input iterator and output iterator. This is so
|
||||
nonintuitive that at least one implementation erroneously assigns
|
||||
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt> as its <tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
|
||||
<p>Another difficult-to-categorize iterator is the transform iterator, an
|
||||
adaptor which applies a unary function object to the dereferenced
|
||||
value of the some underlying iterator (see <a class="reference" href="http://www.boost.org/libs/utility/transform_iterator.htm">transform_iterator</a>).
|
||||
For unary functions such as <tt class="literal"><span class="pre">times</span></tt>, the return type of
|
||||
<tt class="literal"><span class="pre">operator*</span></tt> clearly needs to be the <tt class="literal"><span class="pre">result_type</span></tt> of the function
|
||||
object, which is typically not a reference. Because random access
|
||||
iterators are required to return lvalues from <tt class="literal"><span class="pre">operator*</span></tt>, if you
|
||||
wrap <tt class="literal"><span class="pre">int*</span></tt> with a transform iterator, you do not get a random
|
||||
access iterator as might be expected, but an input iterator.</p>
|
||||
<p>A third example is found in the vertex and edge iterators of the
|
||||
<a class="reference" href="http://www.boost.org/libs/graph/doc/table_of_contents.html">Boost Graph Library</a>. These iterators return vertex and edge
|
||||
descriptors, which are lightweight handles created on-the-fly. They
|
||||
must be returned by-value. As a result, their current standard
|
||||
iterator category is <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, which means that,
|
||||
strictly speaking, you could not use these iterators with algorithms
|
||||
like <tt class="literal"><span class="pre">min_element()</span></tt>. As a temporary solution, the concept
|
||||
<a class="reference" href="http://www.boost.org/libs/utility/MultiPassInputIterator.html">Multi-Pass Input Iterator</a> was introduced to describe the vertex and
|
||||
edge descriptors, but as the design notes for the concept suggest, a
|
||||
better solution is needed.</p>
|
||||
<p>In short, there are many useful iterators that do not fit into the
|
||||
current standard iterator categories. As a result, the following bad
|
||||
things happen:</p>
|
||||
<ul class="simple">
|
||||
<li>Iterators are often mis-categorized.</li>
|
||||
<li>Algorithm requirements are more strict than necessary, because they
|
||||
cannot separate the need for random access or bidirectional
|
||||
traversal from the need for a true reference return type.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="impact-on-the-standard">
|
||||
<h1><a class="toc-backref" href="#id2" name="impact-on-the-standard">Impact on the Standard</a></h1>
|
||||
<p>The new iterator concepts are backward-compatible with the old
|
||||
iterator requirements, and old iterators are forward-compatible with
|
||||
the new iterator concepts. That is to say, iterators that satisfy the
|
||||
old requirements also satisfy appropriate concepts in the new system,
|
||||
and iterators modeling the new concepts will automatically satisfy the
|
||||
appropriate old requirements.</p>
|
||||
<!-- I think we need to say something about the resolution to allow
|
||||
convertibility to any of the old-style tags as a TR issue (hope it
|
||||
made it). -DWA -->
|
||||
<!-- Hmm, not sure I understand. Are you talking about whether a
|
||||
standards conforming input iterator is allowed to have
|
||||
a tag that is not input_iterator_tag but that
|
||||
is convertible to input_iterator_tag? -JGS -->
|
||||
<p>The algorithms in the standard library benefit from the new iterator
|
||||
concepts because the new concepts provide a more accurate way to
|
||||
express their type requirements. The result is algorithms that are
|
||||
usable in more situations and have fewer type requirements. The
|
||||
following lists the proposed changes to the type requirements of
|
||||
algorithms.</p>
|
||||
<p>Forward Iterator -> Forward Traversal Iterator and Readable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">find_end,</span> <span class="pre">adjacent_find,</span> <span class="pre">search,</span> <span class="pre">search_n,</span> <span class="pre">rotate_copy,</span> <span class="pre">lower_bound,</span> <span class="pre">upper_bound,</span> <span class="pre">equal_range,</span> <span class="pre">binary_search,</span> <span class="pre">min_element,</span> <span class="pre">max_element</span></tt></blockquote>
|
||||
<p>Forward Iterator (1) -> Single Pass Iterator and Readable Iterator
|
||||
Forward Iterator (2) -> Forward Traversal Iterator and Readable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">find_first_of</span></tt></blockquote>
|
||||
<p>Forward Iterator -> Readable Iterator and Writable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">iter_swap</span></tt></blockquote>
|
||||
<p>Forward Iterator -> Single Pass Iterator and Writable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">fill,</span> <span class="pre">generate</span></tt></blockquote>
|
||||
<p>Forward Iterator -> Forward Traversal Iterator and Swappable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">rotate</span></tt></blockquote>
|
||||
<p>Forward Iterator (1) -> Swappable Iterator and Single Pass Iterator
|
||||
Forward Iterator (2) -> Swappable Iterator and Incrementable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">swap_ranges</span></tt></blockquote>
|
||||
<dl>
|
||||
<dt>Forward Iterator -> Forward Traversal Iterator and Readable Iterator and Writable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">remove,</span> <span class="pre">remove_if,</span> <span class="pre">unique</span></tt></dd>
|
||||
</dl>
|
||||
<p>Forward Iterator -> Single Pass Iterator and Readable Iterator and Writable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">replace,</span> <span class="pre">replace_if</span></tt></blockquote>
|
||||
<dl>
|
||||
<dt>Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">reverse</span></tt></dd>
|
||||
<dt>Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable and Swappable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">partition</span></tt></dd>
|
||||
</dl>
|
||||
<p>Bidirectional Iterator (1) -> Bidirectional Traversal Iterator and Readable Iterator,
|
||||
Bidirectional Iterator (2) -> Bidirectional Traversal Iterator and Writable Iterator</p>
|
||||
<blockquote>
|
||||
<tt class="literal"><span class="pre">copy_backwards</span></tt></blockquote>
|
||||
<dl>
|
||||
<dt>Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator and Readable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">next_permutation,</span> <span class="pre">prev_permutation</span></tt></dd>
|
||||
<dt>Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator and Writable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">stable_partition,</span> <span class="pre">inplace_merge</span></tt></dd>
|
||||
<dt>Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">reverse_copy</span></tt></dd>
|
||||
<dt>Random Access Iterator -> Random Access Traversal Iterator and Readable and Swappable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">random_shuffle,</span> <span class="pre">sort,</span> <span class="pre">stable_sort,</span> <span class="pre">partial_sort,</span> <span class="pre">nth_element,</span> <span class="pre">push_heap,</span> <span class="pre">pop_heap</span>
|
||||
<span class="pre">make_heap,</span> <span class="pre">sort_heap</span></tt></dd>
|
||||
<dt>Input Iterator (2) -> Incrementable Iterator and Readable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">equal</span></tt></dd>
|
||||
<dt>Input Iterator (2) -> Incrementable Iterator and Readable Iterator</dt>
|
||||
<dd><tt class="literal"><span class="pre">transform</span></tt></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="design">
|
||||
<h1><a class="toc-backref" href="#id3" name="design">Design</a></h1>
|
||||
<p>The iterator requirements are be separated into two hierarchies. One
|
||||
set of concepts handles the syntax and semantics of value access:</p>
|
||||
<ul class="simple">
|
||||
<li>Readable Iterator</li>
|
||||
<li>Writable Iterator</li>
|
||||
<li>Swappable Iterator</li>
|
||||
<li>Readable Lvalue Iterator</li>
|
||||
<li>Writable Lvalue Iterator</li>
|
||||
</ul>
|
||||
<p>The refinement relationships among these iterator concepts are given
|
||||
in the following diagram.</p>
|
||||
<p><img alt="access.png" src="access.png" /></p>
|
||||
<p>The access concepts describe requirements related to <tt class="literal"><span class="pre">operator*</span></tt> and
|
||||
<tt class="literal"><span class="pre">operator-></span></tt>, including the <tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, and
|
||||
<tt class="literal"><span class="pre">pointer</span></tt> associated types.</p>
|
||||
<p>The other set of concepts handles traversal:</p>
|
||||
<ul class="simple">
|
||||
<li>Incrementable Iterator</li>
|
||||
<li>Single Pass Iterator</li>
|
||||
<li>Forward Traversal Iterator</li>
|
||||
<li>Bidirectional Traversal Iterator</li>
|
||||
<li>Random Access Traversal Iterator</li>
|
||||
</ul>
|
||||
<p>The refinement relationships for the traversal concepts are in the
|
||||
following diagram.</p>
|
||||
<p><img alt="traversal.png" src="traversal.png" /></p>
|
||||
<p>In addition to the iterator movement operators, such as
|
||||
<tt class="literal"><span class="pre">operator++</span></tt>, the traversal concepts also include requirements on
|
||||
position comparison such as <tt class="literal"><span class="pre">operator==</span></tt> and <tt class="literal"><span class="pre">operator<</span></tt>. The
|
||||
reason for the fine grain slicing of the concepts into the
|
||||
Incrementable and Single Pass is to provide concepts that are exact
|
||||
matches with the original input and output iterator requirements.</p>
|
||||
<p>The relationship between the new iterator concepts and the old are
|
||||
given in the following diagram.</p>
|
||||
<p><img alt="oldeqnew.png" src="oldeqnew.png" /></p>
|
||||
<p>Like the old iterator requirements, we provide tags for purposes of
|
||||
dispatching. There are two hierarchies of tags, one for the access
|
||||
concepts and one for the traversal concepts. We provide an access
|
||||
mechanism for mapping iterator types to these new tags. Our design
|
||||
reuses <tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt> as the access
|
||||
mechanism. To enable this, a pair of access and traversal tags are
|
||||
combined into a single type using the following <cite>iterator_tag</cite> class.</p>
|
||||
<pre class="literal-block">
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag : /* appropriate old category or categories */
|
||||
{
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
</pre>
|
||||
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is derived from the appropriate
|
||||
iterator tag or tags from the old requirements based on the new-style
|
||||
tags passed as template parameters. The algorithm for determining the
|
||||
old tag or tags from the new tags picks the least-refined old concepts
|
||||
that include all of the requirements of the access and traversal
|
||||
concepts (that is, the closest fit), if any such category exists. For
|
||||
example, a the category tag for a Readable Single Pass Iterator will
|
||||
always be derived from <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, while the category tag
|
||||
for a Single Pass Iterator that is both Readable and Writable will be
|
||||
derived from both <tt class="literal"><span class="pre">input_iterator_tag</span></tt> and <tt class="literal"><span class="pre">output_iterator_tag</span></tt>.</p>
|
||||
<p>We also provide two helper classes that make it convenient to obtain
|
||||
the access and traversal tags of an iterator. These helper classes
|
||||
work both for iterators whose <tt class="literal"><span class="pre">iterator_category</span></tt> is
|
||||
<tt class="literal"><span class="pre">iterator_tag</span></tt> and also for iterators using the original iterator
|
||||
categories.</p>
|
||||
<pre class="literal-block">
|
||||
template <class Iterator> struct access_category { typedef ... type; };
|
||||
template <class Iterator> struct traversal_category { typedef ... type; };
|
||||
</pre>
|
||||
<p>The most difficult design decision concerned the <tt class="literal"><span class="pre">operator[]</span></tt>. The
|
||||
direct approach for specifying <tt class="literal"><span class="pre">operator[]</span></tt> would have a return type
|
||||
of <tt class="literal"><span class="pre">reference</span></tt>; the same as <tt class="literal"><span class="pre">operator*</span></tt>. However, going in this
|
||||
direction would mean that an iterator satisfying the old Random Access
|
||||
Iterator requirements would not necessarily be a model of Readable or
|
||||
Writable Lvalue Iterator. Instead we have chosen a design that
|
||||
matches the preferred resolution of <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="literal"><span class="pre">operator[]</span></tt> is
|
||||
only required to return something convertible to the <tt class="literal"><span class="pre">value_type</span></tt>
|
||||
(for a Readable Iterator), and is required to support assignment
|
||||
<tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
|
||||
</div>
|
||||
<div class="section" id="proposed-text">
|
||||
<h1><a class="toc-backref" href="#id4" name="proposed-text">Proposed Text</a></h1>
|
||||
<div class="section" id="addition-to-lib-iterator-requirements">
|
||||
<h2><a class="toc-backref" href="#id5" name="addition-to-lib-iterator-requirements">Addition to [lib.iterator.requirements]</a></h2>
|
||||
<div class="section" id="iterator-value-access-concepts-lib-iterator-value-access">
|
||||
<h3><a class="toc-backref" href="#id6" name="iterator-value-access-concepts-lib-iterator-value-access">Iterator Value Access Concepts [lib.iterator.value.access]</a></h3>
|
||||
<p>In the tables below, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> is a constant
|
||||
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is
|
||||
<tt class="literal"><span class="pre">std::iterator_traits<X>::value_type</span></tt>, and <tt class="literal"><span class="pre">v</span></tt> is a constant
|
||||
object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
|
||||
<a class="target" id="readable-iterator" name="readable-iterator"></a><div class="section" id="readable-iterators-lib-readable-iterators">
|
||||
<h4><a class="toc-backref" href="#id7" name="readable-iterators-lib-readable-iterators">Readable Iterators [lib.readable.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Readable Iterator</em> concept
|
||||
for the value type <tt class="literal"><span class="pre">T</span></tt> if the following expressions are valid and
|
||||
respect the stated semantics. <tt class="literal"><span class="pre">U</span></tt> is the type of any specified
|
||||
member of type <tt class="literal"><span class="pre">T</span></tt>.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="34%" />
|
||||
<col width="30%" />
|
||||
<col width="36%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Readable Iterator Requirements (in addition to CopyConstructible)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Note/Precondition/Postcondition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">T</span></tt></td>
|
||||
<td>Any non-reference, non-cv-qualified type</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">access_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">readable_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
||||
<td>pre: <tt class="literal"><span class="pre">a</span></tt> is dereferenceable. If <tt class="literal"><span class="pre">a</span> <span class="pre">==</span>
|
||||
<span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt> is equivalent to <tt class="literal"><span class="pre">*b</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a->m</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">U&</span></tt></td>
|
||||
<td>pre: <tt class="literal"><span class="pre">(*a).m</span></tt> is well-defined.
|
||||
Equivalent to <tt class="literal"><span class="pre">(*a).m</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
<a class="target" id="writable-iterator" name="writable-iterator"></a></div>
|
||||
<div class="section" id="writable-iterators-lib-writable-iterators">
|
||||
<h4><a class="toc-backref" href="#id8" name="writable-iterators-lib-writable-iterators">Writable Iterators [lib.writable.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Writable Iterator</em> concept
|
||||
if the following expressions are valid and respect the stated
|
||||
semantics. In addition, a model of <em>Writable Iterator</em> must include
|
||||
in its documentation the <em>set of value types</em> that it allows for
|
||||
output.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="42%" />
|
||||
<col width="27%" />
|
||||
<col width="31%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Writable Iterator Requirements (in addition to CopyConstructible)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Precondition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">access_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">*a</span> <span class="pre">=</span> <span class="pre">o</span></tt></td>
|
||||
<td> </td>
|
||||
<td>pre: The type of <tt class="literal"><span class="pre">o</span></tt>
|
||||
is in the set of
|
||||
value types of <tt class="literal"><span class="pre">X</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="swappable-iterators-lib-swappable-iterators">
|
||||
<h4><a class="toc-backref" href="#id9" name="swappable-iterators-lib-swappable-iterators">Swappable Iterators [lib.swappable.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Swappable Iterator</em> concept
|
||||
if the following expressions are valid and respect the stated
|
||||
semantics.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="38%" />
|
||||
<col width="14%" />
|
||||
<col width="48%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Swappable Iterator Requirements (in addition to CopyConstructible)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Postcondition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">iter_swap(a,</span> <span class="pre">b)</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">void</span></tt></td>
|
||||
<td>post: the pointed to values are exchanged</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
<dl>
|
||||
<dt>[<em>Note:</em> An iterator that is a model of the <em>Readable</em> and <em>Writable Iterator</em> concepts</dt>
|
||||
<dd>is also a model of <em>Swappable Iterator</em>. <em>--end note</em>]</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="readable-lvalue-iterators-lib-readable-lvalue-iterators">
|
||||
<h4><a class="toc-backref" href="#id10" name="readable-lvalue-iterators-lib-readable-lvalue-iterators">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></h4>
|
||||
<p>The <em>Readable Lvalue Iterator</em> concept adds the requirement that the
|
||||
<tt class="literal"><span class="pre">reference</span></tt> type be a reference to the value type of the iterator.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="35%" />
|
||||
<col width="32%" />
|
||||
<col width="34%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Readable Lvalue Iterator Requirements (in addition to Readable Iterator)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">T&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">T</span></tt> is <em>cv</em>
|
||||
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt>
|
||||
where <em>cv</em> is an optional
|
||||
cv-qualification</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">access_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">readable_lvalue_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="writable-lvalue-iterators-lib-writable-lvalue-iterators">
|
||||
<h4><a class="toc-backref" href="#id11" name="writable-lvalue-iterators-lib-writable-lvalue-iterators">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></h4>
|
||||
<p>The <em>Writable Lvalue Iterator</em> concept adds the requirement that the
|
||||
<tt class="literal"><span class="pre">reference</span></tt> type be a non-const reference to the value type of the
|
||||
iterator.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="45%" />
|
||||
<col width="55%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="2">Writable Lvalue Iterator Requirements (in addition to Readable Lvalue Iterator)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">iterator_traits<X>::value_type&</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">access_category<X>::type</span></tt></td>
|
||||
<td>Convertible to <tt class="literal"><span class="pre">writable_lvalue_iterator_tag</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="iterator-traversal-concepts-lib-iterator-traversal">
|
||||
<h3><a class="toc-backref" href="#id12" name="iterator-traversal-concepts-lib-iterator-traversal">Iterator Traversal Concepts [lib.iterator.traversal]</a></h3>
|
||||
<p>In the tables below, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> and <tt class="literal"><span class="pre">b</span></tt> are
|
||||
constant objects of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">r</span></tt> and <tt class="literal"><span class="pre">s</span></tt> are mutable objects of
|
||||
type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is <tt class="literal"><span class="pre">std::iterator_traits<X>::value_type</span></tt>, and
|
||||
<tt class="literal"><span class="pre">v</span></tt> is a constant object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
|
||||
<div class="section" id="incrementable-iterators-lib-incrementable-iterators">
|
||||
<h4><a class="toc-backref" href="#id13" name="incrementable-iterators-lib-incrementable-iterators">Incrementable Iterators [lib.incrementable.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Incrementable Iterator</em>
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="27%" />
|
||||
<col width="38%" />
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Semantics</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">&r</span> <span class="pre">==</span> <span class="pre">&++r</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">r++</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">++r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
||||
<td>Convertible to <tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="single-pass-iterators-lib-single-pass-iterators">
|
||||
<h4><a class="toc-backref" href="#id14" name="single-pass-iterators-lib-single-pass-iterators">Single Pass Iterators [lib.single.pass.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Single Pass Iterator</em>
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="33%" />
|
||||
<col width="27%" />
|
||||
<col width="39%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Semantics/Pre-/Post-condition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td>pre: <tt class="literal"><span class="pre">r</span></tt> is dereferenceable; post:
|
||||
<tt class="literal"><span class="pre">r</span></tt> is dereferenceable or <tt class="literal"><span class="pre">r</span></tt> is
|
||||
past-the-end</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">==</span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">==</span></tt> is an equivalence relation over
|
||||
its domain</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">!=</span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">==</span> <span class="pre">b)</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">single_pass_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="forward-traversal-iterators-lib-forward-traversal-iterators">
|
||||
<h4><a class="toc-backref" href="#id15" name="forward-traversal-iterators-lib-forward-traversal-iterators">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Forward Traversal Iterator</em>
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="39%" />
|
||||
<col width="37%" />
|
||||
<col width="24%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Forward Traversal Iterator Requirements (in addition to Single Pass Iterator)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Note</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">X</span> <span class="pre">u;</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">note:</span> <span class="pre">u</span> <span class="pre">may</span> <span class="pre">have</span> <span class="pre">a</span>
|
||||
<span class="pre">singular</span> <span class="pre">value.</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt> and <tt class="literal"><span class="pre">r</span></tt> is
|
||||
dereferenceable implies
|
||||
<tt class="literal"><span class="pre">++r</span> <span class="pre">==</span> <span class="pre">++s.</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::difference_type</span></tt></td>
|
||||
<td>A signed integral type representing
|
||||
the distance between iterators</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">forward_traversal_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">
|
||||
<h4><a class="toc-backref" href="#id16" name="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Bidirectional Traversal
|
||||
Iterator</em> concept if the following expressions are valid and respect
|
||||
the stated semantics.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="28%" />
|
||||
<col width="36%" />
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="3">Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Assertion/Semantics/Pre-/Post-condition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">--r</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td>pre: there exists <tt class="literal"><span class="pre">s</span></tt> such that <tt class="literal"><span class="pre">r</span>
|
||||
<span class="pre">==</span> <span class="pre">++s</span></tt>. post: <tt class="literal"><span class="pre">s</span></tt> is
|
||||
dereferenceable. <tt class="literal"><span class="pre">--(++r)</span> <span class="pre">==</span> <span class="pre">r</span></tt>.
|
||||
<tt class="literal"><span class="pre">--r</span> <span class="pre">==</span> <span class="pre">--s</span></tt> implies <tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt>. <tt class="literal"><span class="pre">&r</span>
|
||||
<span class="pre">==</span> <span class="pre">&--r</span></tt>.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">r--</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">const</span> <span class="pre">X&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">--r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">bidirectional_traversal_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="section" id="random-access-traversal-iterators-lib-random-access-traversal-iterators">
|
||||
<h4><a class="toc-backref" href="#id17" name="random-access-traversal-iterators-lib-random-access-traversal-iterators">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></h4>
|
||||
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Random Access Traversal
|
||||
Iterator</em> concept if the following expressions are valid and respect
|
||||
the stated semantics. In the table below, <tt class="literal"><span class="pre">Distance</span></tt> is
|
||||
<tt class="literal"><span class="pre">iterator_traits<X>::difference_type</span></tt> and <tt class="literal"><span class="pre">n</span></tt> represents a
|
||||
constant object of type <tt class="literal"><span class="pre">Distance</span></tt>.</p>
|
||||
<blockquote>
|
||||
<table border class="table">
|
||||
<colgroup>
|
||||
<col width="26%" />
|
||||
<col width="33%" />
|
||||
<col width="18%" />
|
||||
<col width="24%" />
|
||||
</colgroup>
|
||||
<thead valign="bottom">
|
||||
<tr><th colspan="4">Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator)</th>
|
||||
</tr>
|
||||
<tr><th>Expression</th>
|
||||
<th>Return Type</th>
|
||||
<th>Operational Semantics</th>
|
||||
<th>Assertion/Precondition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody valign="top">
|
||||
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">+=</span> <span class="pre">n</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td><pre class="first last literal-block">
|
||||
{
|
||||
Distance m = n;
|
||||
if (m >= 0)
|
||||
while (m--)
|
||||
++r;
|
||||
else
|
||||
while (m++)
|
||||
--r;
|
||||
return r;
|
||||
}
|
||||
</pre>
|
||||
</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span></tt>, <tt class="literal"><span class="pre">n</span> <span class="pre">+</span> <span class="pre">a</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
|
||||
<span class="pre">tmp</span> <span class="pre">+=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">-=</span> <span class="pre">n</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X&</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">return</span> <span class="pre">r</span> <span class="pre">+=</span> <span class="pre">-n</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">-</span> <span class="pre">n</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">X</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
|
||||
<span class="pre">tmp</span> <span class="pre">-=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">?</span>
|
||||
<span class="pre">distance(a,b)</span> <span class="pre">:</span>
|
||||
<span class="pre">-distance(b,a)</span></tt></td>
|
||||
<td>pre: there exists a value
|
||||
<tt class="literal"><span class="pre">n</span></tt> of <tt class="literal"><span class="pre">Distance</span></tt> such
|
||||
that <tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">b</span></tt>. <tt class="literal"><span class="pre">b</span> <span class="pre">==</span>
|
||||
<span class="pre">a</span> <span class="pre">+</span> <span class="pre">(b</span> <span class="pre">-</span> <span class="pre">a)</span></tt>.</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a[n]</span></tt></td>
|
||||
<td>convertible to T</td>
|
||||
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span></tt></td>
|
||||
<td>pre: a is a <a class="reference" href="#readable-iterator">readable
|
||||
iterator</a></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a[n]</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
|
||||
<td>convertible to T</td>
|
||||
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
|
||||
<td>pre: a is a <a class="reference" href="#writable-iterator">writable
|
||||
iterator</a></td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span> <span class="pre">></span> <span class="pre">0</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre"><</span></tt> is a total ordering
|
||||
relation</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">></span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">b</span> <span class="pre"><</span> <span class="pre">a</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">></span></tt> is a total ordering
|
||||
relation</td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">>=</span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre"><</span> <span class="pre">b)</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre"><=</span> <span class="pre">b</span></tt></td>
|
||||
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
||||
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">></span> <span class="pre">b)</span></tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
||||
<td>Convertible to
|
||||
<tt class="literal"><span class="pre">random_access_traversal_iterator_tag</span></tt></td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="addition-to-lib-iterator-synopsis">
|
||||
<h2><a class="toc-backref" href="#id18" name="addition-to-lib-iterator-synopsis">Addition to [lib.iterator.synopsis]</a></h2>
|
||||
<pre class="literal-block">
|
||||
// lib.iterator.traits, traits and tags
|
||||
template <class Iterator> struct access_category;
|
||||
template <class Iterator> struct traversal_category;
|
||||
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag : /* appropriate old category or categories */ {
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag { };
|
||||
struct readable_writable_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
, virtual writable_iterator_tag
|
||||
, virtual swappable_iterator_tag { };
|
||||
struct readable_lvalue_iterator_tag { };
|
||||
struct writable_lvalue_iterator_tag
|
||||
: virtual public readable_writable_iterator_tag
|
||||
, virtual public readable_lvalue_iterator_tag { };
|
||||
|
||||
struct incrementable_iterator_tag { };
|
||||
struct single_pass_iterator_tag : incrementable_iterator_tag { };
|
||||
struct forward_traversal_tag : single_pass_iterator_tag { };
|
||||
struct bidirectional_traversal_tag : forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : bidirectional_traversal_tag { };
|
||||
|
||||
struct null_category_tag { };
|
||||
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="addition-to-lib-iterator-traits">
|
||||
<h2><a class="toc-backref" href="#id19" name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
|
||||
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is an iterator category tag that
|
||||
encodes the access and traversal tags in addition to being compatible
|
||||
with the original iterator tags. The <tt class="literal"><span class="pre">iterator_tag</span></tt> class inherits
|
||||
from one of the original iterator tags according to the following
|
||||
pseudo-code.</p>
|
||||
<pre class="literal-block">
|
||||
inherit-category(access-tag, traversal-tag) =
|
||||
if (access-tag is convertible to readable_lvalue_iterator_tag) {
|
||||
if (traversal-tag is convertible to random_access_traversal_tag)
|
||||
return random_access_iterator_tag;
|
||||
else if (traversal-tag is convertible to bidirectional_traversal_tag)
|
||||
return bidirectional_iterator_tag;
|
||||
else if (traversal-tag is convertible to forward_traversal_tag)
|
||||
return forward_iterator_tag;
|
||||
else if (traversal-tag is convertible to single_pass_traversal_tag)
|
||||
if (access-tag is convertible to writable_iterator_tag)
|
||||
return input_output_iterator_tag;
|
||||
else
|
||||
return input_iterator_tag;
|
||||
else if (access-tag is convertible to writable_iterator_tag)
|
||||
return output_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
} else if (access-tag is convertible to readable_writable_iterator_tag
|
||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||
return input_output_iterator_tag;
|
||||
else if (access-tag is convertible to readable_iterator_tag
|
||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||
return input_iterator_tag;
|
||||
else if (access-tag is convertible to writable_iterator_tag
|
||||
and traversal-tag is convertible to incrementable_iterator_tag)
|
||||
return output_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
</pre>
|
||||
<p>The <tt class="literal"><span class="pre">access_category</span></tt> and <tt class="literal"><span class="pre">traversal_category</span></tt> class templates are
|
||||
traits classes. For iterators whose
|
||||
<tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt> type is <tt class="literal"><span class="pre">iterator_tag</span></tt>,
|
||||
the <tt class="literal"><span class="pre">access_category</span></tt> and <tt class="literal"><span class="pre">traversal_category</span></tt> traits access the
|
||||
<tt class="literal"><span class="pre">access</span></tt> and <tt class="literal"><span class="pre">traversal</span></tt> member types within <tt class="literal"><span class="pre">iterator_tag</span></tt>.
|
||||
For iterators whose <tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt> type
|
||||
is not <tt class="literal"><span class="pre">iterator_tag</span></tt> and instead is a tag convertible to one of the
|
||||
original tags, the appropriate traversal and access tags is deduced.
|
||||
The following pseudo-code describes the algorithm.</p>
|
||||
<pre class="literal-block">
|
||||
access-category(Iterator) =
|
||||
cat = iterator_traits<Iterator>::iterator_category;
|
||||
if (cat == iterator_tag<Access,Traversal>)
|
||||
return Access;
|
||||
else if (cat is convertible to forward_iterator_tag) {
|
||||
if (iterator_traits<Iterator>::reference is a const reference)
|
||||
return readable_lvalue_iterator_tag;
|
||||
else
|
||||
return writable_lvalue_iterator_tag;
|
||||
} else if (cat is convertible to input_iterator_tag)
|
||||
return readable_iterator_tag;
|
||||
else if (cat is convertible to output_iterator_tag)
|
||||
return writable_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
|
||||
traversal-category(Iterator) =
|
||||
cat = iterator_traits<Iterator>::iterator_category;
|
||||
if (cat == iterator_tag<Access,Traversal>)
|
||||
return Traversal;
|
||||
else if (cat is convertible to random_access_iterator_tag)
|
||||
return random_access_traversal_tag;
|
||||
else if (cat is convertible to bidirectional_iterator_tag)
|
||||
return bidirectional_traversal_tag;
|
||||
else if (cat is convertible to forward_iterator_tag)
|
||||
return forward_traversal_tag;
|
||||
else if (cat is convertible to input_iterator_tag)
|
||||
return single_pass_iterator_tag;
|
||||
else if (cat is convertible to output_iterator_tag)
|
||||
return incrementable_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
</pre>
|
||||
<p>The following specializations provide the access and traversal
|
||||
category tags for pointer types.</p>
|
||||
<pre class="literal-block">
|
||||
template <typename T>
|
||||
struct access_category<const T*>
|
||||
{
|
||||
typedef readable_lvalue_iterator_tag type;
|
||||
};
|
||||
template <typename T>
|
||||
struct access_category<T*>
|
||||
{
|
||||
typedef writable_lvalue_iterator_tag type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
</pre>
|
||||
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
|
||||
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
|
||||
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
|
||||
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
|
||||
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
|
||||
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="new-iter-concepts.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,760 +0,0 @@
|
||||
++++++++++++++++++++++
|
||||
New Iterator Concepts
|
||||
++++++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems Lab`_, University of Hanover `Institute for Transport Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:Number: **This document is a revised version of the official** N1477=03-0060
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:Abstract: We propose a new system of iterator concepts that treat
|
||||
access and positioning independently. This allows the
|
||||
concepts to more closely match the requirements
|
||||
of algorithms and provides better categorizations
|
||||
of iterators that are used in practice. This proposal
|
||||
is a revision of paper n1297_.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
|
||||
|
||||
============
|
||||
Motivation
|
||||
============
|
||||
|
||||
The standard iterator categories and requirements are flawed because
|
||||
they use a single hierarchy of concepts to address two orthogonal
|
||||
issues: *iterator traversal* and *value access*. As a result, many
|
||||
algorithms with requirements expressed in terms of the iterator
|
||||
categories are too strict. Also, many real-world iterators can not be
|
||||
accurately categorized. A proxy-based iterator with random-access
|
||||
traversal, for example, may only legally have a category of "input
|
||||
iterator", so generic algorithms are unable to take advantage of its
|
||||
random-access capabilities. The current iterator concept hierarchy is
|
||||
geared towards iterator traversal (hence the category names), while
|
||||
requirements that address value access sneak in at various places. The
|
||||
following table gives a summary of the current value access
|
||||
requirements in the iterator categories.
|
||||
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|Output Iterator |``*i = a`` |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|Input Iterator |``*i`` is convertible to ``T`` |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|Forward Iterator |``*i`` is ``T&`` (or ``const T&`` once `issue 200`_ |
|
||||
| |is resolved) |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|Random Access Iterator |``i[n]`` is convertible to ``T`` (also ``i[n] = t`` |
|
||||
| |is required for mutable iterators once `issue 299`_ |
|
||||
| |is resolved) |
|
||||
+------------------------+-----------------------------------------------------+
|
||||
|
||||
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
|
||||
.. _issue 299: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299
|
||||
|
||||
|
||||
Because iterator traversal and value access are mixed together in a
|
||||
single hierarchy, many useful iterators can not be appropriately
|
||||
categorized. For example, ``vector<bool>::iterator`` is almost a
|
||||
random access iterator, but the return type is not ``bool&`` (see
|
||||
`issue 96`_ and Herb Sutter's paper J16/99-0008 = WG21
|
||||
N1185). Therefore, the iterators of ``vector<bool>`` only meet the
|
||||
requirements of input iterator and output iterator. This is so
|
||||
nonintuitive that at least one implementation erroneously assigns
|
||||
``random_access_iterator_tag`` as its ``iterator_category``.
|
||||
|
||||
.. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96
|
||||
|
||||
Another difficult-to-categorize iterator is the transform iterator, an
|
||||
adaptor which applies a unary function object to the dereferenced
|
||||
value of the some underlying iterator (see `transform_iterator`_).
|
||||
For unary functions such as ``times``, the return type of
|
||||
``operator*`` clearly needs to be the ``result_type`` of the function
|
||||
object, which is typically not a reference. Because random access
|
||||
iterators are required to return lvalues from ``operator*``, if you
|
||||
wrap ``int*`` with a transform iterator, you do not get a random
|
||||
access iterator as might be expected, but an input iterator.
|
||||
|
||||
.. _`transform_iterator`: http://www.boost.org/libs/utility/transform_iterator.htm
|
||||
|
||||
A third example is found in the vertex and edge iterators of the
|
||||
`Boost Graph Library`_. These iterators return vertex and edge
|
||||
descriptors, which are lightweight handles created on-the-fly. They
|
||||
must be returned by-value. As a result, their current standard
|
||||
iterator category is ``input_iterator_tag``, which means that,
|
||||
strictly speaking, you could not use these iterators with algorithms
|
||||
like ``min_element()``. As a temporary solution, the concept
|
||||
`Multi-Pass Input Iterator`_ was introduced to describe the vertex and
|
||||
edge descriptors, but as the design notes for the concept suggest, a
|
||||
better solution is needed.
|
||||
|
||||
.. _Boost Graph Library: http://www.boost.org/libs/graph/doc/table_of_contents.html
|
||||
.. _Multi-Pass Input Iterator: http://www.boost.org/libs/utility/MultiPassInputIterator.html
|
||||
|
||||
In short, there are many useful iterators that do not fit into the
|
||||
current standard iterator categories. As a result, the following bad
|
||||
things happen:
|
||||
|
||||
- Iterators are often mis-categorized.
|
||||
|
||||
- Algorithm requirements are more strict than necessary, because they
|
||||
cannot separate the need for random access or bidirectional
|
||||
traversal from the need for a true reference return type.
|
||||
|
||||
|
||||
========================
|
||||
Impact on the Standard
|
||||
========================
|
||||
|
||||
The new iterator concepts are backward-compatible with the old
|
||||
iterator requirements, and old iterators are forward-compatible with
|
||||
the new iterator concepts. That is to say, iterators that satisfy the
|
||||
old requirements also satisfy appropriate concepts in the new system,
|
||||
and iterators modeling the new concepts will automatically satisfy the
|
||||
appropriate old requirements.
|
||||
|
||||
.. I think we need to say something about the resolution to allow
|
||||
convertibility to any of the old-style tags as a TR issue (hope it
|
||||
made it). -DWA
|
||||
|
||||
.. Hmm, not sure I understand. Are you talking about whether a
|
||||
standards conforming input iterator is allowed to have
|
||||
a tag that is not input_iterator_tag but that
|
||||
is convertible to input_iterator_tag? -JGS
|
||||
|
||||
The algorithms in the standard library benefit from the new iterator
|
||||
concepts because the new concepts provide a more accurate way to
|
||||
express their type requirements. The result is algorithms that are
|
||||
usable in more situations and have fewer type requirements. The
|
||||
following lists the proposed changes to the type requirements of
|
||||
algorithms.
|
||||
|
||||
Forward Iterator -> Forward Traversal Iterator and Readable Iterator
|
||||
|
||||
``find_end, adjacent_find, search, search_n, rotate_copy, lower_bound, upper_bound, equal_range, binary_search, min_element, max_element``
|
||||
|
||||
Forward Iterator (1) -> Single Pass Iterator and Readable Iterator
|
||||
Forward Iterator (2) -> Forward Traversal Iterator and Readable Iterator
|
||||
|
||||
``find_first_of``
|
||||
|
||||
Forward Iterator -> Readable Iterator and Writable Iterator
|
||||
|
||||
``iter_swap``
|
||||
|
||||
Forward Iterator -> Single Pass Iterator and Writable Iterator
|
||||
|
||||
``fill, generate``
|
||||
|
||||
Forward Iterator -> Forward Traversal Iterator and Swappable Iterator
|
||||
|
||||
``rotate``
|
||||
|
||||
Forward Iterator (1) -> Swappable Iterator and Single Pass Iterator
|
||||
Forward Iterator (2) -> Swappable Iterator and Incrementable Iterator
|
||||
|
||||
``swap_ranges``
|
||||
|
||||
Forward Iterator -> Forward Traversal Iterator and Readable Iterator and Writable Iterator
|
||||
``remove, remove_if, unique``
|
||||
|
||||
Forward Iterator -> Single Pass Iterator and Readable Iterator and Writable Iterator
|
||||
|
||||
``replace, replace_if``
|
||||
|
||||
Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator
|
||||
``reverse``
|
||||
|
||||
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable and Swappable Iterator
|
||||
``partition``
|
||||
|
||||
Bidirectional Iterator (1) -> Bidirectional Traversal Iterator and Readable Iterator,
|
||||
Bidirectional Iterator (2) -> Bidirectional Traversal Iterator and Writable Iterator
|
||||
|
||||
``copy_backwards``
|
||||
|
||||
Bidirectional Iterator -> Bidirectional Traversal Iterator and Swappable Iterator and Readable Iterator
|
||||
``next_permutation, prev_permutation``
|
||||
|
||||
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator and Writable Iterator
|
||||
``stable_partition, inplace_merge``
|
||||
|
||||
Bidirectional Iterator -> Bidirectional Traversal Iterator and Readable Iterator
|
||||
``reverse_copy``
|
||||
|
||||
Random Access Iterator -> Random Access Traversal Iterator and Readable and Swappable Iterator
|
||||
``random_shuffle, sort, stable_sort, partial_sort, nth_element, push_heap, pop_heap
|
||||
make_heap, sort_heap``
|
||||
|
||||
Input Iterator (2) -> Incrementable Iterator and Readable Iterator
|
||||
``equal``
|
||||
|
||||
Input Iterator (2) -> Incrementable Iterator and Readable Iterator
|
||||
``transform``
|
||||
|
||||
========
|
||||
Design
|
||||
========
|
||||
|
||||
The iterator requirements are be separated into two hierarchies. One
|
||||
set of concepts handles the syntax and semantics of value access:
|
||||
|
||||
- Readable Iterator
|
||||
- Writable Iterator
|
||||
- Swappable Iterator
|
||||
- Readable Lvalue Iterator
|
||||
- Writable Lvalue Iterator
|
||||
|
||||
The refinement relationships among these iterator concepts are given
|
||||
in the following diagram.
|
||||
|
||||
.. image:: access.png
|
||||
|
||||
The access concepts describe requirements related to ``operator*`` and
|
||||
``operator->``, including the ``value_type``, ``reference``, and
|
||||
``pointer`` associated types.
|
||||
|
||||
The other set of concepts handles traversal:
|
||||
|
||||
- Incrementable Iterator
|
||||
- Single Pass Iterator
|
||||
- Forward Traversal Iterator
|
||||
- Bidirectional Traversal Iterator
|
||||
- Random Access Traversal Iterator
|
||||
|
||||
The refinement relationships for the traversal concepts are in the
|
||||
following diagram.
|
||||
|
||||
.. image:: traversal.png
|
||||
|
||||
In addition to the iterator movement operators, such as
|
||||
``operator++``, the traversal concepts also include requirements on
|
||||
position comparison such as ``operator==`` and ``operator<``. The
|
||||
reason for the fine grain slicing of the concepts into the
|
||||
Incrementable and Single Pass is to provide concepts that are exact
|
||||
matches with the original input and output iterator requirements.
|
||||
|
||||
The relationship between the new iterator concepts and the old are
|
||||
given in the following diagram.
|
||||
|
||||
.. image:: oldeqnew.png
|
||||
|
||||
Like the old iterator requirements, we provide tags for purposes of
|
||||
dispatching. There are two hierarchies of tags, one for the access
|
||||
concepts and one for the traversal concepts. We provide an access
|
||||
mechanism for mapping iterator types to these new tags. Our design
|
||||
reuses ``iterator_traits<Iter>::iterator_category`` as the access
|
||||
mechanism. To enable this, a pair of access and traversal tags are
|
||||
combined into a single type using the following `iterator_tag` class.
|
||||
|
||||
::
|
||||
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag : /* appropriate old category or categories */
|
||||
{
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
|
||||
The ``iterator_tag`` class template is derived from the appropriate
|
||||
iterator tag or tags from the old requirements based on the new-style
|
||||
tags passed as template parameters. The algorithm for determining the
|
||||
old tag or tags from the new tags picks the least-refined old concepts
|
||||
that include all of the requirements of the access and traversal
|
||||
concepts (that is, the closest fit), if any such category exists. For
|
||||
example, a the category tag for a Readable Single Pass Iterator will
|
||||
always be derived from ``input_iterator_tag``, while the category tag
|
||||
for a Single Pass Iterator that is both Readable and Writable will be
|
||||
derived from both ``input_iterator_tag`` and ``output_iterator_tag``.
|
||||
|
||||
We also provide two helper classes that make it convenient to obtain
|
||||
the access and traversal tags of an iterator. These helper classes
|
||||
work both for iterators whose ``iterator_category`` is
|
||||
``iterator_tag`` and also for iterators using the original iterator
|
||||
categories.
|
||||
|
||||
::
|
||||
|
||||
template <class Iterator> struct access_category { typedef ... type; };
|
||||
template <class Iterator> struct traversal_category { typedef ... type; };
|
||||
|
||||
|
||||
The most difficult design decision concerned the ``operator[]``. The
|
||||
direct approach for specifying ``operator[]`` would have a return type
|
||||
of ``reference``; the same as ``operator*``. However, going in this
|
||||
direction would mean that an iterator satisfying the old Random Access
|
||||
Iterator requirements would not necessarily be a model of Readable or
|
||||
Writable Lvalue Iterator. Instead we have chosen a design that
|
||||
matches the preferred resolution of `issue 299`_: ``operator[]`` is
|
||||
only required to return something convertible to the ``value_type``
|
||||
(for a Readable Iterator), and is required to support assignment
|
||||
``i[n] = t`` (for a Writable Iterator).
|
||||
|
||||
|
||||
===============
|
||||
Proposed Text
|
||||
===============
|
||||
|
||||
Addition to [lib.iterator.requirements]
|
||||
=======================================
|
||||
|
||||
Iterator Value Access Concepts [lib.iterator.value.access]
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
In the tables below, ``X`` is an iterator type, ``a`` is a constant
|
||||
object of type ``X``, ``T`` is
|
||||
``std::iterator_traits<X>::value_type``, and ``v`` is a constant
|
||||
object of type ``T``.
|
||||
|
||||
.. _Readable Iterator:
|
||||
|
||||
Readable Iterators [lib.readable.iterators]
|
||||
-------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Readable Iterator* concept
|
||||
for the value type ``T`` if the following expressions are valid and
|
||||
respect the stated semantics. ``U`` is the type of any specified
|
||||
member of type ``T``.
|
||||
|
||||
+-------------------------------------------------------------------------------------------------------------------+
|
||||
|Readable Iterator Requirements (in addition to CopyConstructible) |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|Expression |Return Type |Assertion/Note/Precondition/Postcondition|
|
||||
+======================================+==================================+=========================================+
|
||||
|``iterator_traits<X>::value_type`` |``T`` |Any non-reference, non-cv-qualified type |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|``iterator_traits<X>::reference`` |Convertible to | |
|
||||
| |``iterator_traits<X>::value_type``| |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|``access_category<X>::type`` |Convertible to | |
|
||||
| |``readable_iterator_tag`` | |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|``*a`` |``iterator_traits<X>::reference`` |pre: ``a`` is dereferenceable. If ``a == |
|
||||
| | |b`` then ``*a`` is equivalent to ``*b`` |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|``a->m`` |``U&`` |pre: ``(*a).m`` is well-defined. |
|
||||
| | |Equivalent to ``(*a).m`` |
|
||||
+--------------------------------------+----------------------------------+-----------------------------------------+
|
||||
|
||||
|
||||
.. _Writable Iterator:
|
||||
|
||||
Writable Iterators [lib.writable.iterators]
|
||||
-------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Writable Iterator* concept
|
||||
if the following expressions are valid and respect the stated
|
||||
semantics. In addition, a model of *Writable Iterator* must include
|
||||
in its documentation the *set of value types* that it allows for
|
||||
output.
|
||||
|
||||
+---------------------------------------------------------------------------------------------+
|
||||
|Writable Iterator Requirements (in addition to CopyConstructible) |
|
||||
+--------------------------------------+-------------------------+----------------------------+
|
||||
|Expression |Return Type |Precondition |
|
||||
+======================================+=========================+============================+
|
||||
|``access_category<X>::type`` |Convertible to | |
|
||||
| |``writable_iterator_tag``| |
|
||||
+--------------------------------------+-------------------------+----------------------------+
|
||||
|``*a = o`` | | pre: The type of ``o`` |
|
||||
| | | is in the set of |
|
||||
| | | value types of ``X`` |
|
||||
+--------------------------------------+-------------------------+----------------------------+
|
||||
|
||||
|
||||
|
||||
Swappable Iterators [lib.swappable.iterators]
|
||||
---------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Swappable Iterator* concept
|
||||
if the following expressions are valid and respect the stated
|
||||
semantics.
|
||||
|
||||
+------------------------------------------------------------------------------------------------+
|
||||
|Swappable Iterator Requirements (in addition to CopyConstructible) |
|
||||
+------------------------------------+-------------+---------------------------------------------+
|
||||
|Expression |Return Type |Postcondition |
|
||||
+====================================+=============+=============================================+
|
||||
|``iter_swap(a, b)`` |``void`` |post: the pointed to values are exchanged |
|
||||
+------------------------------------+-------------+---------------------------------------------+
|
||||
|
||||
[*Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
|
||||
is also a model of *Swappable Iterator*. *--end note*]
|
||||
|
||||
|
||||
Readable Lvalue Iterators [lib.readable.lvalue.iterators]
|
||||
---------------------------------------------------------
|
||||
|
||||
The *Readable Lvalue Iterator* concept adds the requirement that the
|
||||
``reference`` type be a reference to the value type of the iterator.
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------+
|
||||
|Readable Lvalue Iterator Requirements (in addition to Readable Iterator) |
|
||||
+------------------------------------+---------------------------------+-----------------------------------+
|
||||
|Expression |Return Type |Assertion |
|
||||
+====================================+=================================+===================================+
|
||||
|``iterator_traits<X>::reference`` |``T&`` |``T`` is *cv* |
|
||||
| | |``iterator_traits<X>::value_type`` |
|
||||
| | |where *cv* is an optional |
|
||||
| | |cv-qualification |
|
||||
+------------------------------------+---------------------------------+-----------------------------------+
|
||||
|``access_category<X>::type`` |Convertible to | |
|
||||
| |``readable_lvalue_iterator_tag`` | |
|
||||
+------------------------------------+---------------------------------+-----------------------------------+
|
||||
|
||||
|
||||
Writable Lvalue Iterators [lib.writable.lvalue.iterators]
|
||||
---------------------------------------------------------
|
||||
|
||||
The *Writable Lvalue Iterator* concept adds the requirement that the
|
||||
``reference`` type be a non-const reference to the value type of the
|
||||
iterator.
|
||||
|
||||
|
||||
+--------------------------------------------------------------------------------------+
|
||||
| Writable Lvalue Iterator Requirements (in addition to Readable Lvalue Iterator) |
|
||||
+--------------------------------------+-----------------------------------------------+
|
||||
| Expression | Return Type |
|
||||
+======================================+===============================================+
|
||||
|``iterator_traits<X>::reference`` |``iterator_traits<X>::value_type&`` |
|
||||
+--------------------------------------+-----------------------------------------------+
|
||||
|``access_category<X>::type`` |Convertible to ``writable_lvalue_iterator_tag``|
|
||||
| | |
|
||||
+--------------------------------------+-----------------------------------------------+
|
||||
|
||||
|
||||
Iterator Traversal Concepts [lib.iterator.traversal]
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
In the tables below, ``X`` is an iterator type, ``a`` and ``b`` are
|
||||
constant objects of type ``X``, ``r`` and ``s`` are mutable objects of
|
||||
type ``X``, ``T`` is ``std::iterator_traits<X>::value_type``, and
|
||||
``v`` is a constant object of type ``T``.
|
||||
|
||||
|
||||
Incrementable Iterators [lib.incrementable.iterators]
|
||||
-----------------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Incrementable Iterator*
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.
|
||||
|
||||
|
||||
+-------------------------------------------------------------------------------------------------------------------------+
|
||||
|Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible) |
|
||||
+--------------------------------+---------------------------------------------+------------------------------------------+
|
||||
|Expression |Return Type |Assertion/Semantics |
|
||||
+================================+=============================================+==========================================+
|
||||
|``++r`` |``X&`` |``&r == &++r`` |
|
||||
+--------------------------------+---------------------------------------------+------------------------------------------+
|
||||
|``r++`` |``X`` |``{ X tmp = r; ++r; return tmp; }`` |
|
||||
+--------------------------------+---------------------------------------------+------------------------------------------+
|
||||
|``traversal_category<X>::type`` |Convertible to ``incrementable_iterator_tag``| |
|
||||
+--------------------------------+---------------------------------------------+------------------------------------------+
|
||||
|
||||
|
||||
Single Pass Iterators [lib.single.pass.iterators]
|
||||
-------------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Single Pass Iterator*
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.
|
||||
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------+
|
||||
|Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable) |
|
||||
+----------------------------------+----------------------------+----------------------------------------+
|
||||
|Expression |Return Type |Assertion/Semantics/Pre-/Post-condition |
|
||||
+==================================+============================+========================================+
|
||||
|``++r`` |``X&`` |pre: ``r`` is dereferenceable; post: |
|
||||
| | |``r`` is dereferenceable or ``r`` is |
|
||||
| | |past-the-end |
|
||||
+----------------------------------+----------------------------+----------------------------------------+
|
||||
|``a == b`` |convertible to ``bool`` |``==`` is an equivalence relation over |
|
||||
| | |its domain |
|
||||
+----------------------------------+----------------------------+----------------------------------------+
|
||||
|``a != b`` |convertible to ``bool`` |``!(a == b)`` |
|
||||
+----------------------------------+----------------------------+----------------------------------------+
|
||||
|``traversal_category<X>::type`` |Convertible to | |
|
||||
| |``single_pass_iterator_tag``| |
|
||||
+----------------------------------+----------------------------+----------------------------------------+
|
||||
|
||||
|
||||
Forward Traversal Iterators [lib.forward.traversal.iterators]
|
||||
-------------------------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Forward Traversal Iterator*
|
||||
concept if the following expressions are valid and respect the stated
|
||||
semantics.
|
||||
|
||||
+------------------------------------------------------------------------------------------------------+
|
||||
|Forward Traversal Iterator Requirements (in addition to Single Pass Iterator) |
|
||||
+---------------------------------------+-------------------------------------+------------------------+
|
||||
|Expression |Return Type |Assertion/Note |
|
||||
+=======================================+=====================================+========================+
|
||||
|``X u;`` |``X&`` |``note: u may have a |
|
||||
| | |singular value.`` |
|
||||
+---------------------------------------+-------------------------------------+------------------------+
|
||||
|``++r`` |``X&`` |``r == s`` and ``r`` is |
|
||||
| | |dereferenceable implies |
|
||||
| | |``++r == ++s.`` |
|
||||
+---------------------------------------+-------------------------------------+------------------------+
|
||||
|``iterator_traits<X>::difference_type``|A signed integral type representing | |
|
||||
| |the distance between iterators | |
|
||||
+---------------------------------------+-------------------------------------+------------------------+
|
||||
|``traversal_category<X>::type`` |Convertible to | |
|
||||
| |``forward_traversal_iterator_tag`` | |
|
||||
+---------------------------------------+-------------------------------------+------------------------+
|
||||
|
||||
|
||||
Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Bidirectional Traversal
|
||||
Iterator* concept if the following expressions are valid and respect
|
||||
the stated semantics.
|
||||
|
||||
+----------------------------------------------------------------------------------------------------------------+
|
||||
|Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator) |
|
||||
+-------------------------------+----------------------------------------+---------------------------------------+
|
||||
|Expression |Return Type |Assertion/Semantics/Pre-/Post-condition|
|
||||
+===============================+========================================+=======================================+
|
||||
|``--r`` |``X&`` |pre: there exists ``s`` such that ``r |
|
||||
| | |== ++s``. post: ``s`` is |
|
||||
| | |dereferenceable. ``--(++r) == r``. |
|
||||
| | |``--r == --s`` implies ``r == s``. ``&r|
|
||||
| | |== &--r``. |
|
||||
+-------------------------------+----------------------------------------+---------------------------------------+
|
||||
|``r--`` |convertible to ``const X&`` |``{ X tmp = r; --r; return tmp; }`` |
|
||||
| | | |
|
||||
| | | |
|
||||
+-------------------------------+----------------------------------------+---------------------------------------+
|
||||
|``traversal_category<X>::type``|Convertible to | |
|
||||
| |``bidirectional_traversal_iterator_tag``| |
|
||||
| | | |
|
||||
+-------------------------------+----------------------------------------+---------------------------------------+
|
||||
|
||||
|
||||
Random Access Traversal Iterators [lib.random.access.traversal.iterators]
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
A class or built-in type ``X`` models the *Random Access Traversal
|
||||
Iterator* concept if the following expressions are valid and respect
|
||||
the stated semantics. In the table below, ``Distance`` is
|
||||
``iterator_traits<X>::difference_type`` and ``n`` represents a
|
||||
constant object of type ``Distance``.
|
||||
|
||||
+------------------------------------------------------------------------------------------------------------------------------+
|
||||
|Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator) |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
| Expression |Return Type | Operational Semantics| Assertion/Precondition |
|
||||
+================================+========================================+======================+=============================+
|
||||
|``r += n`` |``X&`` |:: | |
|
||||
| | | | |
|
||||
| | | { | |
|
||||
| | | Distance m = n; | |
|
||||
| | | if (m >= 0) | |
|
||||
| | | while (m--) | |
|
||||
| | | ++r; | |
|
||||
| | | else | |
|
||||
| | | while (m++) | |
|
||||
| | | --r; | |
|
||||
| | | return r; | |
|
||||
| | | } | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
| ``a + n``, ``n + a`` |``X`` |``{ X tmp = a; return | |
|
||||
| | |tmp += n; }`` | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``r -= n`` |``X&`` |``return r += -n`` | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a - n`` |``X`` |``{ X tmp = a; return | |
|
||||
| | |tmp -= n; }`` | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``b - a`` |``Distance`` |``a < b ? |pre: there exists a value |
|
||||
| | |distance(a,b) : |``n`` of ``Distance`` such |
|
||||
| | |-distance(b,a)`` |that ``a + n == b``. ``b == |
|
||||
| | | |a + (b - a)``. |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a[n]`` |convertible to T |``*(a + n)`` |pre: a is a `readable |
|
||||
| | | |iterator`_ |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a[n] = v`` |convertible to T |``*(a + n) = v`` |pre: a is a `writable |
|
||||
| | | |iterator`_ |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a < b`` |convertible to ``bool`` |``b - a > 0`` |``<`` is a total ordering |
|
||||
| | | |relation |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a > b`` |convertible to ``bool`` |``b < a`` |``>`` is a total ordering |
|
||||
| | | |relation |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a >= b`` |convertible to ``bool`` |``!(a < b)`` | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``a <= b`` |convertible to ``bool`` |``!(a > b)`` | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|``traversal_category<X>::type`` |Convertible to | | |
|
||||
| |``random_access_traversal_iterator_tag``| | |
|
||||
+--------------------------------+----------------------------------------+----------------------+-----------------------------+
|
||||
|
||||
|
||||
|
||||
Addition to [lib.iterator.synopsis]
|
||||
===================================
|
||||
|
||||
::
|
||||
|
||||
// lib.iterator.traits, traits and tags
|
||||
template <class Iterator> struct access_category;
|
||||
template <class Iterator> struct traversal_category;
|
||||
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag : /* appropriate old category or categories */ {
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
|
||||
struct readable_iterator_tag { };
|
||||
struct writable_iterator_tag { };
|
||||
struct swappable_iterator_tag { };
|
||||
struct readable_writable_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
, virtual writable_iterator_tag
|
||||
, virtual swappable_iterator_tag { };
|
||||
struct readable_lvalue_iterator_tag { };
|
||||
struct writable_lvalue_iterator_tag
|
||||
: virtual public readable_writable_iterator_tag
|
||||
, virtual public readable_lvalue_iterator_tag { };
|
||||
|
||||
struct incrementable_iterator_tag { };
|
||||
struct single_pass_iterator_tag : incrementable_iterator_tag { };
|
||||
struct forward_traversal_tag : single_pass_iterator_tag { };
|
||||
struct bidirectional_traversal_tag : forward_traversal_tag { };
|
||||
struct random_access_traversal_tag : bidirectional_traversal_tag { };
|
||||
|
||||
struct null_category_tag { };
|
||||
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
|
||||
|
||||
Addition to [lib.iterator.traits]
|
||||
=================================
|
||||
|
||||
The ``iterator_tag`` class template is an iterator category tag that
|
||||
encodes the access and traversal tags in addition to being compatible
|
||||
with the original iterator tags. The ``iterator_tag`` class inherits
|
||||
from one of the original iterator tags according to the following
|
||||
pseudo-code.
|
||||
|
||||
::
|
||||
|
||||
inherit-category(access-tag, traversal-tag) =
|
||||
if (access-tag is convertible to readable_lvalue_iterator_tag) {
|
||||
if (traversal-tag is convertible to random_access_traversal_tag)
|
||||
return random_access_iterator_tag;
|
||||
else if (traversal-tag is convertible to bidirectional_traversal_tag)
|
||||
return bidirectional_iterator_tag;
|
||||
else if (traversal-tag is convertible to forward_traversal_tag)
|
||||
return forward_iterator_tag;
|
||||
else if (traversal-tag is convertible to single_pass_traversal_tag)
|
||||
if (access-tag is convertible to writable_iterator_tag)
|
||||
return input_output_iterator_tag;
|
||||
else
|
||||
return input_iterator_tag;
|
||||
else if (access-tag is convertible to writable_iterator_tag)
|
||||
return output_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
} else if (access-tag is convertible to readable_writable_iterator_tag
|
||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||
return input_output_iterator_tag;
|
||||
else if (access-tag is convertible to readable_iterator_tag
|
||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||
return input_iterator_tag;
|
||||
else if (access-tag is convertible to writable_iterator_tag
|
||||
and traversal-tag is convertible to incrementable_iterator_tag)
|
||||
return output_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
|
||||
|
||||
The ``access_category`` and ``traversal_category`` class templates are
|
||||
traits classes. For iterators whose
|
||||
``iterator_traits<Iter>::iterator_category`` type is ``iterator_tag``,
|
||||
the ``access_category`` and ``traversal_category`` traits access the
|
||||
``access`` and ``traversal`` member types within ``iterator_tag``.
|
||||
For iterators whose ``iterator_traits<Iter>::iterator_category`` type
|
||||
is not ``iterator_tag`` and instead is a tag convertible to one of the
|
||||
original tags, the appropriate traversal and access tags is deduced.
|
||||
The following pseudo-code describes the algorithm.
|
||||
|
||||
::
|
||||
|
||||
access-category(Iterator) =
|
||||
cat = iterator_traits<Iterator>::iterator_category;
|
||||
if (cat == iterator_tag<Access,Traversal>)
|
||||
return Access;
|
||||
else if (cat is convertible to forward_iterator_tag) {
|
||||
if (iterator_traits<Iterator>::reference is a const reference)
|
||||
return readable_lvalue_iterator_tag;
|
||||
else
|
||||
return writable_lvalue_iterator_tag;
|
||||
} else if (cat is convertible to input_iterator_tag)
|
||||
return readable_iterator_tag;
|
||||
else if (cat is convertible to output_iterator_tag)
|
||||
return writable_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
|
||||
traversal-category(Iterator) =
|
||||
cat = iterator_traits<Iterator>::iterator_category;
|
||||
if (cat == iterator_tag<Access,Traversal>)
|
||||
return Traversal;
|
||||
else if (cat is convertible to random_access_iterator_tag)
|
||||
return random_access_traversal_tag;
|
||||
else if (cat is convertible to bidirectional_iterator_tag)
|
||||
return bidirectional_traversal_tag;
|
||||
else if (cat is convertible to forward_iterator_tag)
|
||||
return forward_traversal_tag;
|
||||
else if (cat is convertible to input_iterator_tag)
|
||||
return single_pass_iterator_tag;
|
||||
else if (cat is convertible to output_iterator_tag)
|
||||
return incrementable_iterator_tag;
|
||||
else
|
||||
return null_category_tag;
|
||||
|
||||
|
||||
The following specializations provide the access and traversal
|
||||
category tags for pointer types.
|
||||
|
||||
::
|
||||
|
||||
template <typename T>
|
||||
struct access_category<const T*>
|
||||
{
|
||||
typedef readable_lvalue_iterator_tag type;
|
||||
};
|
||||
template <typename T>
|
||||
struct access_category<T*>
|
||||
{
|
||||
typedef writable_lvalue_iterator_tag type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
..
|
||||
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
|
||||
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
|
||||
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
|
||||
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
|
||||
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
|
||||
LocalWords: TraversalTag typename lvalues DWA Hmm JGS
|
BIN
doc/oldeqnew.png
BIN
doc/oldeqnew.png
Binary file not shown.
Before Width: | Height: | Size: 33 KiB |
@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Permutation Iterator</title>
|
||||
<meta name="author" content="Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="permutation-iterator">
|
||||
<h1 class="title">Permutation Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="last reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="last reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The permutation iterator adaptor provides a permuted view of a given
|
||||
range. That is, the view includes every element of the given range but
|
||||
in a potentially different order.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id4" name="id4">Introduction</a></li>
|
||||
<li><a class="reference" href="#reference" id="id5" name="id5">Reference</a><ul>
|
||||
<li><a class="reference" href="#permutation-iterator-requirements" id="id6" name="id6"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#permutation-iterator-operations" id="id7" name="id7"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="introduction">
|
||||
<h1><a class="toc-backref" href="#id4" name="introduction">Introduction</a></h1>
|
||||
<p>The adaptor takes two arguments:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>an iterator to the range V on which the permutation
|
||||
will be applied</li>
|
||||
<li>the reindexing scheme that defines how the
|
||||
elements of V will be permuted.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>Note that the permutation iterator is not limited to strict
|
||||
permutations of the given range V. The distance between begin and end
|
||||
of the reindexing iterators is allowed to be smaller compared to the
|
||||
size of the range V, in which case the permutation iterator only
|
||||
provides a permutation of a subrange of V. The indexes neither need
|
||||
to be unique. In this same context, it must be noted that the past the
|
||||
end permutation iterator is completely defined by means of the
|
||||
past-the-end iterator to the indices.</p>
|
||||
</div>
|
||||
<div class="section" id="reference">
|
||||
<h1><a class="toc-backref" href="#id5" name="reference">Reference</a></h1>
|
||||
<pre class="literal-block">
|
||||
template< class ElementIterator
|
||||
, class IndexIterator
|
||||
, class ValueT = use_default
|
||||
, class CategoryT = use_default
|
||||
, class ReferenceT = use_default
|
||||
, class DifferenceT = use_default >
|
||||
class permutation_iterator
|
||||
: public iterator_adaptor<...>
|
||||
{
|
||||
typedef iterator_adaptor<...>
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
permutation_iterator();
|
||||
explicit permutation_iterator(ElementIterator x, IndexIterator y);
|
||||
|
||||
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
||||
permutation_iterator(
|
||||
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
||||
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
||||
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
||||
);
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="permutation-iterator-requirements">
|
||||
<h2><a class="toc-backref" href="#id6" name="permutation-iterator-requirements"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></h2>
|
||||
<p><tt class="literal"><span class="pre">ElementIterator</span></tt> must be a model of <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>.
|
||||
<tt class="literal"><span class="pre">IndexIterator</span></tt> must at least be a model <a class="reference" href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>. The
|
||||
value type of the <tt class="literal"><span class="pre">IndexIterator</span></tt> must be convertible to the
|
||||
difference type of <tt class="literal"><span class="pre">ElementIterator</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="permutation-iterator-operations">
|
||||
<h2><a class="toc-backref" href="#id7" name="permutation-iterator-operations"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></h2>
|
||||
<p>The permutation iterator implements the member functions and operators
|
||||
required for the <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> concept. However, the
|
||||
permutation iterator can only meet the complexity guarantees of the
|
||||
same concept as the IndexIterator. Thus for instance, although the
|
||||
permutation iterator provides <tt class="literal"><span class="pre">operator+=(distance)</span></tt>, this operation
|
||||
will take linear time in case the IndexIterator is a model of
|
||||
ForwardIterator instead of amortized constant time.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="permutation_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
++++++++++++++++++++++
|
||||
Permutation Iterator
|
||||
++++++++++++++++++++++
|
||||
|
||||
:Author: Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: permutation_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. include:: permutation_iterator_body.rst
|
||||
|
||||
|
||||
Reference
|
||||
=========
|
||||
|
||||
.. include:: permutation_iterator_ref.rst
|
@ -1,4 +0,0 @@
|
||||
The permutation iterator adaptor provides a permuted view of a given
|
||||
range. That is, the view includes every element of the given range but
|
||||
in a potentially different order.
|
||||
|
@ -1,15 +0,0 @@
|
||||
The adaptor takes two arguments:
|
||||
|
||||
* an iterator to the range V on which the permutation
|
||||
will be applied
|
||||
* the reindexing scheme that defines how the
|
||||
elements of V will be permuted.
|
||||
|
||||
Note that the permutation iterator is not limited to strict
|
||||
permutations of the given range V. The distance between begin and end
|
||||
of the reindexing iterators is allowed to be smaller compared to the
|
||||
size of the range V, in which case the permutation iterator only
|
||||
provides a permutation of a subrange of V. The indexes neither need
|
||||
to be unique. In this same context, it must be noted that the past the
|
||||
end permutation iterator is completely defined by means of the
|
||||
past-the-end iterator to the indices.
|
@ -1,54 +0,0 @@
|
||||
.. parsed-literal::
|
||||
|
||||
template< class ElementIterator
|
||||
, class IndexIterator
|
||||
, class ValueT = use_default
|
||||
, class CategoryT = use_default
|
||||
, class ReferenceT = use_default
|
||||
, class DifferenceT = use_default >
|
||||
class permutation_iterator
|
||||
: public iterator_adaptor<...>
|
||||
{
|
||||
typedef iterator_adaptor<...>
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
permutation_iterator();
|
||||
explicit permutation_iterator(ElementIterator x, IndexIterator y);
|
||||
|
||||
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
||||
permutation_iterator(
|
||||
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
||||
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
||||
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
``permutation_iterator`` requirements
|
||||
-------------------------------------
|
||||
|
||||
``ElementIterator`` must be a model of RandomAccessIterator__.
|
||||
``IndexIterator`` must at least be a model ForwardIterator__. The
|
||||
value type of the ``IndexIterator`` must be convertible to the
|
||||
difference type of ``ElementIterator``.
|
||||
|
||||
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html
|
||||
|
||||
__ http://www.sgi.com/tech/stl/ForwardIterator.html
|
||||
|
||||
|
||||
|
||||
|
||||
``permutation_iterator`` operations
|
||||
-----------------------------------
|
||||
|
||||
The permutation iterator implements the member functions and operators
|
||||
required for the `Random Access Iterator`__ concept. However, the
|
||||
permutation iterator can only meet the complexity guarantees of the
|
||||
same concept as the IndexIterator. Thus for instance, although the
|
||||
permutation iterator provides ``operator+=(distance)``, this operation
|
||||
will take linear time in case the IndexIterator is a model of
|
||||
ForwardIterator instead of amortized constant time.
|
||||
|
||||
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html
|
@ -1,143 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
|
||||
<title>Reverse Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="reverse-iterator">
|
||||
<h1 class="title">Reverse Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- I think we'd better strike the old reverse_iterator text from the standard, eh? -->
|
||||
<p>The reverse iterator adaptor flips the direction of a base iterator's
|
||||
motion. Invoking <tt class="literal"><span class="pre">operator++()</span></tt> moves the base iterator backward and
|
||||
invoking <tt class="literal"><span class="pre">operator--()</span></tt> moves the base iterator forward.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#reverse-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <class Iterator>
|
||||
class reverse_iterator :
|
||||
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
reverse_iterator() {}
|
||||
explicit reverse_iterator(Iterator x) ;
|
||||
|
||||
template<class OtherIterator>
|
||||
reverse_iterator(
|
||||
reverse_iterator<OtherIterator> const& r
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
private: // as-if specification
|
||||
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
|
||||
|
||||
void increment() { --this->base_reference(); }
|
||||
void decrement() { ++this->base_reference(); }
|
||||
|
||||
void advance(typename reverse_iterator::difference_type n)
|
||||
{
|
||||
this->base_reference() += -n;
|
||||
}
|
||||
|
||||
template <class OtherIterator>
|
||||
typename reverse_iterator::difference_type
|
||||
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||
{
|
||||
return this->base_reference() - y.base();
|
||||
}
|
||||
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="reverse-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="reverse-iterator-requirements"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></h1>
|
||||
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal
|
||||
Iterator. The resulting <tt class="literal"><span class="pre">reverse_iterator</span></tt> will be a model of the
|
||||
most refined standard traversal and access concepts that are modeled
|
||||
by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
||||
<p><tt class="literal"><span class="pre">reverse_iterator();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
|
||||
default constructed base object.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">reverse_iterator(Iterator</span> <span class="pre">x);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
|
||||
base object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template<class OtherIterator>
|
||||
reverse_iterator(
|
||||
reverse_iterator<OtherIterator> const& r
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">r</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="footer" />
|
||||
<div class="footer">
|
||||
<a class="reference" href="reverse_iterator.rst">View document source</a>.
|
||||
Generated on: 2003-09-14 02:16 UTC.
|
||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
++++++++++++++++++
|
||||
Reverse Iterator
|
||||
++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: reverse_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: reverse_iterator_ref.rst
|
@ -1,6 +0,0 @@
|
||||
.. I think we'd better strike the old reverse_iterator text from the standard, eh?
|
||||
|
||||
The reverse iterator adaptor flips the direction of a base iterator's
|
||||
motion. Invoking ``operator++()`` moves the base iterator backward and
|
||||
invoking ``operator--()`` moves the base iterator forward.
|
||||
|
@ -1,69 +0,0 @@
|
||||
::
|
||||
|
||||
template <class Iterator>
|
||||
class reverse_iterator :
|
||||
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
reverse_iterator() {}
|
||||
explicit reverse_iterator(Iterator x) ;
|
||||
|
||||
template<class OtherIterator>
|
||||
reverse_iterator(
|
||||
reverse_iterator<OtherIterator> const& r
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
private: // as-if specification
|
||||
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
|
||||
|
||||
void increment() { --this->base_reference(); }
|
||||
void decrement() { ++this->base_reference(); }
|
||||
|
||||
void advance(typename reverse_iterator::difference_type n)
|
||||
{
|
||||
this->base_reference() += -n;
|
||||
}
|
||||
|
||||
template <class OtherIterator>
|
||||
typename reverse_iterator::difference_type
|
||||
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||
{
|
||||
return this->base_reference() - y.base();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
``reverse_iterator`` requirements
|
||||
.................................
|
||||
|
||||
The base ``Iterator`` must be a model of Bidirectional Traversal
|
||||
Iterator. The resulting ``reverse_iterator`` will be a model of the
|
||||
most refined standard traversal and access concepts that are modeled
|
||||
by ``Iterator``.
|
||||
|
||||
|
||||
``reverse_iterator();``
|
||||
|
||||
:Requires: ``Iterator`` must be Default Constructible.
|
||||
:Returns: An instance of ``reverse_iterator`` with a
|
||||
default constructed base object.
|
||||
|
||||
``explicit reverse_iterator(Iterator x);``
|
||||
|
||||
:Returns: An instance of ``reverse_iterator`` with a
|
||||
base object copy constructed from ``x``.
|
||||
|
||||
|
||||
::
|
||||
|
||||
template<class OtherIterator>
|
||||
reverse_iterator(
|
||||
reverse_iterator<OtherIterator> const& r
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
|
||||
:Returns: An instance of ``reverse_iterator`` that is a copy of ``r``.
|
@ -1,169 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
|
||||
<title>Transform Iterator</title>
|
||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||
<meta name="date" content="2003-08-05" />
|
||||
<meta name="copyright" content="Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="transform-iterator">
|
||||
<h1 class="title">Transform Iterator</h1>
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
|
||||
<tr><th class="docinfo-name">Contact:</th>
|
||||
<td><a class="first reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a>, <a class="last reference" href="mailto:witt@ive.uni-hannover.de">witt@ive.uni-hannover.de</a></td></tr>
|
||||
<tr><th class="docinfo-name">Organization:</th>
|
||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
|
||||
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
|
||||
Railway Operation and Construction</a></td></tr>
|
||||
<tr><th class="docinfo-name">Date:</th>
|
||||
<td>2003-08-05</td></tr>
|
||||
<tr><th class="docinfo-name">Copyright:</th>
|
||||
<td>Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The transform iterator adapts an iterator by applying some function
|
||||
object to the result of dereferencing the iterator. In other words,
|
||||
the <tt class="literal"><span class="pre">operator*</span></tt> of the transform iterator first dereferences the
|
||||
base iterator, passes the result of this to the function object, and
|
||||
then returns the result.</p>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#transform-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></li>
|
||||
<li><a class="reference" href="#transform-iterator-public-operations" id="id2" name="id2"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></li>
|
||||
<li><a class="reference" href="#transform-iterator-private-operations" id="id3" name="id3"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<pre class="literal-block">
|
||||
template <class AdaptableUnaryFunction,
|
||||
class Iterator,
|
||||
class Reference = use_default,
|
||||
class Value = use_default>
|
||||
class transform_iterator
|
||||
: public iterator_adaptor</* see discussion */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
transform_iterator();
|
||||
transform_iterator(Iterator const& x, AdaptableUnaryFunction f);
|
||||
|
||||
template<class OtherIterator, class R2, class V2>
|
||||
transform_iterator(
|
||||
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
AdaptableUnaryFunction functor() const;
|
||||
private:
|
||||
typename transform_iterator::value_type dereference() const;
|
||||
AdaptableUnaryFunction m_f;
|
||||
};
|
||||
</pre>
|
||||
<div class="section" id="transform-iterator-requirements">
|
||||
<h1><a class="toc-backref" href="#id1" name="transform-iterator-requirements"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
|
||||
<p>The type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> must be Assignable, Copy
|
||||
Constructible, and the expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid where <tt class="literal"><span class="pre">f</span></tt>
|
||||
is an object of type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of
|
||||
type <tt class="literal"><span class="pre">AdaptableUnaryFunction::argument_type</span></tt>, and where the type of
|
||||
<tt class="literal"><span class="pre">f(x)</span></tt> must be <tt class="literal"><span class="pre">AdaptableUnaryFunction::result_type</span></tt>.</p>
|
||||
<p>The type <tt class="literal"><span class="pre">Iterator</span></tt> must at least model Readable Iterator. The
|
||||
resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
|
||||
following options that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>Writable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> of the
|
||||
<tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> is a non-const reference.</li>
|
||||
<li>Readable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> is a const
|
||||
reference.</li>
|
||||
<li>Readable Iterator otherwise.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>The <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined standard traversal
|
||||
concept that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
||||
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of <tt class="literal"><span class="pre">transform_iterator</span></tt> is
|
||||
<tt class="literal"><span class="pre">remove_reference<result_type>::type</span></tt>. The <tt class="literal"><span class="pre">reference</span></tt> type is
|
||||
<tt class="literal"><span class="pre">result_type</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="transform-iterator-public-operations">
|
||||
<h1><a class="toc-backref" href="#id2" name="transform-iterator-public-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">transform_iterator();</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
|
||||
and <tt class="literal"><span class="pre">m_iterator</span></tt> default constructed.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">transform_iterator(Iterator</span> <span class="pre">const&</span> <span class="pre">x,</span> <span class="pre">AdaptableUnaryFunction</span> <span class="pre">f);</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
|
||||
initialized to <tt class="literal"><span class="pre">f</span></tt> and <tt class="literal"><span class="pre">m_iterator</span></tt> initialized to <tt class="literal"><span class="pre">x</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<pre class="literal-block">
|
||||
template<class OtherIterator, class R2, class V2>
|
||||
transform_iterator(
|
||||
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
</pre>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">transform_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">t</span></tt>.</td>
|
||||
</tr>
|
||||
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><tt class="literal"><span class="pre">AdaptableUnaryFunction</span> <span class="pre">functor()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_f</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="transform-iterator-private-operations">
|
||||
<h1><a class="toc-backref" href="#id3" name="transform-iterator-private-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></h1>
|
||||
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">transform_iterator::value_type</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
|
||||
<table class="field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_f(transform_iterator::dereference());</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
++++++++++++++++++++
|
||||
Transform Iterator
|
||||
++++++++++++++++++++
|
||||
|
||||
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||
Lab`_, University of Hanover `Institute for Transport
|
||||
Railway Operation and Construction`_
|
||||
:date: $Date$
|
||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||
|
||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||
|
||||
:abstract:
|
||||
|
||||
.. include:: transform_iterator_abstract.rst
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. include:: transform_iterator_ref.rst
|
@ -1,5 +0,0 @@
|
||||
The transform iterator adapts an iterator by applying some function
|
||||
object to the result of dereferencing the iterator. In other words,
|
||||
the ``operator*`` of the transform iterator first dereferences the
|
||||
base iterator, passes the result of this to the function object, and
|
||||
then returns the result.
|
@ -1,95 +0,0 @@
|
||||
::
|
||||
|
||||
template <class AdaptableUnaryFunction,
|
||||
class Iterator,
|
||||
class Reference = use_default,
|
||||
class Value = use_default>
|
||||
class transform_iterator
|
||||
: public iterator_adaptor</* see discussion */>
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
public:
|
||||
transform_iterator();
|
||||
transform_iterator(Iterator const& x, AdaptableUnaryFunction f);
|
||||
|
||||
template<class OtherIterator, class R2, class V2>
|
||||
transform_iterator(
|
||||
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
AdaptableUnaryFunction functor() const;
|
||||
private:
|
||||
typename transform_iterator::value_type dereference() const;
|
||||
AdaptableUnaryFunction m_f;
|
||||
};
|
||||
|
||||
|
||||
``transform_iterator`` requirements
|
||||
...................................
|
||||
|
||||
The type ``AdaptableUnaryFunction`` must be Assignable, Copy
|
||||
Constructible, and the expression ``f(x)`` must be valid where ``f``
|
||||
is an object of type ``AdaptableUnaryFunction``, ``x`` is an object of
|
||||
type ``AdaptableUnaryFunction::argument_type``, and where the type of
|
||||
``f(x)`` must be ``AdaptableUnaryFunction::result_type``.
|
||||
|
||||
The type ``Iterator`` must at least model Readable Iterator. The
|
||||
resulting ``transform_iterator`` models the most refined of the
|
||||
following options that is also modeled by ``Iterator``.
|
||||
|
||||
* Writable Lvalue Iterator if the ``result_type`` of the
|
||||
``AdaptableUnaryFunction`` is a non-const reference.
|
||||
|
||||
* Readable Lvalue Iterator if the ``result_type`` is a const
|
||||
reference.
|
||||
|
||||
* Readable Iterator otherwise.
|
||||
|
||||
|
||||
The ``transform_iterator`` models the most refined standard traversal
|
||||
concept that is modeled by ``Iterator``.
|
||||
|
||||
The ``value_type`` of ``transform_iterator`` is
|
||||
``remove_reference<result_type>::type``. The ``reference`` type is
|
||||
``result_type``.
|
||||
|
||||
|
||||
``transform_iterator`` public operations
|
||||
........................................
|
||||
|
||||
|
||||
``transform_iterator();``
|
||||
|
||||
:Returns: An instance of ``transform_iterator`` with ``m_f``
|
||||
and ``m_iterator`` default constructed.
|
||||
|
||||
|
||||
``transform_iterator(Iterator const& x, AdaptableUnaryFunction f);``
|
||||
|
||||
:Returns: An instance of ``transform_iterator`` with ``m_f``
|
||||
initialized to ``f`` and ``m_iterator`` initialized to ``x``.
|
||||
|
||||
|
||||
::
|
||||
|
||||
template<class OtherIterator, class R2, class V2>
|
||||
transform_iterator(
|
||||
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
:Returns: An instance of ``transform_iterator`` that is a copy of ``t``.
|
||||
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
|
||||
|
||||
``AdaptableUnaryFunction functor() const;``
|
||||
|
||||
:Returns: ``m_f``
|
||||
|
||||
``transform_iterator`` private operations
|
||||
.........................................
|
||||
|
||||
``typename transform_iterator::value_type dereference() const;``
|
||||
|
||||
:Returns: ``m_f(transform_iterator::dereference());``
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB |
@ -1 +0,0 @@
|
||||
unit-test ia1 : reverse_iterator.cpp : <sysinclude>../../.. <sysinclude>$(BOOST) ;
|
@ -1,16 +0,0 @@
|
||||
#include <boost/iterator/iterator_adaptors.hpp>
|
||||
#include <boost/cstdlib.hpp>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
int main()
|
||||
{
|
||||
int x[] = { 1, 2, 3, 4 };
|
||||
boost::reverse_iterator<int*, int, int&, int*,
|
||||
boost::iterator_tag<boost::mutable_lvalue_iterator_tag, boost::random_access_traversal_tag>
|
||||
, std::ptrdiff_t> first(x + 4), last(x);
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
@ -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
|
@ -1,426 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek and David Abrahams 2000-2001. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its suitability
|
||||
// for any purpose.
|
||||
//
|
||||
// Revision History:
|
||||
// 11 Feb 2001 Use new iterator_adaptor interface, Fixes for Borland.
|
||||
// (Dave Abrahams)
|
||||
// 04 Feb 2001 Support for user-defined iterator categories (Dave Abrahams)
|
||||
// 30 Jan 2001 Initial Checkin (Dave Abrahams)
|
||||
|
||||
#ifndef BOOST_HALF_OPEN_RANGE_HPP_
|
||||
# define BOOST_HALF_OPEN_RANGE_HPP_
|
||||
|
||||
# include <boost/counting_iterator.hpp>
|
||||
# include <functional>
|
||||
# include <cassert>
|
||||
# include <boost/operators.hpp>
|
||||
# include <string>
|
||||
# include <stdexcept>
|
||||
# include <iterator>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Template class choose_finish -- allows us to maintain the invariant that
|
||||
// start() <= finish() on half_open_range specializations that support random
|
||||
// access.
|
||||
#ifdef __MWERKS__
|
||||
template <class T>
|
||||
const T& choose_finish(const T&, const T& finish, std::input_iterator_tag)
|
||||
{
|
||||
return finish;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& choose_finish(const T&, const T& finish, std::output_iterator_tag)
|
||||
{
|
||||
return finish;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& choose_finish(const T& start, const T& finish, std::random_access_iterator_tag)
|
||||
{
|
||||
return finish < start ? start : finish;
|
||||
}
|
||||
#else
|
||||
template <bool is_random_access> struct finish_chooser;
|
||||
|
||||
template <>
|
||||
struct finish_chooser<false>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
static T choose(const T&, const T& finish)
|
||||
{ return finish; }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct finish_chooser<true>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
static T choose(const T& start, const T& finish)
|
||||
{ return finish < start ? start : finish; }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Category, class Incrementable>
|
||||
struct choose_finish
|
||||
{
|
||||
static const Incrementable choose(const Incrementable& start, const Incrementable& finish)
|
||||
{
|
||||
return finish_chooser<(
|
||||
::boost::is_convertible<Category*,std::random_access_iterator_tag*>::value
|
||||
)>::template rebind<Incrementable>::choose(start, finish);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
struct half_open_range
|
||||
{
|
||||
typedef typename counting_iterator_generator<Incrementable>::type iterator;
|
||||
|
||||
private: // utility type definitions
|
||||
// Using iter_t prevents compiler confusion with boost::iterator
|
||||
typedef typename counting_iterator_generator<Incrementable>::type iter_t;
|
||||
|
||||
typedef std::less<Incrementable> less_value;
|
||||
typedef typename iter_t::iterator_category category;
|
||||
typedef half_open_range<Incrementable> self;
|
||||
|
||||
public:
|
||||
typedef iter_t const_iterator;
|
||||
typedef typename iterator::value_type value_type;
|
||||
typedef typename iterator::difference_type difference_type;
|
||||
typedef typename iterator::reference reference;
|
||||
typedef typename iterator::reference const_reference;
|
||||
typedef typename iterator::pointer pointer;
|
||||
typedef typename iterator::pointer const_pointer;
|
||||
|
||||
// It would be nice to select an unsigned type, but this is appropriate
|
||||
// since the library makes an attempt to select a difference_type which can
|
||||
// hold the difference between any two iterators.
|
||||
typedef typename iterator::difference_type size_type;
|
||||
|
||||
half_open_range(Incrementable start, Incrementable finish)
|
||||
: m_start(start),
|
||||
m_finish(
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(start, finish)
|
||||
#else
|
||||
detail::choose_finish(start, finish, category())
|
||||
#endif
|
||||
)
|
||||
{}
|
||||
|
||||
// Implicit conversion from std::pair<Incrementable,Incrementable> allows us
|
||||
// to accept the results of std::equal_range(), for example.
|
||||
half_open_range(const std::pair<Incrementable,Incrementable>& x)
|
||||
: m_start(x.first),
|
||||
m_finish(
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(x.first, x.second)
|
||||
#else
|
||||
detail::choose_finish(x.first, x.second, category())
|
||||
#endif
|
||||
)
|
||||
{}
|
||||
|
||||
half_open_range& operator=(const self& x)
|
||||
{
|
||||
m_start = x.m_start;
|
||||
m_finish = x.m_finish;
|
||||
return *this;
|
||||
}
|
||||
|
||||
half_open_range& operator=(const std::pair<Incrementable,Incrementable>& x)
|
||||
{
|
||||
m_start = x.first;
|
||||
m_finish =
|
||||
#ifndef __MWERKS__
|
||||
detail::choose_finish<category,Incrementable>::choose(x.first, x.second);
|
||||
#else
|
||||
detail::choose_finish(x.first, x.second, category();
|
||||
#endif
|
||||
}
|
||||
|
||||
iterator begin() const { return iterator(m_start); }
|
||||
iterator end() const { return iterator(m_finish); }
|
||||
|
||||
Incrementable front() const { assert(!this->empty()); return m_start; }
|
||||
Incrementable back() const { assert(!this->empty()); return boost::prior(m_finish); }
|
||||
|
||||
Incrementable start() const { return m_start; }
|
||||
Incrementable finish() const { return m_finish; }
|
||||
|
||||
size_type size() const { return boost::detail::distance(begin(), end()); }
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_finish == m_start;
|
||||
}
|
||||
|
||||
void swap(half_open_range& x) {
|
||||
std::swap(m_start, x.m_start);
|
||||
std::swap(m_finish, x.m_finish);
|
||||
}
|
||||
|
||||
public: // functions requiring random access elements
|
||||
|
||||
// REQUIRES: x is reachable from this->front()
|
||||
bool contains(const value_type& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return !less_value()(x, m_start) && less_value()(x, m_finish);
|
||||
}
|
||||
|
||||
bool contains(const half_open_range& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return x.empty() || !less_value()(x.m_start, m_start) && !less_value()(m_finish, x.m_finish);
|
||||
}
|
||||
|
||||
bool intersects(const half_open_range& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
return less_value()(
|
||||
less_value()(this->m_start, x.m_start) ? x.m_start : this->m_start,
|
||||
less_value()(this->m_finish, x.m_finish) ? this->m_finish : x.m_finish);
|
||||
}
|
||||
|
||||
half_open_range& operator&=(const half_open_range& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
if (less_value()(this->m_start, x.m_start))
|
||||
this->m_start = x.m_start;
|
||||
|
||||
if (less_value()(x.m_finish, this->m_finish))
|
||||
this->m_finish = x.m_finish;
|
||||
|
||||
if (less_value()(this->m_finish, this->m_start))
|
||||
this->m_start = this->m_finish;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
half_open_range& operator|=(const half_open_range& x)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
if (!x.empty())
|
||||
{
|
||||
if (this->empty())
|
||||
{
|
||||
*this = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (less_value()(x.m_start, this->m_start))
|
||||
this->m_start = x.m_start;
|
||||
|
||||
if (less_value()(this->m_finish, x.m_finish))
|
||||
this->m_finish = x.m_finish;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// REQUIRES: x is reachable from this->front()
|
||||
const_iterator find(const value_type& x) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<category, std::random_access_iterator_tag>::value));
|
||||
|
||||
return const_iterator(this->contains(x) ? x : m_finish);
|
||||
}
|
||||
|
||||
// REQUIRES: index >= 0 && index < size()
|
||||
value_type operator[](size_type index) const
|
||||
{
|
||||
assert(index >= 0 && index < size());
|
||||
return m_start + index;
|
||||
}
|
||||
|
||||
value_type at(size_type index) const
|
||||
{
|
||||
if (index < 0 || index >= size())
|
||||
throw std::out_of_range(std::string("half_open_range"));
|
||||
return m_start + index;
|
||||
}
|
||||
|
||||
private: // data members
|
||||
Incrementable m_start, m_finish;
|
||||
};
|
||||
|
||||
template <class Incrementable>
|
||||
half_open_range<Incrementable> operator|(
|
||||
half_open_range<Incrementable> x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x |= y;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
half_open_range<Incrementable> operator&(
|
||||
half_open_range<Incrementable> x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x &= y;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline bool operator==(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
const bool y_empty = y.empty();
|
||||
return x.empty() ? y_empty : !y_empty && x.start() == y.start() && x.finish() == y.finish();
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline bool operator!=(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
inline half_open_range<Incrementable>
|
||||
make_half_open_range(Incrementable first, Incrementable last)
|
||||
{
|
||||
return half_open_range<Incrementable>(first, last);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool intersects(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x.intersects(y);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool contains(
|
||||
const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return x.contains(y);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
namespace std {
|
||||
template <class Incrementable> struct less<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
less<Incrementable> cmp;
|
||||
return !y.empty() && (
|
||||
cmp(x.start(), y.start())
|
||||
|| !cmp(y.start(), x.start())
|
||||
&& cmp(x.finish(), y.finish()));
|
||||
}
|
||||
};
|
||||
|
||||
template <class Incrementable> struct less_equal<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return !cmp(y,x);
|
||||
}
|
||||
};
|
||||
template <class Incrementable> struct greater<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return cmp(y,x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Incrementable> struct greater_equal<boost::half_open_range<Incrementable> >
|
||||
: binary_function<
|
||||
boost::half_open_range<Incrementable>,
|
||||
boost::half_open_range<Incrementable>,bool>
|
||||
{
|
||||
bool operator()(
|
||||
const boost::half_open_range<Incrementable>& x,
|
||||
const boost::half_open_range<Incrementable>& y) const
|
||||
{
|
||||
typedef boost::half_open_range<Incrementable> range;
|
||||
less<range> cmp;
|
||||
return !cmp(x,y);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#else
|
||||
|
||||
namespace boost {
|
||||
// Can't partially specialize std::less et al, so we must provide the operators
|
||||
template <class Incrementable>
|
||||
bool operator<(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !y.empty() && (
|
||||
x.empty() || std::less<Incrementable>()(x.start(), y.start())
|
||||
|| !std::less<Incrementable>()(y.start(), x.start())
|
||||
&& std::less<Incrementable>()(x.finish(), y.finish()));
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator>(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator<=(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <class Incrementable>
|
||||
bool operator>=(const half_open_range<Incrementable>& x,
|
||||
const half_open_range<Incrementable>& y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_HALF_OPEN_RANGE_HPP_
|
@ -1,60 +0,0 @@
|
||||
// interator.hpp workarounds for non-conforming standard libraries ---------//
|
||||
|
||||
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org/libs/utility for documentation.
|
||||
|
||||
// Revision History
|
||||
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
|
||||
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
|
||||
// 26 Jun 00 Initial version (Jeremy Siek)
|
||||
|
||||
#ifndef BOOST_ITERATOR_HPP
|
||||
#define BOOST_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <cstddef> // std::ptrdiff_t
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
template <class Category, class T,
|
||||
class Distance = std::ptrdiff_t,
|
||||
class Pointer = T*, class Reference = T&>
|
||||
struct iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef Distance difference_type;
|
||||
typedef Pointer pointer;
|
||||
typedef Reference reference;
|
||||
typedef Category iterator_category;
|
||||
};
|
||||
# else
|
||||
|
||||
// declare iterator_base in namespace detail to work around MSVC bugs which
|
||||
// prevent derivation from an identically-named class in a different namespace.
|
||||
namespace detail {
|
||||
template <class Category, class T, class Distance, class Pointer, class Reference>
|
||||
# if !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
|
||||
# else
|
||||
struct iterator_base : std::iterator<Category, T, Distance>
|
||||
{
|
||||
typedef Reference reference;
|
||||
typedef Pointer pointer;
|
||||
typedef Distance difference_type;
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Category, class T, class Distance = std::ptrdiff_t,
|
||||
class Pointer = T*, class Reference = T&>
|
||||
struct iterator : detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
|
||||
# endif
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_HPP
|
@ -15,7 +15,12 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Incrementable, class Category, class Difference> class counting_iterator;
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal
|
||||
, class Difference
|
||||
>
|
||||
class counting_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@ -67,35 +72,38 @@ namespace detail
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||
template <class Incrementable, class Category, class Difference>
|
||||
|
||||
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
typedef typename mpl::apply_if<
|
||||
is_same<Category, use_default>
|
||||
typedef typename detail::ia_dflt_help<
|
||||
CategoryOrTraversal
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, mpl::identity<std::random_access_iterator_tag>
|
||||
, BOOST_ITERATOR_CATEGORY<Incrementable>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, iterator_traversal<Incrementable>
|
||||
>
|
||||
, mpl::identity<Category>
|
||||
>::type category;
|
||||
>::type traversal;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
is_same<Difference, use_default>
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Difference
|
||||
, mpl::apply_if<
|
||||
is_numeric<Incrementable>
|
||||
, numeric_difference<Incrementable>
|
||||
, iterator_difference<Incrementable>
|
||||
>
|
||||
, mpl::identity<Difference>
|
||||
>::type difference;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
counting_iterator<Incrementable, Category, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // value_type
|
||||
, category
|
||||
, Incrementable const& // reference
|
||||
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // Value
|
||||
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
const // MSVC won't strip this. Instead we enable Thomas'
|
||||
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
||||
# endif
|
||||
, traversal
|
||||
, Incrementable const& // reference
|
||||
, difference
|
||||
> type;
|
||||
};
|
||||
@ -128,11 +136,20 @@ namespace detail
|
||||
};
|
||||
}
|
||||
|
||||
template <class Incrementable, class Category = use_default, class Difference = use_default>
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class counting_iterator
|
||||
: public detail::counting_iterator_base<Incrementable, Category, Difference>::type
|
||||
: public detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::counting_iterator_base<Incrementable, Category, Difference>::type super_t;
|
||||
typedef typename detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
|
19
include/boost/iterator/detail/any_conversion_eater.hpp
Executable file
19
include/boost/iterator/detail/any_conversion_eater.hpp
Executable file
@ -0,0 +1,19 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
// This type can be used in traits to "eat" up the one user-defined
|
||||
// implicit conversion allowed.
|
||||
struct any_conversion_eater
|
||||
{
|
||||
template <class T>
|
||||
any_conversion_eater(T const&);
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
@ -1,360 +1 @@
|
||||
// (C) Copyright Thomas Witt 2002. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
# define BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/or.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
# include <iterator>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// faked new old-style categories needed to make new->old mapping
|
||||
// work
|
||||
namespace detail
|
||||
{
|
||||
struct null_category_tag {};
|
||||
struct input_output_iterator_tag : std::input_iterator_tag, std::output_iterator_tag {};
|
||||
}
|
||||
|
||||
//
|
||||
// Access Categories
|
||||
//
|
||||
struct readable_iterator_tag
|
||||
{
|
||||
typedef std::input_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_iterator_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct swappable_iterator_tag
|
||||
{
|
||||
typedef detail::null_category_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_writable_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
, virtual writable_iterator_tag
|
||||
, virtual swappable_iterator_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct readable_lvalue_iterator_tag
|
||||
: virtual readable_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct writable_lvalue_iterator_tag
|
||||
: virtual public readable_writable_iterator_tag
|
||||
, virtual public readable_lvalue_iterator_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
struct incrementable_traversal_tag
|
||||
{
|
||||
typedef std::output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct single_pass_traversal_tag
|
||||
: incrementable_traversal_tag
|
||||
{
|
||||
typedef detail::input_output_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct forward_traversal_tag
|
||||
: single_pass_traversal_tag
|
||||
{
|
||||
typedef std::forward_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag
|
||||
{
|
||||
typedef std::bidirectional_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag
|
||||
{
|
||||
typedef std::random_access_iterator_tag max_category;
|
||||
};
|
||||
|
||||
struct error_iterator_tag { };
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Tag detection meta functions
|
||||
//
|
||||
|
||||
// I bet this is defined somewhere else. Let's wait and see.
|
||||
struct error_type;
|
||||
|
||||
# ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
// True iff T is a tag "derived" from Tag
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: mpl::or_<
|
||||
is_convertible<T, Tag>
|
||||
|
||||
// Because we can't actually get forward_iterator_tag to
|
||||
// derive from input_output_iterator_tag, we need this
|
||||
// case.
|
||||
, mpl::and_<
|
||||
is_convertible<T,std::forward_iterator_tag>
|
||||
, is_convertible<detail::input_output_iterator_tag,Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
# else
|
||||
template <class Tag, class T>
|
||||
struct is_tag;
|
||||
# endif
|
||||
|
||||
// Generate specializations which will allow us to find
|
||||
// null_category_tag as a minimum old-style category for new-style
|
||||
// iterators which don't have an actual old-style category. We
|
||||
// need that so there is a valid base class for all new-style
|
||||
// iterators.
|
||||
# define BOOST_OLD_ITERATOR_CATEGORY(category) \
|
||||
template <> \
|
||||
struct is_tag <detail::null_category_tag, std::category> \
|
||||
: mpl::true_ {};
|
||||
|
||||
BOOST_OLD_ITERATOR_CATEGORY(input_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(output_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(forward_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(bidirectional_iterator_tag)
|
||||
BOOST_OLD_ITERATOR_CATEGORY(random_access_iterator_tag)
|
||||
# undef BOOST_OLD_ITERATOR_CATEGORY
|
||||
|
||||
template <>
|
||||
struct is_tag<detail::input_output_iterator_tag,std::forward_iterator_tag>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct is_tag<T,T> : mpl::true_
|
||||
{};
|
||||
|
||||
# ifdef BOOST_NO_IS_CONVERTIBLE
|
||||
// Workarounds for CWPro7 which can't detect derivation at
|
||||
// compile-time.
|
||||
|
||||
// Fact of life: we can only detect tag refinement relationships
|
||||
// among predefined tags.
|
||||
//
|
||||
// Algorithm:
|
||||
// is_tag(T,U) ->
|
||||
// T == U
|
||||
// || (exists d in derived_from(T) such that is_tag(d, U))
|
||||
//
|
||||
// T == U case is handled above
|
||||
|
||||
// false by default
|
||||
template <class Tag, class T>
|
||||
struct is_tag_impl : mpl::false_
|
||||
{};
|
||||
|
||||
// The generalized template dispatches to is_tag_impl because
|
||||
// is_tag<T,T> and is_tag<some_tag,T> are equally specialized.
|
||||
// This technique simulates making is_tag<T,T> more-specialized.
|
||||
template <class Tag, class T>
|
||||
struct is_tag
|
||||
: is_tag_impl<Tag, T>
|
||||
{};
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1(base, derived) \
|
||||
BOOST_ITERATOR_DERIVED_TAG1_AUX(base, _, derived)
|
||||
|
||||
# define BOOST_ITERATOR_DERIVED_TAG1_AUX(base, underscore, derived) \
|
||||
template<class T> \
|
||||
struct is_tag_impl<base##underscore##tag, T> \
|
||||
: is_tag<derived##underscore##tag, T> \
|
||||
{ \
|
||||
};
|
||||
|
||||
// Old-style tag relations
|
||||
template<class T>
|
||||
struct is_tag_impl<detail::null_category_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<std::output_iterator_tag, T>
|
||||
, is_tag<std::input_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::output_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::input_iterator, detail::input_output_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(detail::input_output_iterator, std::forward_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::forward_iterator, std::bidirectional_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(std::bidirectional_iterator, std::random_access_iterator)
|
||||
|
||||
// Access tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_lvalue_iterator, writable_lvalue_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(swappable_iterator, readable_writable_iterator)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(readable_writable_iterator, writable_lvalue_iterator)
|
||||
|
||||
template<class T>
|
||||
struct is_tag_impl<readable_iterator_tag, T>
|
||||
: mpl::or_<
|
||||
is_tag<readable_lvalue_iterator_tag, T>
|
||||
, is_tag<readable_writable_iterator_tag, T>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_ITERATOR_DERIVED_TAG1(writable_iterator, readable_writable_iterator)
|
||||
|
||||
// Traversal tag relations
|
||||
BOOST_ITERATOR_DERIVED_TAG1(bidirectional_traversal, random_access_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(forward_traversal, bidirectional_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(single_pass_traversal, forward_traversal)
|
||||
BOOST_ITERATOR_DERIVED_TAG1(incrementable_traversal, single_pass_traversal)
|
||||
|
||||
# endif // BOOST_NO_IS_CONVERTIBLE workarounds
|
||||
|
||||
# endif // ndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class Tag, class Known, class Else>
|
||||
struct known_tag
|
||||
: mpl::apply_if<is_tag<Known,Tag>, mpl::identity<Known>, Else>
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct max_known_traversal_tag
|
||||
: known_tag<
|
||||
Tag, random_access_traversal_tag
|
||||
, known_tag<
|
||||
Tag, bidirectional_traversal_tag
|
||||
, known_tag<
|
||||
Tag, forward_traversal_tag
|
||||
, known_tag<
|
||||
Tag, single_pass_traversal_tag
|
||||
, known_tag<
|
||||
Tag, incrementable_traversal_tag
|
||||
, error_iterator_tag
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
// Doesn't cope with these odd combinations: readable+swappable,
|
||||
// writable+swappable. That doesn't matter for the sake of
|
||||
// new-style tag base computation, which is all it's used for
|
||||
// anyway.
|
||||
template <class Tag>
|
||||
struct max_known_access_tag
|
||||
: known_tag<
|
||||
Tag, writable_lvalue_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_lvalue_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_writable_iterator_tag
|
||||
, known_tag<
|
||||
Tag, writable_iterator_tag
|
||||
, known_tag<
|
||||
Tag, readable_iterator_tag
|
||||
, mpl::apply_if<
|
||||
is_tag<Tag, swappable_iterator_tag>
|
||||
, mpl::identity<null_category_tag>
|
||||
, error_iterator_tag
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// For compilers not supporting is_convertible this only
|
||||
// works with the new boost return and traversal category
|
||||
// types. The exact boost _types_ are required. No derived types
|
||||
// will work.
|
||||
//
|
||||
//
|
||||
template <class T1, class T2>
|
||||
struct minimum_category
|
||||
: mpl::apply_if<
|
||||
is_tag<T1,T2>
|
||||
, mpl::identity<T1>
|
||||
, mpl::if_<
|
||||
is_tag<T2, T1>
|
||||
, T2
|
||||
, error_type
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct minimum_category<int, int> { typedef minimum_category type; };
|
||||
# endif
|
||||
|
||||
//
|
||||
// Tag classification for use in iterator_adaptor
|
||||
//
|
||||
template <class Tag>
|
||||
struct is_access_tag
|
||||
: mpl::or_<
|
||||
is_tag<readable_iterator_tag, Tag>
|
||||
, mpl::or_<
|
||||
is_tag<writable_iterator_tag, Tag>
|
||||
, is_tag<swappable_iterator_tag, Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Tag>
|
||||
struct is_traversal_tag
|
||||
: is_tag<incrementable_traversal_tag, Tag>
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_DETAIL_CATEGORIES_HPP
|
||||
#error obsolete
|
||||
|
@ -18,7 +18,66 @@
|
||||
#include <boost/config.hpp> // for prior
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#define BOOST_ITERATOR_CONFIG_DEF // if you get an error here, you have nested config_def #inclusion.
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# error you have nested config_def #inclusion.
|
||||
#else
|
||||
# define BOOST_ITERATOR_CONFIG_DEF
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
|
||||
|
||||
// Recall that in general, compilers without partial specialization
|
||||
// can't strip constness. Consider counting_iterator, which normally
|
||||
// passes a const Value to iterator_facade. As a result, any code
|
||||
// which makes a std::vector of the iterator's value_type will fail
|
||||
// when its allocator declares functions overloaded on reference and
|
||||
// const_reference (the same type).
|
||||
//
|
||||
// Furthermore, Borland 5.5.1 drops constness in enough ways that we
|
||||
// end up using a proxy for operator[] when we otherwise shouldn't.
|
||||
// Using reference constness gives it an extra hint that it can
|
||||
// return the value_type from operator[] directly, but is not
|
||||
// strictly neccessary. Not sure how best to resolve this one.
|
||||
|
||||
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|
||||
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER))
|
||||
# define BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
# if 0 // test code
|
||||
struct v {};
|
||||
|
||||
typedef char (&no)[3];
|
||||
|
||||
template <class T>
|
||||
no foo(T const&, ...);
|
||||
|
||||
template <class T>
|
||||
char foo(T&, int);
|
||||
|
||||
|
||||
struct value_iterator
|
||||
{
|
||||
v operator*() const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lvalue_deref_helper
|
||||
{
|
||||
static T& x;
|
||||
enum { value = (sizeof(foo(*x,0)) == 1) };
|
||||
};
|
||||
|
||||
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
|
||||
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||
|| BOOST_WORKAROUND(__GNUC__, <= 2 && __GNUC_MINOR__ <= 95) \
|
||||
|
@ -18,6 +18,7 @@
|
||||
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
|
||||
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
#undef BOOST_ARG_DEPENDENT_TYPENAME
|
||||
#undef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
|
||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||
# undef BOOST_ITERATOR_CONFIG_DEF
|
||||
|
214
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
214
include/boost/iterator/detail/facade_iterator_category.hpp
Executable file
@ -0,0 +1,214 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||
|
||||
# include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
|
||||
# include <boost/mpl/and.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_const.hpp>
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
|
||||
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/python/detail/indirect_traits.hpp>
|
||||
# endif
|
||||
|
||||
//
|
||||
// iterator_category deduction for iterator_facade
|
||||
//
|
||||
|
||||
// forward declaration
|
||||
namespace boost { struct use_default; }
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
struct input_output_iterator_tag
|
||||
: std::input_iterator_tag
|
||||
{
|
||||
// Using inheritance for only input_iterator_tag helps to avoid
|
||||
// ambiguities when a stdlib implementation dispatches on a
|
||||
// function which is overloaded on both input_iterator_tag and
|
||||
// output_iterator_tag, as STLPort does, in its __valid_range
|
||||
// function. I claim it's better to avoid the ambiguity in these
|
||||
// cases.
|
||||
operator std::output_iterator_tag() const
|
||||
{
|
||||
return std::output_iterator_tag();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// True iff the user has explicitly disabled writability of this
|
||||
// iterator. Pass the iterator_facade's Value parameter and its
|
||||
// nested ::reference type.
|
||||
//
|
||||
template <class ValueParam, class Reference>
|
||||
struct iterator_writability_disabled
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
|
||||
: mpl::or_<
|
||||
is_const<Reference>
|
||||
, python::detail::is_reference_to_const<Reference>
|
||||
, is_const<ValueParam>
|
||||
>
|
||||
# else
|
||||
: is_const<ValueParam>
|
||||
# endif
|
||||
{};
|
||||
|
||||
|
||||
//
|
||||
// Convert an iterator_facade's traversal category, Value parameter,
|
||||
// and ::reference type to an appropriate old-style category.
|
||||
//
|
||||
// If writability has been disabled per the above metafunction, the
|
||||
// result will not be convertible to output_iterator_tag.
|
||||
//
|
||||
// Otherwise, if Traversal == single_pass_traversal_tag, the following
|
||||
// conditions will result in a tag that is convertible both to
|
||||
// input_iterator_tag and output_iterator_tag:
|
||||
//
|
||||
// 1. Reference is a reference to non-const
|
||||
// 2. Reference is not a reference and is convertible to Value
|
||||
//
|
||||
template <class Traversal, class ValueParam, class Reference>
|
||||
struct iterator_facade_default_category
|
||||
: mpl::apply_if<
|
||||
mpl::and_<
|
||||
is_reference<Reference>
|
||||
, is_convertible<Traversal,forward_traversal_tag>
|
||||
>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,random_access_traversal_tag>
|
||||
, mpl::identity<std::random_access_iterator_tag>
|
||||
, mpl::if_<
|
||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||
, std::bidirectional_iterator_tag
|
||||
, std::forward_iterator_tag
|
||||
>
|
||||
>
|
||||
, typename mpl::apply_if<
|
||||
mpl::and_<
|
||||
is_convertible<Traversal, single_pass_traversal_tag>
|
||||
|
||||
, mpl::or_< // check for readability
|
||||
is_same<ValueParam,use_default>
|
||||
, is_convertible<Reference, ValueParam>
|
||||
>
|
||||
>
|
||||
, mpl::if_<
|
||||
iterator_writability_disabled<ValueParam,Reference>
|
||||
, std::input_iterator_tag
|
||||
, input_output_iterator_tag
|
||||
>
|
||||
|
||||
, mpl::identity<std::output_iterator_tag>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// True iff T is convertible to an old-style iterator category.
|
||||
template <class T>
|
||||
struct is_iterator_category
|
||||
: mpl::or_<
|
||||
is_convertible<T,std::input_iterator_tag>
|
||||
, is_convertible<T,std::output_iterator_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_iterator_traversal
|
||||
: is_convertible<T,incrementable_traversal_tag>
|
||||
{};
|
||||
|
||||
//
|
||||
// A composite iterator_category tag convertible to Category (a pure
|
||||
// old-style category) and Traversal (a pure traversal tag).
|
||||
// Traversal must be a strict increase of the traversal power given by
|
||||
// Category.
|
||||
//
|
||||
template <class Category, class Traversal>
|
||||
struct iterator_category_with_traversal
|
||||
: Category, Traversal
|
||||
{
|
||||
# if 0
|
||||
// Because of limitations on multiple user-defined conversions,
|
||||
// this should be a good test of whether convertibility is enough
|
||||
// in the spec, or whether we need to specify inheritance.
|
||||
operator Category() const { return Category(); }
|
||||
operator Traversal() const { return Traversal(); }
|
||||
# endif
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// Make sure this isn't used to build any categories where
|
||||
// convertibility to Traversal is redundant. Should just use the
|
||||
// Category element in that case.
|
||||
BOOST_STATIC_ASSERT(
|
||||
!(is_convertible<
|
||||
typename iterator_category_to_traversal<Category>::type
|
||||
, Traversal
|
||||
>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT(is_iterator_category<Category>::value);
|
||||
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
|
||||
BOOST_STATIC_ASSERT(!is_iterator_traversal<Category>::value);
|
||||
BOOST_STATIC_ASSERT(is_iterator_traversal<Traversal>::value);
|
||||
# endif
|
||||
};
|
||||
|
||||
// Computes an iterator_category tag whose traversal is Traversal and
|
||||
// which is appropriate for an iterator
|
||||
template <class Traversal, class ValueParam, class Reference>
|
||||
struct facade_iterator_category_impl
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT(!is_iterator_category<Traversal>::value);
|
||||
# endif
|
||||
|
||||
typedef typename iterator_facade_default_category<
|
||||
Traversal,ValueParam,Reference
|
||||
>::type category;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_same<
|
||||
Traversal
|
||||
, typename iterator_category_to_traversal<category>::type
|
||||
>
|
||||
, category
|
||||
, iterator_category_with_traversal<category,Traversal>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//
|
||||
// Compute an iterator_category for iterator_facade
|
||||
//
|
||||
template <class CategoryOrTraversal, class ValueParam, class Reference>
|
||||
struct facade_iterator_category
|
||||
: mpl::apply_if<
|
||||
is_iterator_category<CategoryOrTraversal>
|
||||
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
|
||||
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
98
include/boost/iterator/detail/minimum_category.hpp
Executable file
98
include/boost/iterator/detail/minimum_category.hpp
Executable file
@ -0,0 +1,98 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
//
|
||||
// Returns the minimum category type or error_type
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// For compilers not supporting is_convertible this only
|
||||
// works with the new boost return and traversal category
|
||||
// types. The exact boost _types_ are required. No derived types
|
||||
// will work.
|
||||
//
|
||||
//
|
||||
template <bool GreaterEqual, bool LessEqual>
|
||||
struct minimum_category_impl;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct error_not_related_by_convertibility;
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
: error_not_related_by_convertibility<T1,T2>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||
struct minimum_category
|
||||
{
|
||||
typedef minimum_category_impl<
|
||||
::boost::is_convertible<T1,T2>::value
|
||||
, ::boost::is_convertible<T2,T1>::value
|
||||
> outer;
|
||||
|
||||
typedef typename outer::template apply<T1,T2> inner;
|
||||
typedef typename inner::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category<mpl::_1,mpl::_2>
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply : minimum_category<T1,T2>
|
||||
{};
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct minimum_category<int,int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
@ -13,28 +13,42 @@
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
struct filter_iterator_base
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>
|
||||
, Iterator
|
||||
, use_default
|
||||
, typename mpl::if_<
|
||||
is_convertible<
|
||||
typename iterator_traversal<Iterator>::type
|
||||
, bidirectional_traversal_tag
|
||||
>
|
||||
, forward_traversal_tag
|
||||
, use_default
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
>
|
||||
: public detail::filter_iterator_base<Predicate, Iterator>::type
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>, Iterator
|
||||
, use_default
|
||||
, typename detail::minimum_category<
|
||||
bidirectional_traversal_tag
|
||||
, typename traversal_category<Iterator>::type
|
||||
>::type
|
||||
> super_t;
|
||||
typedef typename detail::filter_iterator_base<
|
||||
Predicate, Iterator
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
|
150
include/boost/iterator/is_lvalue_iterator.hpp
Executable file
150
include/boost/iterator/is_lvalue_iterator.hpp
Executable file
@ -0,0 +1,150 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
// should be the last #includes
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
// Calling lvalue_preserver( <expression>, 0 ) returns a reference
|
||||
// to the expression's result if <expression> is an lvalue, or
|
||||
// not_an_lvalue() otherwise.
|
||||
struct not_an_lvalue {};
|
||||
|
||||
template <class T>
|
||||
T& lvalue_preserver(T&, int);
|
||||
|
||||
template <class U>
|
||||
not_an_lvalue lvalue_preserver(U const&, ...);
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) lvalue_preserver(expr,0)
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) expr
|
||||
|
||||
#endif
|
||||
|
||||
// Guts of is_lvalue_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_lvalue_iterator_impl
|
||||
{
|
||||
// Eat implicit conversions so we don't report true for things
|
||||
// convertible to Value const&
|
||||
struct conversion_eater
|
||||
{
|
||||
conversion_eater(Value&);
|
||||
};
|
||||
|
||||
static char tester(conversion_eater, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_lvalue_iterator_impl<Value>::tester(
|
||||
BOOST_LVALUE_PRESERVER(*x), 0
|
||||
)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_LVALUE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
|
||||
template <class It>
|
||||
struct is_non_const_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
// Define the trait with full mpl lambda capability and various broken
|
||||
// compiler workarounds
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
#include <boost/type_traits/detail/bool_trait_undef.hpp>
|
||||
|
||||
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
108
include/boost/iterator/is_readable_iterator.hpp
Executable file
108
include/boost/iterator/is_readable_iterator.hpp
Executable file
@ -0,0 +1,108 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
// should be the last #include
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Guts of is_readable_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_readable_iterator_impl
|
||||
{
|
||||
static char tester(Value&, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_readable_iterator_impl<Value>::tester(*x, 1)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_READABLE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_readable_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_iterator_impl2
|
||||
: is_readable_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
// Define the trait with full mpl lambda capability and various broken
|
||||
// compiler workarounds
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2<T>::value)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP
|
@ -26,12 +26,32 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
#else
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// Used as a default template argument internally, merely to
|
||||
// indicate "use the default", this can also be passed by users
|
||||
// explicitly in order to specify that the default should be used.
|
||||
struct use_default;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// the incompleteness of use_default causes massive problems for
|
||||
// is_convertible (naturally). This workaround is fortunately not
|
||||
// needed for vc6/vc7.
|
||||
template<class To>
|
||||
struct is_convertible<use_default,To>
|
||||
: mpl::false_ {};
|
||||
# endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@ -142,63 +162,51 @@ namespace boost
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value
|
||||
, class Category
|
||||
, class Traversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_adaptor_base
|
||||
{
|
||||
private: // intermediate results
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
mpl::or_<
|
||||
is_same<Category, use_default>
|
||||
, mpl::or_<
|
||||
is_access_tag<Category>
|
||||
, is_traversal_tag<Category>
|
||||
>
|
||||
>
|
||||
, BOOST_ITERATOR_CATEGORY<Base>
|
||||
, mpl::identity<Category>
|
||||
>::type category;
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value, use_default>
|
||||
, iterator_reference<Base>
|
||||
, mpl::identity<Value&>
|
||||
>
|
||||
>::type reference;
|
||||
|
||||
public: // return type
|
||||
typedef iterator_facade<
|
||||
Derived
|
||||
|
||||
|
||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
, typename detail::ia_dflt_help<
|
||||
Value
|
||||
, mpl::apply_if<
|
||||
is_same<Reference,use_default>
|
||||
, iterator_value<Base>
|
||||
, remove_reference<Reference>
|
||||
>
|
||||
>::type
|
||||
# else
|
||||
, typename detail::ia_dflt_help<
|
||||
Value, iterator_value<Base>
|
||||
>::type
|
||||
|
||||
, typename mpl::apply_if<
|
||||
is_access_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, access_category_tag<category, reference>
|
||||
>::type
|
||||
# endif
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Traversal
|
||||
, iterator_traversal<Base>
|
||||
>::type
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Reference
|
||||
, mpl::apply_if<
|
||||
is_same<Value,use_default>
|
||||
, iterator_reference<Base>
|
||||
, add_reference<Value>
|
||||
>
|
||||
>::type
|
||||
|
||||
, typename mpl::apply_if<
|
||||
is_traversal_tag<Category>
|
||||
, mpl::identity<Category>
|
||||
, traversal_category_tag<category>
|
||||
>::type
|
||||
|
||||
, reference
|
||||
|
||||
, typename detail::ia_dflt_help<
|
||||
Difference, iterator_difference<Base>
|
||||
>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
template <class T> int static_assert_convertible_to(T);
|
||||
}
|
||||
|
||||
//
|
||||
@ -215,8 +223,8 @@ namespace boost
|
||||
// const. If const, a conforming compiler strips constness for the
|
||||
// value_type. If not supplied, iterator_traits<Base>::value_type is used
|
||||
//
|
||||
// Category - the iterator_category of the resulting iterator. If not
|
||||
// supplied, iterator_traits<Base>::iterator_category is used.
|
||||
// Category - the traversal category of the resulting iterator. If not
|
||||
// supplied, iterator_traversal<Base>::type is used.
|
||||
//
|
||||
// Reference - the reference type of the resulting iterator, and in
|
||||
// particular, the result type of operator*(). If not supplied but
|
||||
@ -230,19 +238,19 @@ namespace boost
|
||||
class Derived
|
||||
, class Base
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Traversal = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class iterator_adaptor
|
||||
: public detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Difference
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
friend class iterator_core_access;
|
||||
|
||||
typedef typename detail::iterator_adaptor_base<
|
||||
Derived, Base, Value, Category, Reference, Difference
|
||||
Derived, Base, Value, Traversal, Reference, Difference
|
||||
>::type super_t;
|
||||
|
||||
public:
|
||||
@ -287,17 +295,18 @@ namespace boost
|
||||
// );
|
||||
return m_iterator == x.base();
|
||||
}
|
||||
|
||||
|
||||
typedef typename iterator_category_to_traversal<
|
||||
typename super_t::iterator_category
|
||||
>::type my_traversal;
|
||||
|
||||
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
|
||||
typedef int assertion[sizeof(detail::static_assert_convertible_to<cat>(my_traversal()))];
|
||||
// BOOST_STATIC_ASSERT((is_convertible<my_traversal,cat>::value));
|
||||
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::is_tag<
|
||||
random_access_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::value)
|
||||
);
|
||||
# endif
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
|
||||
m_iterator += n;
|
||||
}
|
||||
|
||||
@ -305,14 +314,7 @@ namespace boost
|
||||
|
||||
void decrement()
|
||||
{
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) // seems to get instantiated incorrectly
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::is_tag<
|
||||
bidirectional_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::value)
|
||||
);
|
||||
# endif
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
|
||||
--m_iterator;
|
||||
}
|
||||
|
||||
@ -322,12 +324,7 @@ namespace boost
|
||||
typename super_t::difference_type distance_to(
|
||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(detail::is_tag<
|
||||
random_access_traversal_tag
|
||||
, BOOST_ARG_DEPENDENT_TYPENAME super_t::iterator_category::traversal
|
||||
>::value)
|
||||
);
|
||||
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
|
||||
// Maybe readd with same_distance
|
||||
// BOOST_STATIC_ASSERT(
|
||||
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||
@ -335,6 +332,8 @@ namespace boost
|
||||
return y.base() - m_iterator;
|
||||
}
|
||||
|
||||
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
|
||||
|
||||
private: // data members
|
||||
Base m_iterator;
|
||||
};
|
||||
|
@ -8,341 +8,449 @@
|
||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||
#include <boost/mpl/bitand.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
namespace boost {
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
|
||||
namespace iterator_archetypes
|
||||
{
|
||||
enum {
|
||||
readable_iterator_bit = 1
|
||||
, writable_iterator_bit = 2
|
||||
, swappable_iterator_bit = 4
|
||||
, lvalue_iterator_bit = 8
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
// Not quite tags, since dispatching wouldn't work.
|
||||
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
|
||||
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|writable_iterator_bit)
|
||||
>::type readable_writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|lvalue_iterator_bit)
|
||||
>::type readable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(lvalue_iterator_bit|writable_iterator_bit)
|
||||
>::type writable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
|
||||
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
template <class Derived, class Base>
|
||||
struct has_access
|
||||
: mpl::equal_to<
|
||||
mpl::bitand_<Derived,Base>
|
||||
, Base
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
assign_proxy& operator=(T);
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy :
|
||||
assign_proxy<T>
|
||||
{
|
||||
template <class T>
|
||||
struct read_proxy
|
||||
{
|
||||
operator T();
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
template <class T>
|
||||
struct read_write_proxy
|
||||
: assign_proxy<T>
|
||||
, read_proxy<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
T const* operator->() const;
|
||||
};
|
||||
};
|
||||
|
||||
struct no_operator_brackets {};
|
||||
struct no_operator_brackets {};
|
||||
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
ValueType operator[](std::ptrdiff_t n) const;
|
||||
};
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
read_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct writable_operator_brackets
|
||||
{
|
||||
template <class ValueType>
|
||||
struct writable_operator_brackets
|
||||
{
|
||||
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets :
|
||||
mpl::if_< is_tag<random_access_traversal_tag, TraversalCategory>,
|
||||
mpl::if_< is_tag<writable_iterator_tag, AccessCategory>,
|
||||
writable_operator_brackets< Value >,
|
||||
mpl::if_< is_tag<readable_iterator_tag, AccessCategory>,
|
||||
readable_operator_brackets<Value>,
|
||||
no_operator_brackets > >,
|
||||
no_operator_brackets >::type
|
||||
{
|
||||
};
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename mpl::apply_if<
|
||||
is_convertible<TraversalCategory, random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, mpl::identity<writable_operator_brackets<Value> >
|
||||
, mpl::if_<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory
|
||||
, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
, readable_operator_brackets<Value>
|
||||
, no_operator_brackets
|
||||
>
|
||||
>
|
||||
, mpl::identity<no_operator_brackets>
|
||||
>::type
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
{
|
||||
template <class Derived,class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
{
|
||||
template <class Derived,class Value> struct archetype;
|
||||
};
|
||||
template <class Derived, class Value, class TraversalCategory>
|
||||
struct traversal_archetype_
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class Derived, class Value, class TraversalCategory>
|
||||
struct traversal_archetype_
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
>::type
|
||||
{};
|
||||
template <>
|
||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
{
|
||||
typedef void difference_type;
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
{
|
||||
typedef void difference_type;
|
||||
Derived& operator++();
|
||||
Derived operator++(int) const;
|
||||
};
|
||||
};
|
||||
|
||||
Derived& operator++();
|
||||
Derived operator++(int) const;
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||
template <class Derived, class Value>
|
||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// doesn't seem to pick up != from equality_comparable
|
||||
template <class Derived, class Value>
|
||||
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||
template <class Derived, class Value>
|
||||
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&);
|
||||
#endif
|
||||
template <>
|
||||
struct traversal_archetype_impl<forward_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||
{
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct traversal_archetype_impl<forward_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||
{
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||
{
|
||||
Derived& operator--();
|
||||
Derived operator--(int) const;
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||
{
|
||||
Derived& operator--();
|
||||
Derived operator--(int) const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||
{
|
||||
Derived& operator+=(std::ptrdiff_t);
|
||||
Derived& operator-=(std::ptrdiff_t);
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public partially_ordered<traversal_archetype_<Derived, Value, random_access_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||
{
|
||||
Derived& operator+=(std::ptrdiff_t);
|
||||
Derived& operator-=(std::ptrdiff_t);
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t);
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t);
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(std::ptrdiff_t,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(std::ptrdiff_t,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t);
|
||||
template <class Derived, class Value>
|
||||
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t);
|
||||
|
||||
template <class Derived, class Value>
|
||||
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
template <class Derived, class Value>
|
||||
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
template <class Derived, class Value>
|
||||
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&);
|
||||
|
||||
struct bogus_type;
|
||||
struct bogus_type;
|
||||
|
||||
template <class Value>
|
||||
struct convertible_type
|
||||
: mpl::if_< is_const<Value>,
|
||||
typename remove_const<Value>::type,
|
||||
bogus_type >
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct iterator_access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct iterator_access_archetype
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename iterator_access_archetype_impl<
|
||||
AccessCategory
|
||||
>::template archetype<Value>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct convertible_type
|
||||
: mpl::if_< is_const<Value>,
|
||||
typename remove_const<Value>::type,
|
||||
bogus_type >
|
||||
{};
|
||||
struct archetype
|
||||
{
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef Value reference;
|
||||
typedef Value* pointer;
|
||||
|
||||
} // namespace detail
|
||||
value_type operator*() const;
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype
|
||||
: mpl::aux::msvc_eti_base<
|
||||
typename access_archetype_impl<AccessCategory>::template archetype<Value>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_iterator_tag>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef Value reference;
|
||||
typedef Value* pointer;
|
||||
|
||||
value_type operator*() const;
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<writable_iterator_tag>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||
# endif
|
||||
typedef void value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
typedef void value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
detail::assign_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
detail::assign_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_writable_iterator_tag>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||
{
|
||||
typedef detail::read_write_proxy<Value> reference;
|
||||
|
||||
detail::read_write_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<readable_lvalue_iterator_tag>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_iterator_tag>
|
||||
{
|
||||
typedef Value& reference;
|
||||
|
||||
Value& operator*() const;
|
||||
Value* operator->() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct access_archetype_impl<writable_lvalue_iterator_tag>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual access_archetype<Value, readable_lvalue_iterator_tag>
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||
# endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
: detail::operator_brackets<
|
||||
typename remove_cv<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>
|
||||
, detail::traversal_archetype_<
|
||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||
, Value
|
||||
, TraversalCategory
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
iterator_archetypes::readable_writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
};
|
||||
{
|
||||
typedef detail::read_write_proxy<Value> reference;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
, public access_archetype<Value, AccessCategory>
|
||||
detail::read_write_proxy<Value> operator*() const;
|
||||
};
|
||||
};
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
, public std::iterator<
|
||||
iterator_tag<AccessCategory,TraversalCategory>
|
||||
, typename access_archetype<Value, AccessCategory>::value_type
|
||||
, typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type
|
||||
>
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef Value& reference;
|
||||
|
||||
Value& operator*() const;
|
||||
Value* operator->() const;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, iterator_archetypes::readable_lvalue_iterator_t
|
||||
>
|
||||
{
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||
# endif
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
: detail::operator_brackets<
|
||||
typename remove_cv<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>
|
||||
, detail::traversal_archetype_<
|
||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||
, Value
|
||||
, TraversalCategory
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype_base
|
||||
: iterator_access_archetype<Value, AccessCategory>
|
||||
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
{
|
||||
// Derivation from std::iterator above caused ambiguity, so now
|
||||
// we have to declare all the types here.
|
||||
typedef iterator_access_archetype<Value, AccessCategory> access;
|
||||
|
||||
typedef typename detail::facade_iterator_category<
|
||||
TraversalCategory
|
||||
, typename mpl::apply_if<
|
||||
iterator_archetypes::has_access<
|
||||
AccessCategory, iterator_archetypes::writable_iterator_t
|
||||
>
|
||||
, remove_const<Value>
|
||||
, add_const<Value>
|
||||
>::type
|
||||
, typename access::reference
|
||||
>::type iterator_category;
|
||||
|
||||
// Needed for some broken libraries (see below)
|
||||
typedef boost::iterator<
|
||||
iterator_category
|
||||
, Value
|
||||
, typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type
|
||||
, typename access::pointer
|
||||
, typename access::reference
|
||||
> workaround_iterator_base;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
typedef typename access_archetype<Value, AccessCategory>::value_type value_type;
|
||||
|
||||
typedef typename access_archetype<Value, AccessCategory>::pointer pointer;
|
||||
|
||||
typedef typename access_archetype<Value, AccessCategory>::reference reference;
|
||||
|
||||
typedef typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type difference_type;
|
||||
, public detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::workaround_iterator_base
|
||||
# endif
|
||||
{
|
||||
// Derivation from std::iterator above caused references to nested
|
||||
// types to be ambiguous, so now we have to redeclare them all
|
||||
// here.
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
|
||||
typedef detail::iterator_archetype_base<
|
||||
Value,AccessCategory,TraversalCategory
|
||||
> base;
|
||||
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator_category iterator_category;
|
||||
# endif
|
||||
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
|
||||
iterator_archetype();
|
||||
iterator_archetype(iterator_archetype const&);
|
||||
iterator_archetype();
|
||||
iterator_archetype(iterator_archetype const&);
|
||||
|
||||
iterator_archetype& operator=(iterator_archetype const&);
|
||||
iterator_archetype& operator=(iterator_archetype const&);
|
||||
|
||||
// Optional conversion from mutable
|
||||
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
||||
};
|
||||
// Optional conversion from mutable
|
||||
// iterator_archetype(iterator_archetype<typename detail::convertible_type<Value>::type, AccessCategory, TraversalCategory> const&);
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -4,425 +4,159 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// TODO:
|
||||
// Add separate category tag for operator[].
|
||||
|
||||
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
|
||||
#define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
# define BOOST_ITERATOR_CATEGORIES_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/detail/categories.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/python/detail/indirect_traits.hpp>
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/aux_/has_xxx.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
||||
#ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
# include <boost/mpl/apply_if.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
#endif
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
#include <iterator>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||
# define BOOST_NO_IS_CONVERTIBLE // "Convertible does not provide enough/is not working"
|
||||
#endif
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Helper metafunction for std_category below
|
||||
template <class Cat, class Tag, class Next>
|
||||
struct match_tag
|
||||
: mpl::apply_if<is_tag<Tag, Cat>, mpl::identity<Tag>, Next>
|
||||
{
|
||||
};
|
||||
|
||||
// Converts a possibly user-defined category tag to the
|
||||
// most-derived standard tag which is a base of that tag.
|
||||
template <class Category>
|
||||
struct std_category
|
||||
: match_tag<
|
||||
Category, std::random_access_iterator_tag
|
||||
, match_tag<Category, std::bidirectional_iterator_tag
|
||||
, match_tag<Category, std::forward_iterator_tag
|
||||
, match_tag<Category, std::input_iterator_tag
|
||||
, match_tag<Category, std::output_iterator_tag
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
, mpl::identity<void>
|
||||
# else
|
||||
, void
|
||||
# endif
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// std_to_new_tags --
|
||||
//
|
||||
// A metafunction which converts any standard tag into its
|
||||
// corresponding new-style traversal tag.
|
||||
//
|
||||
// Also, instantiations are metafunction classes which convert a
|
||||
// reference type into a corresponding new-style access tag.
|
||||
template <class Category> struct std_to_new_tags
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300) // handle ETI
|
||||
{
|
||||
typedef void type;
|
||||
template <class T> struct apply { typedef void type; };
|
||||
}
|
||||
# endif
|
||||
;
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // handle ETI
|
||||
template <> struct std_to_new_tags<int> {};
|
||||
# endif
|
||||
|
||||
//
|
||||
// Specializations for specific standard tags
|
||||
//
|
||||
template <>
|
||||
struct std_to_new_tags<std::input_iterator_tag>
|
||||
{
|
||||
typedef single_pass_traversal_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::identity<readable_iterator_tag> {};
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::output_iterator_tag>
|
||||
{
|
||||
typedef incrementable_traversal_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::identity<writable_iterator_tag> {};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::forward_iterator_tag>
|
||||
{
|
||||
typedef forward_traversal_tag type;
|
||||
|
||||
template <class Reference>
|
||||
struct apply
|
||||
: mpl::if_<
|
||||
python::detail::is_reference_to_const<Reference>
|
||||
, boost::readable_lvalue_iterator_tag
|
||||
, boost::writable_lvalue_iterator_tag
|
||||
>
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::bidirectional_iterator_tag>
|
||||
: std_to_new_tags<std::forward_iterator_tag>
|
||||
{
|
||||
typedef bidirectional_traversal_tag type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std_to_new_tags<std::random_access_iterator_tag>
|
||||
: std_to_new_tags<std::bidirectional_iterator_tag>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
template <class Category>
|
||||
struct old_tag_converter
|
||||
: std_to_new_tags<
|
||||
typename std_category<Category>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Category>
|
||||
struct iter_category_to_traversal
|
||||
: std_to_new_tags<
|
||||
typename std_category<Category>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename Category, typename Reference>
|
||||
struct iter_category_to_access
|
||||
: mpl::apply1<
|
||||
iter_category_to_traversal<Category>
|
||||
, Reference
|
||||
>
|
||||
{};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct iter_category_to_access<int, int> {};
|
||||
template <> struct iter_category_to_traversal<int> {};
|
||||
# endif
|
||||
|
||||
// A metafunction returning true iff T is boost::iterator_tag<R,U>
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag;
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
//
|
||||
// has_xxx fails, so we have to use
|
||||
// something less sophisticated.
|
||||
//
|
||||
// The solution depends on the fact that only
|
||||
// std iterator categories work with is_xxx_iterator
|
||||
// meta functions, as BOOST_NO_IS_CONVERTIBLE is
|
||||
// defined for cwpro7.
|
||||
//
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: mpl::not_<
|
||||
mpl::or_<
|
||||
is_tag<std::input_iterator_tag, Tag>
|
||||
, is_tag<std::output_iterator_tag, Tag>
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
#elif BOOST_WORKAROUND(__GNUC__, == 2 && __GNUC_MINOR__ == 95) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: is_boost_iterator_tag<Tag>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(traversal)
|
||||
|
||||
template <class Tag>
|
||||
struct is_new_iterator_tag
|
||||
: mpl::if_<
|
||||
is_class<Tag>
|
||||
, has_traversal<Tag>
|
||||
, mpl::false_
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
//
|
||||
// Traversal Categories
|
||||
//
|
||||
struct incrementable_traversal_tag {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class NewCategoryTag>
|
||||
struct get_traversal_category {
|
||||
typedef typename NewCategoryTag::traversal type;
|
||||
};
|
||||
|
||||
// Remove all writability from the given access tag. This
|
||||
// functionality is part of new_category_to_access in order to
|
||||
// support deduction of the proper default access category for
|
||||
// iterator_adaptor; when the reference type is a reference to
|
||||
// constant we must strip writability.
|
||||
template <class AccessTag>
|
||||
struct remove_access_writability
|
||||
: mpl::apply_if<
|
||||
is_tag<writable_lvalue_iterator_tag, AccessTag>
|
||||
, mpl::identity<readable_lvalue_iterator_tag>
|
||||
|
||||
, mpl::apply_if<
|
||||
is_tag<readable_writable_iterator_tag, AccessTag>
|
||||
, mpl::identity<readable_iterator_tag>
|
||||
|
||||
, mpl::if_<
|
||||
is_tag<writable_iterator_tag, AccessTag>
|
||||
// Is this OK? I think it may correct be for all
|
||||
// legitimate cases, because at this point the
|
||||
// iterator is not readable, so it could not have
|
||||
// been any more than writable + swappable.
|
||||
, swappable_iterator_tag
|
||||
, AccessTag
|
||||
>
|
||||
>
|
||||
>
|
||||
{};
|
||||
struct single_pass_traversal_tag
|
||||
: incrementable_traversal_tag {};
|
||||
|
||||
template <class NewCategoryTag, class Reference>
|
||||
struct new_category_to_access
|
||||
: mpl::apply_if<
|
||||
python::detail::is_reference_to_const<Reference>
|
||||
, remove_access_writability<typename NewCategoryTag::access>
|
||||
, mpl::identity<typename NewCategoryTag::access>
|
||||
>
|
||||
{};
|
||||
struct forward_traversal_tag
|
||||
: single_pass_traversal_tag {};
|
||||
|
||||
struct bidirectional_traversal_tag
|
||||
: forward_traversal_tag {};
|
||||
|
||||
struct random_access_traversal_tag
|
||||
: bidirectional_traversal_tag {};
|
||||
|
||||
template <class CategoryTag, class Reference>
|
||||
struct access_category_tag
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, new_category_to_access<CategoryTag, Reference>
|
||||
, iter_category_to_access<CategoryTag, Reference>
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
// Convert a "strictly old-style" iterator category to a traversal
|
||||
// tag. This is broken out into a separate metafunction to reduce
|
||||
// the cost of instantiating iterator_category_to_traversal, below,
|
||||
// for new-style types.
|
||||
//
|
||||
template <class Cat>
|
||||
struct old_category_to_traversal
|
||||
: mpl::apply_if<
|
||||
is_convertible<Cat,std::random_access_iterator_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::bidirectional_iterator_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::forward_iterator_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::input_iterator_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Cat,std::output_iterator_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template <class CategoryTag>
|
||||
struct traversal_category_tag
|
||||
: mpl::apply_if<
|
||||
is_new_iterator_tag<CategoryTag>
|
||||
, get_traversal_category<CategoryTag>
|
||||
, iter_category_to_traversal<CategoryTag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
|
||||
// Deal with ETI
|
||||
template <> struct access_category_tag<int, int> { typedef void type; };
|
||||
template <> struct traversal_category_tag<int> { typedef void type; };
|
||||
# endif
|
||||
|
||||
// iterator_tag_base - a metafunction to compute the appropriate
|
||||
// old-style tag (if any) to use as a base for a new-style tag.
|
||||
template <class KnownAccessTag, class KnownTraversalTag>
|
||||
struct iterator_tag_base
|
||||
: minimum_category<
|
||||
typename KnownAccessTag::max_category
|
||||
, typename KnownTraversalTag::max_category
|
||||
>
|
||||
{};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC,<=1200)
|
||||
template <>
|
||||
struct iterator_tag_base<int,int>
|
||||
: mpl::false_ {}; // just using false_ so that the result will be
|
||||
// a legal base class
|
||||
# endif
|
||||
|
||||
// specialization for this special case. Otherwise we get
|
||||
// input_output_iterator_tag, because the standard hierarchy has a
|
||||
// sudden anomalous distinction between readability and
|
||||
// writability at the level of input iterator/output iterator.
|
||||
template <>
|
||||
struct iterator_tag_base<
|
||||
readable_lvalue_iterator_tag,single_pass_traversal_tag>
|
||||
{
|
||||
typedef std::input_iterator_tag type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Iterator>
|
||||
struct access_category
|
||||
: detail::access_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
, typename detail::iterator_traits<Iterator>::reference>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class Iterator>
|
||||
struct traversal_category
|
||||
: detail::traversal_category_tag<
|
||||
typename detail::iterator_traits<Iterator>::iterator_category
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct old_category_to_traversal<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
template <class Traversal>
|
||||
struct pure_traversal_tag
|
||||
: mpl::apply_if<
|
||||
is_convertible<Traversal,random_access_traversal_tag>
|
||||
, mpl::identity<random_access_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||
, mpl::identity<bidirectional_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,forward_traversal_tag>
|
||||
, mpl::identity<forward_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,single_pass_traversal_tag>
|
||||
, mpl::identity<single_pass_traversal_tag>
|
||||
, mpl::apply_if<
|
||||
is_convertible<Traversal,incrementable_traversal_tag>
|
||||
, mpl::identity<incrementable_traversal_tag>
|
||||
, void
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
||||
template <>
|
||||
struct pure_traversal_tag<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
# endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
//
|
||||
// Convert an iterator category into a traversal tag
|
||||
//
|
||||
template <class Cat>
|
||||
struct iterator_category_to_traversal
|
||||
: mpl::apply_if< // if already convertible to a traversal tag, we're done.
|
||||
is_convertible<Cat,incrementable_traversal_tag>
|
||||
, mpl::identity<Cat>
|
||||
, detail::old_category_to_traversal<Cat>
|
||||
>
|
||||
{};
|
||||
|
||||
// Trait to get an iterator's traversal category
|
||||
template <class Iterator = mpl::_1>
|
||||
struct iterator_traversal
|
||||
: iterator_category_to_traversal<
|
||||
typename boost::detail::iterator_traits<Iterator>::iterator_category
|
||||
>
|
||||
{};
|
||||
|
||||
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template <>
|
||||
struct access_category<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : access_category<T>
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_category<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : traversal_category<T>
|
||||
{};
|
||||
};
|
||||
# endif
|
||||
|
||||
# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <typename T>
|
||||
struct access_category<T*>
|
||||
: mpl::if_<
|
||||
is_const<T>
|
||||
, readable_lvalue_iterator_tag
|
||||
, writable_lvalue_iterator_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct traversal_category<T*>
|
||||
{
|
||||
typedef random_access_traversal_tag type;
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
template <class AccessTag, class TraversalTag>
|
||||
struct iterator_tag
|
||||
: detail::iterator_tag_base<
|
||||
typename detail::max_known_access_tag<AccessTag>::type
|
||||
, typename detail::max_known_traversal_tag<TraversalTag>::type
|
||||
>::type
|
||||
{
|
||||
typedef AccessTag access;
|
||||
typedef TraversalTag traversal;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
struct iterator_traversal<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag
|
||||
: mpl::false_ {};
|
||||
|
||||
template <class R, class T>
|
||||
struct is_boost_iterator_tag<iterator_tag<R,T> >
|
||||
: mpl::true_ {};
|
||||
# else
|
||||
template <class T>
|
||||
struct is_boost_iterator_tag
|
||||
{
|
||||
typedef char (&yes)[1];
|
||||
typedef char (&no)[2];
|
||||
|
||||
template <class R, class U>
|
||||
static yes test(mpl::identity<iterator_tag<R,U> >*);
|
||||
static no test(...);
|
||||
|
||||
static mpl::identity<T>* inst;
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(test(inst)) == sizeof(yes));
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
struct apply : iterator_traversal<T>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct iterator_traversal<mpl::_>
|
||||
: iterator_traversal<mpl::_1>
|
||||
{};
|
||||
# endif
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -15,16 +15,20 @@
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
// Use boost/limits to work around missing limits headers on some compilers
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
@ -56,7 +60,6 @@ namespace boost_concepts {
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME ::boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
@ -64,8 +67,6 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_iterator_tag, access_category>::value));
|
||||
|
||||
reference r = *i; // or perhaps read(x)
|
||||
value_type v(r);
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
@ -73,19 +74,19 @@ namespace boost_concepts {
|
||||
Iterator i;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename ValueType>
|
||||
template <
|
||||
typename Iterator
|
||||
, typename ValueType = typename boost::detail::iterator_traits<Iterator>::value_type
|
||||
>
|
||||
class WritableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_iterator_tag, access_category>::value));
|
||||
|
||||
*i = v; // a good alternative could be something like write(x, v)
|
||||
}
|
||||
ValueType v;
|
||||
@ -95,11 +96,8 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class SwappableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::swappable_iterator_tag, access_category>::value));
|
||||
|
||||
std::iter_swap(i1, i2);
|
||||
}
|
||||
Iterator i1;
|
||||
@ -107,25 +105,25 @@ namespace boost_concepts {
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ReadableLvalueIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
class ReadableLvalueIteratorConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
void constraints()
|
||||
{
|
||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::readable_lvalue_iterator_tag, access_category>::value));
|
||||
|
||||
typedef boost::mpl::or_<
|
||||
boost::is_same<reference, value_type&>,
|
||||
boost::is_same<reference, value_type const&> > correct_reference;
|
||||
typedef boost::mpl::or_<
|
||||
boost::is_same<reference, value_type&>
|
||||
, boost::is_same<reference, value_type const&>
|
||||
> correct_reference;
|
||||
|
||||
BOOST_STATIC_ASSERT(correct_reference::value);
|
||||
BOOST_STATIC_ASSERT(correct_reference::value);
|
||||
|
||||
reference v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
reference v = *i;
|
||||
boost::ignore_unused_variable_warning(v);
|
||||
}
|
||||
Iterator i;
|
||||
};
|
||||
@ -135,7 +133,6 @@ namespace boost_concepts {
|
||||
public:
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename boost::access_category<Iterator>::type access_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires<
|
||||
@ -145,7 +142,6 @@ namespace boost_concepts {
|
||||
boost::function_requires<
|
||||
SwappableIteratorConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::writable_lvalue_iterator_tag, access_category>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
||||
}
|
||||
@ -157,14 +153,19 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class IncrementableIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::incrementable_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::incrementable_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
++i;
|
||||
(void)i++;
|
||||
@ -175,21 +176,26 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class SinglePassIteratorConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< IncrementableIteratorConcept<Iterator> >();
|
||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::single_pass_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::single_pass_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class ForwardTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
|
||||
|
||||
void constraints() {
|
||||
@ -201,19 +207,29 @@ namespace boost_concepts {
|
||||
> difference_type_is_signed_integral;
|
||||
|
||||
BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value);
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::forward_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::forward_traversal_tag
|
||||
>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class BidirectionalTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< ForwardTraversalConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::bidirectional_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
--i;
|
||||
(void)i--;
|
||||
@ -224,14 +240,19 @@ namespace boost_concepts {
|
||||
template <typename Iterator>
|
||||
class RandomAccessTraversalConcept {
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
void constraints() {
|
||||
boost::function_requires< BidirectionalTraversalConcept<Iterator> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::detail::is_tag<boost::random_access_traversal_tag, traversal_category>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_convertible<
|
||||
traversal_category
|
||||
, boost::random_access_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
i += n;
|
||||
i = i + n;
|
||||
@ -326,11 +347,11 @@ namespace detail
|
||||
class InteroperableConcept
|
||||
{
|
||||
public:
|
||||
typedef typename boost::traversal_category<Iterator>::type traversal_category;
|
||||
typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
typedef typename boost::traversal_category<ConstIterator>::type
|
||||
typedef typename boost::iterator_traversal<ConstIterator>::type
|
||||
const_traversal_category;
|
||||
typedef typename boost::detail::iterator_traits<ConstIterator>::difference_type
|
||||
const_difference_type;
|
||||
|
@ -12,15 +12,17 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/interoperable.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <boost/mpl/apply_if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
@ -30,22 +32,8 @@ namespace boost
|
||||
{
|
||||
// This forward declaration is required for the friend declaration
|
||||
// in iterator_core_access
|
||||
template <class I, class V, class AC, class TC, class R, class D> class iterator_facade;
|
||||
template <class I, class V, class TC, class R, class D> class iterator_facade;
|
||||
|
||||
// Used as a default template argument internally, merely to
|
||||
// indicate "use the default", this can also be passed by users
|
||||
// explicitly in order to specify that the default should be used.
|
||||
struct use_default;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// the incompleteness of use_default causes massive problems for
|
||||
// is_convertible (naturally). This workaround is fortunately not
|
||||
// needed for vc6/vc7.
|
||||
template<class To>
|
||||
struct is_convertible<use_default,To>
|
||||
: mpl::false_ {};
|
||||
# endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//
|
||||
@ -75,59 +63,30 @@ namespace boost
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Add const qualification for iterators which are not writable
|
||||
//
|
||||
template<class Value, class AccessCategory>
|
||||
struct const_qualified_ref :
|
||||
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||
Value&,
|
||||
Value const& >
|
||||
{};
|
||||
|
||||
// The apparent duplication here works around a Borland problem
|
||||
template<class Value, class AccessCategory>
|
||||
struct const_qualified_ptr :
|
||||
mpl::if_< is_tag< writable_iterator_tag, AccessCategory >,
|
||||
Value*,
|
||||
Value const* >
|
||||
{};
|
||||
|
||||
//
|
||||
// Generates the associated types for an iterator_facade with the
|
||||
// given parameters. Additionally generates a 'base' type for
|
||||
// compiler/library combinations which require user-defined
|
||||
// iterators to inherit from std::iterator.
|
||||
// Generates associated types for an iterator_facade with the
|
||||
// given parameters.
|
||||
//
|
||||
template <
|
||||
class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference
|
||||
class ValueParam
|
||||
, class CategoryOrTraversal
|
||||
, class Reference
|
||||
, class Difference
|
||||
>
|
||||
struct iterator_facade_types
|
||||
{
|
||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||
typedef typename facade_iterator_category<
|
||||
CategoryOrTraversal, ValueParam, Reference
|
||||
>::type iterator_category;
|
||||
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef typename remove_const<ValueParam>::type value_type;
|
||||
|
||||
typedef Difference difference_type;
|
||||
|
||||
typedef typename const_qualified_ptr<Value, AccessCategory>::type pointer;
|
||||
|
||||
// The use_default support is needed for iterator_adaptor.
|
||||
// For practical reasons iterator_adaptor needs to specify
|
||||
// a fixed number of template arguments of iterator_facade.
|
||||
// So use_default is its way to say: "What I really mean
|
||||
// is your default parameter".
|
||||
typedef typename mpl::if_<
|
||||
is_same<Reference, use_default>
|
||||
, typename const_qualified_ref<Value, AccessCategory>::type
|
||||
, Reference
|
||||
>::type reference;
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
detail::iterator_writability_disabled<ValueParam,Reference>
|
||||
, add_pointer<typename add_const<value_type>::type>
|
||||
, add_pointer<value_type>
|
||||
>::type pointer;
|
||||
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|
||||
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
|
||||
@ -141,7 +100,7 @@ namespace boost
|
||||
# define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
|
||||
|
||||
typedef
|
||||
iterator<iterator_category, value_type, difference_type, pointer, reference>
|
||||
iterator<iterator_category, value_type, Difference, pointer, Reference>
|
||||
base;
|
||||
# endif
|
||||
};
|
||||
@ -205,10 +164,10 @@ namespace boost
|
||||
|
||||
public:
|
||||
operator_brackets_proxy(Iterator const& iter)
|
||||
: m_iter(iter)
|
||||
: m_iter(iter)
|
||||
{}
|
||||
|
||||
operator reference()
|
||||
operator reference() const
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
@ -223,28 +182,24 @@ namespace boost
|
||||
Iterator m_iter;
|
||||
};
|
||||
|
||||
template <class Iterator, class ValueType, class Category, class Reference>
|
||||
template <class Iterator, class Value, class Reference>
|
||||
struct operator_brackets_result
|
||||
{
|
||||
typedef typename access_category_tag<Category,Reference>::type access_category;
|
||||
|
||||
typedef is_tag<writable_iterator_tag, access_category> use_proxy;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
use_proxy
|
||||
typedef typename mpl::if_<
|
||||
iterator_writability_disabled<Value,Reference>
|
||||
, Value
|
||||
, operator_brackets_proxy<Iterator>
|
||||
, ValueType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||
operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||
{
|
||||
return operator_brackets_proxy<Iterator>(iter);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
|
||||
typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::true_)
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
@ -253,20 +208,20 @@ namespace boost
|
||||
|
||||
|
||||
// Macros which describe the declarations of binary operators
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
template < \
|
||||
class Derived1, class V1, class AC1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class AC2, class TC2, class R2, class D2 \
|
||||
> \
|
||||
prefix typename detail::enable_if_interoperable< \
|
||||
Derived1, Derived2, result_type \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, AC1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, AC2, TC2, R2, D2> const& rhs)
|
||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||
template < \
|
||||
class Derived1, class V1, class TC1, class R1, class D1 \
|
||||
, class Derived2, class V2, class TC2, class R2, class D2 \
|
||||
> \
|
||||
prefix typename detail::enable_if_interoperable< \
|
||||
Derived1, Derived2, result_type \
|
||||
>::type \
|
||||
operator op( \
|
||||
iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs \
|
||||
, iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template <class Derived, class V, class AC, class TC, class R, class D> \
|
||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||
template <class Derived, class V, class TC, class R, class D> \
|
||||
prefix Derived operator+ args
|
||||
|
||||
//
|
||||
@ -287,7 +242,7 @@ namespace boost
|
||||
public:
|
||||
# else
|
||||
|
||||
template <class I, class V, class AC, class TC, class R, class D> friend class iterator_facade;
|
||||
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
|
||||
|
||||
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, bool);
|
||||
@ -307,7 +262,7 @@ namespace boost
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (iterator_facade<Derived, V, AC, TC, R, D> const&
|
||||
, (iterator_facade<Derived, V, TC, R, D> const&
|
||||
, typename Derived::difference_type)
|
||||
)
|
||||
;
|
||||
@ -315,7 +270,7 @@ namespace boost
|
||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||
friend
|
||||
, (typename Derived::difference_type
|
||||
, iterator_facade<Derived, V, AC, TC, R, D> const&)
|
||||
, iterator_facade<Derived, V, TC, R, D> const&)
|
||||
)
|
||||
;
|
||||
|
||||
@ -370,26 +325,21 @@ namespace boost
|
||||
template <
|
||||
class Derived // The derived iterator type being constructed
|
||||
, class Value
|
||||
, class AccessCategory
|
||||
, class TraversalCategory
|
||||
, class Reference = BOOST_DEDUCED_TYPENAME detail::const_qualified_ref<Value, AccessCategory>::type
|
||||
, class CategoryOrTraversal
|
||||
, class Reference = Value&
|
||||
, class Difference = std::ptrdiff_t
|
||||
>
|
||||
class iterator_facade
|
||||
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||
: public detail::iterator_facade_types<
|
||||
Value, AccessCategory, TraversalCategory, Reference, Difference
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
>::base
|
||||
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||
# endif
|
||||
{
|
||||
private:
|
||||
typedef typename
|
||||
detail::iterator_facade_types<Value, AccessCategory, TraversalCategory, Reference, Difference>
|
||||
types;
|
||||
|
||||
//
|
||||
// Curiously Recursive Template interface.
|
||||
// Curiously Recurring Template interface.
|
||||
//
|
||||
typedef Derived derived_t;
|
||||
|
||||
@ -403,13 +353,17 @@ namespace boost
|
||||
return static_cast<Derived const&>(*this);
|
||||
}
|
||||
|
||||
typedef detail::iterator_facade_types<
|
||||
Value, CategoryOrTraversal, Reference, Difference
|
||||
> associated_types;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename types::value_type value_type;
|
||||
typedef typename types::reference reference;
|
||||
typedef typename types::difference_type difference_type;
|
||||
typedef typename types::pointer pointer;
|
||||
typedef typename types::iterator_category iterator_category;
|
||||
typedef typename associated_types::value_type value_type;
|
||||
typedef Reference reference;
|
||||
typedef Difference difference_type;
|
||||
typedef typename associated_types::pointer pointer;
|
||||
typedef typename associated_types::iterator_category iterator_category;
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
@ -430,14 +384,16 @@ namespace boost
|
||||
>::make(*this->derived());
|
||||
}
|
||||
|
||||
typename detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::type
|
||||
typename detail::operator_brackets_result<Derived,Value,Reference>::type
|
||||
operator[](difference_type n) const
|
||||
{
|
||||
typedef typename
|
||||
detail::operator_brackets_result<Derived,value_type,iterator_category,reference>::use_proxy
|
||||
use_proxy;
|
||||
typedef detail::iterator_writability_disabled<Value,Reference>
|
||||
not_writable;
|
||||
|
||||
return detail::make_operator_brackets_result<Derived>(this->derived() + n, use_proxy());
|
||||
return detail::make_operator_brackets_result<Derived>(
|
||||
this->derived() + n
|
||||
, not_writable()
|
||||
);
|
||||
}
|
||||
|
||||
Derived& operator++()
|
||||
@ -615,13 +571,13 @@ namespace boost
|
||||
}
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||
iterator_facade<Derived, V, TC, R, D> const& i
|
||||
, typename Derived::difference_type n
|
||||
))
|
||||
|
||||
BOOST_ITERATOR_FACADE_PLUS((
|
||||
typename Derived::difference_type n
|
||||
, iterator_facade<Derived, V, AC, TC, R, D> const& i
|
||||
, iterator_facade<Derived, V, TC, R, D> const& i
|
||||
))
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||
|
@ -24,15 +24,13 @@
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <boost/pending/iterator_tests.hpp>
|
||||
# include <boost/iterator/is_readable_iterator.hpp>
|
||||
# include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
void is_readable(readable_iterator_tag) { }
|
||||
void is_writable(writable_iterator_tag) { }
|
||||
void is_swappable(swappable_iterator_tag) { }
|
||||
void is_constant_lvalue(readable_lvalue_iterator_tag) { }
|
||||
void is_mutable_lvalue(writable_lvalue_iterator_tag) { }
|
||||
|
||||
// Preconditions: *i == v
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_test(const Iterator i1, T v)
|
||||
@ -45,8 +43,12 @@ void readable_iterator_test(const Iterator i1, T v)
|
||||
T v2 = r2;
|
||||
assert(v1 == v);
|
||||
assert(v2 == v);
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_readable(result_category());
|
||||
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
// I think we don't really need this as it checks the same things as
|
||||
// the above code.
|
||||
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
@ -54,7 +56,6 @@ void writable_iterator_test(Iterator i, T v)
|
||||
{
|
||||
Iterator i2(i); // Copy Constructible
|
||||
*i2 = v;
|
||||
is_writable(typename access_category<Iterator>::type());
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
@ -65,8 +66,6 @@ void swappable_iterator_test(Iterator i, Iterator j)
|
||||
iter_swap(i2, j2);
|
||||
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||
assert(bi == aj && bj == ai);
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_swappable(result_category());
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
@ -78,12 +77,14 @@ void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
|
||||
const T& v2 = *i2;
|
||||
assert(v1 == v2);
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_constant_lvalue(result_category());
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
|
||||
@ -91,11 +92,17 @@ void mutable_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
|
||||
T& v3 = *i2;
|
||||
assert(v1 == v3);
|
||||
|
||||
// A non-const lvalue iterator is not neccessarily writable, but we
|
||||
// are assuming the value_type is assignable here
|
||||
*i = v2;
|
||||
|
||||
T& v4 = *i2;
|
||||
assert(v2 == v4);
|
||||
typedef typename access_category<Iterator>::type result_category;
|
||||
is_mutable_lvalue(result_category());
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
@ -159,7 +166,6 @@ void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||
readable_iterator_test(i2, v2);
|
||||
}
|
||||
|
||||
|
||||
// random access
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
@ -169,10 +175,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == j[c]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[c];
|
||||
assert(*i == x);
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
@ -183,10 +191,12 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == j[N - 1 - c]);
|
||||
typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
|
||||
assert(*i == x);
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
@ -197,8 +207,8 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
}
|
||||
}
|
||||
|
||||
// #if 0'd code snipped; see CVS v 1.4 if you need it back
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||
@ -46,53 +48,38 @@ namespace boost
|
||||
};
|
||||
#endif
|
||||
|
||||
// Given the transform iterator's transformation and iterator, this
|
||||
// is the type used as its traits.
|
||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||
struct transform_iterator_base
|
||||
{
|
||||
private:
|
||||
private:
|
||||
// By default, dereferencing the iterator yields the same as
|
||||
// the function. Do we need to adjust the way
|
||||
// function_object_result is computed for the standard
|
||||
// proposal (e.g. using Doug's result_of)?
|
||||
typedef typename ia_dflt_help<
|
||||
Reference
|
||||
, function_object_result<UnaryFunction>
|
||||
>::type reference;
|
||||
|
||||
// transform_iterator does not support writable/swappable iterators
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
||||
#endif
|
||||
|
||||
typedef typename mpl::apply_if<
|
||||
is_same< Reference, use_default >
|
||||
, function_object_result<UnaryFunction>
|
||||
, mpl::identity<Reference>
|
||||
>::type result_type;
|
||||
// To get the default for Value: remove any reference on the
|
||||
// result type, but retain any constness to signal
|
||||
// non-writability. Note that if we adopt Thomas' suggestion
|
||||
// to key non-writability *only* on the Reference argument,
|
||||
// we'd need to strip constness here as well.
|
||||
typedef typename ia_dflt_help<
|
||||
Value
|
||||
, remove_reference<reference>
|
||||
>::type cv_value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_same< Value, use_default >
|
||||
, typename remove_reference< result_type >::type
|
||||
, Value
|
||||
>::type cv_value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_reference< result_type >
|
||||
, typename mpl::if_<
|
||||
is_const< cv_value_type >
|
||||
, readable_lvalue_iterator_tag
|
||||
, writable_lvalue_iterator_tag
|
||||
>::type
|
||||
, readable_iterator_tag
|
||||
>::type maximum_access_tag;
|
||||
|
||||
typedef typename minimum_category<
|
||||
maximum_access_tag
|
||||
, typename access_category<Iterator>::type
|
||||
>::type access_category;
|
||||
|
||||
public:
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, access_category
|
||||
, result_type
|
||||
> type;
|
||||
public:
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, use_default // Leave the traversal category alone
|
||||
, reference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
@ -150,12 +137,16 @@ namespace boost
|
||||
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
||||
}
|
||||
|
||||
// Version which allows explicit specification of the UnaryFunction
|
||||
// type.
|
||||
//
|
||||
// This generator is not provided if UnaryFunction is a function
|
||||
// pointer type, because it's too dangerous: the default-constructed
|
||||
// function pointer in the iterator be 0, leading to a runtime
|
||||
// crash.
|
||||
template <class UnaryFunction, class Iterator>
|
||||
// don't provide this generator if UnaryFunction is a
|
||||
// function pointer type. Too dangerous. We should probably
|
||||
// find a cheaper test than is_class<>
|
||||
typename iterators::enable_if<
|
||||
is_class<UnaryFunction>
|
||||
is_class<UnaryFunction> // We should probably find a cheaper test than is_class<>
|
||||
, transform_iterator<UnaryFunction, Iterator>
|
||||
>::type
|
||||
make_transform_iterator(Iterator it)
|
||||
@ -174,4 +165,6 @@ namespace boost
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/detail/iterator_traits.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/iterator/detail/minimum_category.hpp>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
@ -259,16 +261,17 @@ namespace boost {
|
||||
)
|
||||
{
|
||||
typedef typename tuple_meta_transform<
|
||||
typename Tuple::tail_type
|
||||
BOOST_DEDUCED_TYPENAME Tuple::tail_type
|
||||
, Fun
|
||||
>::type transformed_tail_type;
|
||||
|
||||
return tuples::cons<
|
||||
typename mpl::apply1<Fun, typename Tuple::head_type>::type
|
||||
BOOST_DEDUCED_TYPENAME mpl::apply1<
|
||||
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
|
||||
>::type
|
||||
, transformed_tail_type
|
||||
>(
|
||||
f(boost::tuples::get<0>(t)),
|
||||
tuple_transform(t.get_tail(), f)
|
||||
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
|
||||
);
|
||||
}
|
||||
|
||||
@ -380,12 +383,12 @@ namespace boost {
|
||||
{
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple
|
||||
, traversal_category<mpl::_1>
|
||||
, iterator_traversal<>
|
||||
>::type tuple_of_traversal_tags;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
tuple_of_traversal_tags
|
||||
, minimum_category<mpl::_1,mpl::_2>
|
||||
, minimum_category<>
|
||||
, random_access_traversal_tag
|
||||
>::type type;
|
||||
};
|
||||
@ -398,31 +401,6 @@ namespace boost {
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename Iterator>
|
||||
struct iterator_is_readable
|
||||
: is_tag<
|
||||
readable_iterator_tag
|
||||
, typename access_category<Iterator>::type
|
||||
>
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1, iterator_is_readable, (Iterator))
|
||||
};
|
||||
|
||||
# ifdef BOOST_MPL_NO_FULL_LAMBDA_SUPPORT
|
||||
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
|
||||
// out well. Instantiating the nested apply template also
|
||||
// requires instantiating iterator_traits on the
|
||||
// placeholder. Instead we just specialize it as a metafunction
|
||||
// class.
|
||||
template <>
|
||||
struct iterator_is_readable<mpl::_1>
|
||||
{
|
||||
template <class T>
|
||||
struct apply : iterator_is_readable<T>
|
||||
{};
|
||||
};
|
||||
# endif
|
||||
|
||||
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
||||
// accumulating functor. To this end, we need to wrap it into
|
||||
// a struct that has exactly two arguments (that is, template
|
||||
@ -446,28 +424,6 @@ namespace boost {
|
||||
};
|
||||
# endif
|
||||
|
||||
// Metafunction to assert that all iterators in a tuple are
|
||||
// readable.
|
||||
//
|
||||
// Probably not worth it, IMO. Why not a writable zip_iterator
|
||||
// anyway? -- dwa.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct all_iterators_in_tuple_readable
|
||||
{
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple,
|
||||
iterator_is_readable<mpl::_1>
|
||||
>::type tuple_of_readability_bools;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
tuple_of_readability_bools,
|
||||
and_with_two_args<mpl::_1,mpl::_2>
|
||||
, mpl::bool_<true>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class zip_iterator_base
|
||||
@ -479,14 +435,6 @@ namespace boost {
|
||||
struct zip_iterator_base
|
||||
{
|
||||
private:
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
// seems to give vc7's parser fits, and vc6 needs help here too
|
||||
BOOST_STATIC_ASSERT(
|
||||
detail::all_iterators_in_tuple_readable<
|
||||
IteratorTuple
|
||||
>::type::value
|
||||
);
|
||||
#endif
|
||||
// Reference type is the type of the tuple obtained from the
|
||||
// iterators' reference types.
|
||||
typedef typename
|
||||
@ -506,11 +454,6 @@ namespace boost {
|
||||
detail::minimum_traversal_category_in_iterator_tuple<
|
||||
IteratorTuple
|
||||
>::type traversal_category;
|
||||
|
||||
// Access category is readable_iterator_tag. It has been
|
||||
// asserted that all iterators in the tuple are readable.
|
||||
typedef readable_iterator_tag access_category;
|
||||
|
||||
public:
|
||||
|
||||
// The iterator facade type from which the zip iterator will
|
||||
@ -518,7 +461,6 @@ namespace boost {
|
||||
typedef iterator_facade<
|
||||
zip_iterator<IteratorTuple>,
|
||||
value_type,
|
||||
access_category,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
@ -616,7 +558,7 @@ namespace boost {
|
||||
{
|
||||
detail::tuple_impl_specific::tuple_for_each(
|
||||
m_iterator_tuple,
|
||||
detail::advance_iterator<typename super_t::difference_type>(n)
|
||||
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
|
||||
);
|
||||
}
|
||||
// Incrementing a zip iterator means to increment all iterators in
|
||||
|
@ -1,13 +0,0 @@
|
||||
// Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_ITERATOR_ADAPTOR_13062003HK_HPP
|
||||
#define BOOST_ITERATOR_ADAPTOR_13062003HK_HPP
|
||||
|
||||
#define BOOST_ITERATOR_ADAPTORS_VERSION 0x0200
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTOR_13062003HK_HPP
|
@ -1,75 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_INT_ITERATOR_H
|
||||
#define BOOST_INT_ITERATOR_H
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#if !defined BOOST_MSVC
|
||||
#include <boost/operators.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
//using namespace std;
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
#endif
|
||||
|
||||
// this should use random_access_iterator_helper but I've had
|
||||
// VC++ portablility problems with that. -JGS
|
||||
template <class IntT>
|
||||
class int_iterator
|
||||
{
|
||||
typedef int_iterator self;
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef IntT value_type;
|
||||
typedef IntT& reference;
|
||||
typedef IntT* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
inline int_iterator() : _i(0) { }
|
||||
inline int_iterator(IntT i) : _i(i) { }
|
||||
inline int_iterator(const self& x) : _i(x._i) { }
|
||||
inline self& operator=(const self& x) { _i = x._i; return *this; }
|
||||
inline IntT operator*() { return _i; }
|
||||
inline IntT operator[](IntT n) { return _i + n; }
|
||||
inline self& operator++() { ++_i; return *this; }
|
||||
inline self operator++(int) { self t = *this; ++_i; return t; }
|
||||
inline self& operator+=(IntT n) { _i += n; return *this; }
|
||||
inline self operator+(IntT n) { self t = *this; t += n; return t; }
|
||||
inline self& operator--() { --_i; return *this; }
|
||||
inline self operator--(int) { self t = *this; --_i; return t; }
|
||||
inline self& operator-=(IntT n) { _i -= n; return *this; }
|
||||
inline IntT operator-(const self& x) const { return _i - x._i; }
|
||||
inline bool operator==(const self& x) const { return _i == x._i; }
|
||||
// vc++ had a problem finding != in random_access_iterator_helper
|
||||
// need to look into this... for now implementing everything here -JGS
|
||||
inline bool operator!=(const self& x) const { return _i != x._i; }
|
||||
inline bool operator<(const self& x) const { return _i < x._i; }
|
||||
inline bool operator<=(const self& x) const { return _i <= x._i; }
|
||||
inline bool operator>(const self& x) const { return _i > x._i; }
|
||||
inline bool operator>=(const self& x) const { return _i >= x._i; }
|
||||
protected:
|
||||
IntT _i;
|
||||
};
|
||||
|
||||
template <class IntT>
|
||||
inline int_iterator<IntT>
|
||||
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
} /* namespace boost */
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
using ::int_iterator;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* BOOST_INT_ITERATOR_H */
|
@ -1,59 +0,0 @@
|
||||
// (C) Copyright David Abrahams and Jeremy Siek 2000-2001. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its suitability
|
||||
// for any purpose.
|
||||
//
|
||||
// Revision History:
|
||||
// 04 Jan 2001 Factored counting_iterator stuff into
|
||||
// boost/counting_iterator.hpp (David Abrahams)
|
||||
|
||||
#ifndef BOOST_INTEGER_RANGE_HPP_
|
||||
#define BOOST_INTEGER_RANGE_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//=============================================================================
|
||||
// Counting Iterator and Integer Range Class
|
||||
|
||||
template <class IntegerType>
|
||||
struct integer_range {
|
||||
typedef counting_iterator<IntegerType> iterator;
|
||||
|
||||
typedef iterator const_iterator;
|
||||
typedef IntegerType value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef IntegerType reference;
|
||||
typedef IntegerType const_reference;
|
||||
typedef const IntegerType* pointer;
|
||||
typedef const IntegerType* const_pointer;
|
||||
typedef IntegerType size_type;
|
||||
|
||||
integer_range(IntegerType start, IntegerType finish)
|
||||
: m_start(start), m_finish(finish) { }
|
||||
|
||||
iterator begin() const { return iterator(m_start); }
|
||||
iterator end() const { return iterator(m_finish); }
|
||||
size_type size() const { return m_finish - m_start; }
|
||||
bool empty() const { return m_finish == m_start; }
|
||||
void swap(integer_range& x) {
|
||||
std::swap(m_start, x.m_start);
|
||||
std::swap(m_finish, x.m_finish);
|
||||
}
|
||||
protected:
|
||||
IntegerType m_start, m_finish;
|
||||
};
|
||||
|
||||
template <class IntegerType>
|
||||
inline integer_range<IntegerType>
|
||||
make_integer_range(IntegerType first, IntegerType last)
|
||||
{
|
||||
return integer_range<IntegerType>(first, last);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INTEGER_RANGE_HPP_
|
@ -1,7 +0,0 @@
|
||||
// Copyright David Abrahams 2003. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
@ -1,258 +0,0 @@
|
||||
// Copyright David Abrahams and Jeremy Siek 2003. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided
|
||||
// this copyright notice appears in all copies. This software is
|
||||
// provided "as is" without express or implied warranty, and with no
|
||||
// claim as to its suitability for any purpose.
|
||||
#ifndef BOOST_ITERATOR_TESTS_HPP
|
||||
# define BOOST_ITERATOR_TESTS_HPP
|
||||
|
||||
// This is meant to be the beginnings of a comprehensive, generic
|
||||
// test suite for STL concepts such as iterators and containers.
|
||||
//
|
||||
// Revision History:
|
||||
// 28 Apr 2002 Fixed input iterator requirements.
|
||||
// For a == b a++ == b++ is no longer required.
|
||||
// See 24.1.1/3 for details.
|
||||
// (Thomas Witt)
|
||||
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||
// --i is no longer a precondition.
|
||||
// (Jeremy Siek)
|
||||
// 04 Feb 2001 Added lvalue test, corrected preconditions
|
||||
// (David Abrahams)
|
||||
|
||||
# include <iterator>
|
||||
# include <assert.h>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
|
||||
namespace boost {
|
||||
|
||||
// use this for the value type
|
||||
struct dummyT {
|
||||
dummyT() { }
|
||||
dummyT(detail::dummy_constructor) { }
|
||||
dummyT(int x) : m_x(x) { }
|
||||
int foo() const { return m_x; }
|
||||
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
|
||||
int m_x;
|
||||
};
|
||||
|
||||
|
||||
// Tests whether type Iterator satisfies the requirements for a
|
||||
// TrivialIterator.
|
||||
// Preconditions: i != j, *i == val
|
||||
template <class Iterator, class T>
|
||||
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
{
|
||||
Iterator k;
|
||||
assert(i == i);
|
||||
assert(j == j);
|
||||
assert(i != j);
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
T v = *i;
|
||||
#else
|
||||
typename std::iterator_traits<Iterator>::value_type v = *i;
|
||||
#endif
|
||||
assert(v == val);
|
||||
#if 0
|
||||
// hmm, this will give a warning for transform_iterator... perhaps
|
||||
// this should be separated out into a stand-alone test since there
|
||||
// are several situations where it can't be used, like for
|
||||
// integer_range::iterator.
|
||||
assert(v == i->foo());
|
||||
#endif
|
||||
k = i;
|
||||
assert(k == k);
|
||||
assert(k == i);
|
||||
assert(k != j);
|
||||
assert(*k == val);
|
||||
}
|
||||
|
||||
|
||||
// Preconditions: i != j
|
||||
template <class Iterator, class T>
|
||||
void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
{
|
||||
*i = val;
|
||||
trivial_iterator_test(i, j, val);
|
||||
}
|
||||
|
||||
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void input_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i1(i);
|
||||
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
// I can see no generic way to create an input iterator
|
||||
// that is in the domain of== of i and != i.
|
||||
// The following works for istream_iterator but is not
|
||||
// guaranteed to work for arbitrary input iterators.
|
||||
//
|
||||
// Iterator i2;
|
||||
//
|
||||
// assert(i != i2);
|
||||
// assert(!(i == i2));
|
||||
|
||||
assert(*i1 == v1);
|
||||
assert(*i == v1);
|
||||
|
||||
// we cannot test for equivalence of (void)++i & (void)i++
|
||||
// as i is only guaranteed to be single pass.
|
||||
assert(*i++ == v1);
|
||||
|
||||
i1 = i;
|
||||
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
assert(*i1 == v2);
|
||||
assert(*i == v2);
|
||||
|
||||
// i is dereferencable, so it must be incrementable.
|
||||
++i;
|
||||
|
||||
// how to test for operator-> ?
|
||||
}
|
||||
|
||||
// how to test output iterator?
|
||||
|
||||
|
||||
template <bool is_pointer> struct lvalue_test
|
||||
{
|
||||
template <class Iterator> static void check(Iterator)
|
||||
{
|
||||
# ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
# else
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
# endif
|
||||
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
|
||||
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
|
||||
|| boost::is_same<reference,const value_type&>::value
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
template <> struct lvalue_test<true> {
|
||||
template <class T> static void check(T) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
input_iterator_test(i, v1, v2);
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
assert(i == i1++);
|
||||
assert(i != ++i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v1);
|
||||
trivial_iterator_test(i, i2, v1);
|
||||
|
||||
++i;
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
trivial_iterator_test(i, i1, v2);
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
// borland doesn't allow non-type template parameters
|
||||
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
|
||||
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void bidirectional_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
forward_iterator_test(i, v1, v2);
|
||||
++i;
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
assert(i == i1--);
|
||||
assert(i != --i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v2);
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
--i;
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
trivial_iterator_test(i, i1, v1);
|
||||
trivial_iterator_test(i, i2, v1);
|
||||
}
|
||||
|
||||
// mutable_bidirectional_iterator_test
|
||||
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
{
|
||||
bidirectional_iterator_test(i, vals[0], vals[1]);
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == j[c]);
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == j[N - 1 - c]);
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
// Precondition: i != j
|
||||
template <class Iterator, class ConstIterator>
|
||||
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
|
||||
{
|
||||
assert(i != j);
|
||||
assert(j != i);
|
||||
|
||||
ConstIterator k(i);
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
|
||||
k = i;
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_TESTS_HPP
|
@ -1,62 +0,0 @@
|
||||
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
|
||||
|
||||
#ifndef SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||
#define SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||
|
||||
#include "boost/iterator_adaptors.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename Container>
|
||||
class shared_container_iterator : public iterator_adaptor<
|
||||
shared_container_iterator<Container>,
|
||||
typename Container::iterator> {
|
||||
|
||||
typedef iterator_adaptor<
|
||||
shared_container_iterator<Container>,
|
||||
typename Container::iterator> super_t;
|
||||
|
||||
typedef typename Container::iterator iterator_t;
|
||||
typedef boost::shared_ptr<Container> container_ref_t;
|
||||
|
||||
container_ref_t container_ref;
|
||||
public:
|
||||
shared_container_iterator() { }
|
||||
|
||||
shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
|
||||
super_t(x), container_ref(c) { }
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
shared_container_iterator<Container>
|
||||
make_shared_container_iterator(typename Container::iterator iter,
|
||||
boost::shared_ptr<Container> const& container) {
|
||||
typedef shared_container_iterator<Container> iterator;
|
||||
return iterator(iter,container);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename Container>
|
||||
std::pair<
|
||||
shared_container_iterator<Container>,
|
||||
shared_container_iterator<Container> >
|
||||
make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
||||
return
|
||||
std::make_pair(
|
||||
make_shared_container_iterator(container->begin(),container),
|
||||
make_shared_container_iterator(container->end(),container));
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
@ -18,7 +18,12 @@ test-suite iterator
|
||||
# compilation problems.
|
||||
[ run is_convertible_fail.cpp ]
|
||||
|
||||
[ run zip_iterator_test.cpp ]
|
||||
|
||||
# These tests should work for just about everything.
|
||||
[ compile is_lvalue_iterator.cpp ]
|
||||
[ compile is_readable_iterator.cpp ]
|
||||
|
||||
[ run unit_tests.cpp ]
|
||||
[ run concept_tests.cpp ]
|
||||
[ run iterator_adaptor_cc.cpp ]
|
||||
@ -31,7 +36,6 @@ test-suite iterator
|
||||
[ run counting_iterator_test.cpp ]
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
]
|
||||
[ run zip_iterator_test.cpp ]
|
||||
|
||||
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
||||
[ run ../../utility/counting_iterator_example.cpp ]
|
||||
|
44
test/Jamfile.v2
Normal file
44
test/Jamfile.v2
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright David Abrahams 2003. Permission to copy, use,
|
||||
# modify, sell and distribute this software is granted provided this
|
||||
# copyright notice appears in all copies. This software is provided
|
||||
# "as is" without express or implied warranty, and with no claim as
|
||||
# to its suitability for any purpose.
|
||||
|
||||
import testing ;
|
||||
|
||||
test-suite iterator
|
||||
:
|
||||
# These first two tests will run last, and are expected to fail
|
||||
# for many less-capable compilers.
|
||||
|
||||
[ compile-fail interoperable_fail.cpp ]
|
||||
# test uses expected success, so that we catch unrelated
|
||||
# compilation problems.
|
||||
[ run is_convertible_fail.cpp ]
|
||||
|
||||
# These tests should work for just about everything.
|
||||
[ run unit_tests.cpp ]
|
||||
[ run concept_tests.cpp ]
|
||||
[ run iterator_adaptor_cc.cpp ]
|
||||
[ run iterator_adaptor_test.cpp ]
|
||||
[ compile iterator_archetype_cc.cpp ]
|
||||
[ run transform_iterator_test.cpp ]
|
||||
[ run indirect_iterator_test.cpp ]
|
||||
[ run filter_iterator_test.cpp ]
|
||||
[ run reverse_iterator_test.cpp ]
|
||||
[ run counting_iterator_test.cpp ]
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
]
|
||||
[ run zip_iterator_test.cpp ]
|
||||
|
||||
[ run ../../utility/iterator_adaptor_examples.cpp ]
|
||||
[ run ../../utility/counting_iterator_example.cpp ]
|
||||
[ run ../../utility/filter_iterator_example.cpp ]
|
||||
[ run ../../utility/fun_out_iter_example.cpp ]
|
||||
[ run ../../utility/indirect_iterator_example.cpp ]
|
||||
[ run ../../utility/projection_iterator_example.cpp ]
|
||||
[ run ../../utility/reverse_iterator_example.cpp ]
|
||||
[ run ../../utility/transform_iterator_example.cpp ]
|
||||
[ run ../../utility/iterator_traits_test.cpp ]
|
||||
|
||||
;
|
@ -5,15 +5,16 @@
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/iterator/iterator_concepts.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp> // remove
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include "static_assert_same.hpp" // remove
|
||||
|
||||
struct new_random_access
|
||||
: std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
{};
|
||||
|
||||
struct new_iterator
|
||||
: public boost::iterator< boost::iterator_tag<
|
||||
boost::writable_lvalue_iterator_tag
|
||||
, boost::random_access_traversal_tag>, int>
|
||||
: public boost::iterator< new_random_access, int >
|
||||
{
|
||||
int& operator*() const { return *m_x; }
|
||||
new_iterator& operator++() { return *this; }
|
||||
@ -52,103 +53,13 @@ struct old_iterator
|
||||
};
|
||||
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
||||
|
||||
struct my_writable_lvalue_iterator_tag
|
||||
{
|
||||
operator boost::writable_lvalue_iterator_tag() const;
|
||||
};
|
||||
|
||||
struct my_single_pass_traversal_tag
|
||||
{
|
||||
operator boost::single_pass_traversal_tag() const;
|
||||
};
|
||||
|
||||
void test_tag_convertibility()
|
||||
{
|
||||
// This set of tests is by no means complete.
|
||||
|
||||
// Test that this is an input/output iterator
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
boost::writable_lvalue_iterator_tag
|
||||
, boost::single_pass_traversal_tag
|
||||
> tag;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
|
||||
// Test that it's possible to build new sub-tags without
|
||||
// derivation. Convertibility should be enough
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
my_writable_lvalue_iterator_tag
|
||||
, my_single_pass_traversal_tag
|
||||
> tag;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
|
||||
// Test that a single-pass readable lvalue iterator is only an
|
||||
// input iterator. Requires special case handling in
|
||||
// categories.hpp
|
||||
{
|
||||
typedef boost::iterator_tag<
|
||||
boost::readable_lvalue_iterator_tag
|
||||
, boost::single_pass_traversal_tag
|
||||
> tag;
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||
));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test_tag_convertibility();
|
||||
|
||||
typedef boost::iterator_tag< boost::writable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag;
|
||||
|
||||
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<tag>::value));
|
||||
int test = static_assert_same<tag::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<tag::traversal, boost::random_access_traversal_tag>::value;
|
||||
|
||||
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<new_iterator::iterator_category>::value));
|
||||
test = static_assert_same<new_iterator::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<new_iterator::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||
|
||||
typedef boost::traversal_category<new_iterator>::type traversal_category;
|
||||
|
||||
// BOOST_STATIC_ASSERT(boost::detail::has_traversal<new_iterator::iterator_category>::value);
|
||||
BOOST_STATIC_ASSERT(boost::detail::is_new_iterator_tag<new_iterator::iterator_category>::value);
|
||||
|
||||
|
||||
test = static_assert_same<traversal_category, boost::random_access_traversal_tag>::value;
|
||||
(void)test;
|
||||
|
||||
boost::iterator_traversal<new_iterator>::type tc;
|
||||
boost::random_access_traversal_tag derived = tc;
|
||||
(void)derived;
|
||||
|
||||
boost::function_requires<
|
||||
boost_concepts::WritableLvalueIteratorConcept<int*> >();
|
||||
boost::function_requires<
|
||||
|
@ -286,7 +286,7 @@ int main()
|
||||
# ifndef BOOST_NO_SLIST
|
||||
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
|
||||
# endif
|
||||
|
||||
|
||||
// Also prove that we can handle raw pointers.
|
||||
int array[2000];
|
||||
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));
|
||||
|
@ -7,13 +7,12 @@
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/iterator/new_iterator_tests.hpp>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
|
||||
using boost::dummyT;
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
struct one_or_four
|
||||
{
|
||||
@ -38,12 +37,12 @@ int main()
|
||||
filter_iter(one_or_four(), array, array+N)
|
||||
, dummyT(1), dummyT(4));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!boost::detail::is_tag<
|
||||
boost::random_access_traversal_tag
|
||||
, boost::traversal_category<filter_iter>::type
|
||||
>::value
|
||||
));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(!boost::is_convertible<
|
||||
boost::iterator_traversal<filter_iter>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value
|
||||
));
|
||||
|
||||
//# endif
|
||||
|
||||
|
@ -46,8 +46,7 @@
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
|
||||
using boost::dummyT;
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<boost::dummyT>)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<dummyT>)
|
||||
|
||||
typedef std::vector<int> storage;
|
||||
typedef std::vector<int*> pointer_ra_container;
|
||||
|
145
test/is_lvalue_iterator.cpp
Executable file
145
test/is_lvalue_iterator.cpp
Executable file
@ -0,0 +1,145 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
#include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
struct v
|
||||
{
|
||||
v();
|
||||
~v();
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(v)
|
||||
|
||||
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
||||
{
|
||||
v operator*() const;
|
||||
};
|
||||
|
||||
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
|
||||
{
|
||||
boost::noncopyable const& operator*() const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct proxy_iterator
|
||||
: boost::iterator<std::output_iterator_tag,T>
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
typedef boost::iterator<std::input_iterator_tag,value_type> base;
|
||||
typedef base::iterator_category iterator_category;
|
||||
typedef base::difference_type difference_type;
|
||||
typedef base::pointer pointer;
|
||||
typedef base::reference reference;
|
||||
#endif
|
||||
|
||||
struct proxy
|
||||
{
|
||||
operator value_type&() const;
|
||||
proxy& operator=(value_type) const;
|
||||
};
|
||||
|
||||
proxy operator*() const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lvalue_iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T difference_type;
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T* pointer;
|
||||
|
||||
T& operator*() const;
|
||||
lvalue_iterator& operator++();
|
||||
lvalue_iterator operator++(int);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct constant_lvalue_iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T difference_type;
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef T const* pointer;
|
||||
|
||||
T const& operator*() const;
|
||||
constant_lvalue_iterator& operator++();
|
||||
constant_lvalue_iterator operator++(int);
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<v>::proxy)
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<int>::proxy)
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
|
||||
#endif
|
||||
// Make sure inaccessible copy constructor doesn't prevent
|
||||
// reference binding
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
|
||||
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
|
||||
|
||||
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
|
||||
|
||||
return 0;
|
||||
}
|
93
test/is_readable_iterator.cpp
Executable file
93
test/is_readable_iterator.cpp
Executable file
@ -0,0 +1,93 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
#include <boost/iterator/is_readable_iterator.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
struct v
|
||||
{
|
||||
v();
|
||||
~v();
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(v)
|
||||
|
||||
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
||||
{
|
||||
v operator*() const;
|
||||
};
|
||||
|
||||
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
|
||||
{
|
||||
boost::noncopyable const& operator*() const;
|
||||
};
|
||||
|
||||
struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
|
||||
{
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
typedef boost::iterator<std::input_iterator_tag,v> base;
|
||||
typedef base::iterator_category iterator_category;
|
||||
typedef base::value_type value_type;
|
||||
typedef base::difference_type difference_type;
|
||||
typedef base::pointer pointer;
|
||||
typedef base::reference reference;
|
||||
#endif
|
||||
|
||||
struct proxy
|
||||
{
|
||||
operator v&();
|
||||
proxy& operator=(v) const;
|
||||
};
|
||||
|
||||
proxy operator*() const;
|
||||
};
|
||||
|
||||
struct proxy_iterator2 : boost::iterator<std::output_iterator_tag,v>
|
||||
{
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2)
|
||||
typedef boost::iterator<std::input_iterator_tag,v> base;
|
||||
typedef base::iterator_category iterator_category;
|
||||
typedef base::value_type value_type;
|
||||
typedef base::difference_type difference_type;
|
||||
typedef base::pointer pointer;
|
||||
typedef base::reference reference;
|
||||
#endif
|
||||
|
||||
struct proxy
|
||||
{
|
||||
proxy& operator=(v) const;
|
||||
};
|
||||
|
||||
proxy operator*() const;
|
||||
};
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy)
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v const*>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::iterator>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::const_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v> > >::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::ostream_iterator<v> >::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<proxy_iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<proxy_iterator2>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<value_iterator>::value);
|
||||
|
||||
// Make sure inaccessible copy constructor doesn't prevent
|
||||
// readability
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<noncopyable_iterator>::value);
|
||||
|
||||
return 0;
|
||||
}
|
@ -14,6 +14,10 @@
|
||||
#include <numeric>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
# include <boost/iterator/is_readable_iterator.hpp>
|
||||
# include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
#endif
|
||||
#include <boost/pending/iterator_tests.hpp>
|
||||
|
||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
@ -26,7 +30,7 @@
|
||||
|
||||
#include "static_assert_same.hpp"
|
||||
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
@ -83,7 +87,7 @@ struct ptr_iterator
|
||||
ptr_iterator<V>
|
||||
, V*
|
||||
, V
|
||||
, std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
, V&
|
||||
#endif
|
||||
@ -94,7 +98,7 @@ private:
|
||||
ptr_iterator<V>
|
||||
, V*
|
||||
, V
|
||||
, std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
, V&
|
||||
#endif
|
||||
@ -114,13 +118,13 @@ public:
|
||||
};
|
||||
|
||||
// Non-functional iterator for category modification checking
|
||||
template <class Iter, class Category>
|
||||
struct modify_category
|
||||
template <class Iter, class Traversal>
|
||||
struct modify_traversal
|
||||
: boost::iterator_adaptor<
|
||||
modify_category<Iter, Category>
|
||||
modify_traversal<Iter, Traversal>
|
||||
, Iter
|
||||
, boost::use_default
|
||||
, Category
|
||||
, Traversal
|
||||
>
|
||||
{};
|
||||
|
||||
@ -179,6 +183,33 @@ struct constant_iterator
|
||||
: base_t(it) {}
|
||||
};
|
||||
|
||||
char (& traversal2(boost::incrementable_traversal_tag) )[1];
|
||||
char (& traversal2(boost::single_pass_traversal_tag ) )[2];
|
||||
char (& traversal2(boost::forward_traversal_tag ) )[3];
|
||||
char (& traversal2(boost::bidirectional_traversal_tag) )[4];
|
||||
char (& traversal2(boost::random_access_traversal_tag) )[5];
|
||||
|
||||
template <class Cat>
|
||||
struct traversal3
|
||||
{
|
||||
static typename boost::iterator_category_to_traversal<Cat>::type x;
|
||||
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
|
||||
typedef char (&type)[value];
|
||||
};
|
||||
|
||||
template <class Cat>
|
||||
typename traversal3<Cat>::type traversal(Cat);
|
||||
|
||||
template <class Iter, class Trav>
|
||||
int static_assert_traversal(Iter* = 0, Trav* = 0)
|
||||
{
|
||||
typedef typename boost::iterator_category_to_traversal<
|
||||
BOOST_DEDUCED_TYPENAME Iter::iterator_category
|
||||
>::type t2;
|
||||
|
||||
return static_assert_same<Trav,t2>::value;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
@ -219,7 +250,17 @@ main()
|
||||
typedef ptr_iterator<int const> Iter1;
|
||||
test = static_assert_same<Iter1::value_type, int>::value;
|
||||
test = static_assert_same<Iter1::reference, const int&>::value;
|
||||
test = static_assert_same<Iter1::iterator_category::access, boost::readable_lvalue_iterator_tag>::value; test = static_assert_same<Iter1::pointer, const int*>::value;
|
||||
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
|
||||
test = static_assert_same<Iter1::pointer, int const*>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
@ -229,19 +270,19 @@ main()
|
||||
|
||||
test = static_assert_same<Iter::value_type, int>::value;
|
||||
test = static_assert_same<Iter::reference, int const&>::value;
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
|
||||
test = static_assert_same<Iter::pointer, int const*>::value;
|
||||
#endif
|
||||
|
||||
test = static_assert_same<BaseIter::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||
test = static_assert_same<Iter::iterator_category::access, boost::readable_lvalue_iterator_tag>::value;
|
||||
|
||||
// Test category modification
|
||||
typedef modify_category<BaseIter, boost::readable_iterator_tag> ReadableIter;
|
||||
test = static_assert_same<ReadableIter::iterator_category::access, boost::readable_iterator_tag>::value;
|
||||
|
||||
typedef modify_category<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
|
||||
test = static_assert_same<BaseIter::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||
test = static_assert_same<IncrementableIter::iterator_category::traversal, boost::incrementable_traversal_tag>::value;
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
|
||||
#endif
|
||||
|
||||
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
|
||||
|
||||
static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
|
||||
static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
|
||||
}
|
||||
|
||||
// Test the iterator_adaptor
|
||||
|
@ -12,14 +12,15 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef boost::iterator_archetype<int,
|
||||
boost::writable_lvalue_iterator_tag,
|
||||
boost::random_access_traversal_tag> iter;
|
||||
typedef boost::iterator_archetype<
|
||||
int
|
||||
, boost::iterator_archetypes::writable_lvalue_iterator_t
|
||||
, boost::random_access_traversal_tag
|
||||
> iter;
|
||||
|
||||
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
||||
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
||||
}
|
||||
return 0; // keep msvc happy
|
||||
|
||||
return 0; // keep msvc happy
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
// Test reverse iterator
|
||||
int main()
|
||||
{
|
||||
|
@ -10,13 +10,17 @@
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U>
|
||||
struct static_assert_same;
|
||||
struct static_assert_same_base;
|
||||
|
||||
template <class T>
|
||||
struct static_assert_same<T,T>
|
||||
struct static_assert_same_base<T,T>
|
||||
{
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct static_assert_same : static_assert_same_base<T,U> {};
|
||||
|
||||
#else
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
|
@ -184,17 +184,14 @@ main()
|
||||
for (int k2 = 0; k2 < N; ++k2)
|
||||
x[k2] = x[k2] * 2;
|
||||
|
||||
boost::input_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||
, x[0]
|
||||
, x[1]);
|
||||
boost::input_iterator_test(
|
||||
boost::make_transform_iterator(y, mult_2), x[0], x[1]);
|
||||
|
||||
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_2)
|
||||
, x[0]
|
||||
, x[1]);
|
||||
boost::input_iterator_test(
|
||||
boost::make_transform_iterator(&y[0], mult_2), x[0], x[1]);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||
, N
|
||||
, x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator(y, mult_2), N, x);
|
||||
|
||||
}
|
||||
|
||||
@ -213,25 +210,34 @@ main()
|
||||
|
||||
}
|
||||
|
||||
std::copy(x,
|
||||
x + N,
|
||||
boost::make_transform_iterator((pair_t*)values, select_first()));
|
||||
std::copy(
|
||||
x
|
||||
, x + N
|
||||
, boost::make_transform_iterator((pair_t*)values, select_first())
|
||||
);
|
||||
|
||||
std::copy(y,
|
||||
y + N,
|
||||
boost::make_transform_iterator((pair_t*)values, select_second()));
|
||||
std::copy(
|
||||
y
|
||||
, y + N
|
||||
, boost::make_transform_iterator((pair_t*)values, select_second())
|
||||
);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, value_select_first()),
|
||||
N,
|
||||
x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, value_select_first())
|
||||
, N
|
||||
, x
|
||||
);
|
||||
|
||||
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()),
|
||||
N,
|
||||
x);
|
||||
boost::random_access_readable_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, const_select_first())
|
||||
, N, x
|
||||
);
|
||||
|
||||
boost::constant_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
|
||||
boost::constant_lvalue_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
|
||||
|
||||
boost::mutable_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
|
||||
boost::non_const_lvalue_iterator_test(
|
||||
boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,12 @@
|
||||
// to its suitability for any purpose.
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "static_assert_same.hpp"
|
||||
|
||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
#include <boost/iterator/detail/minimum_category.hpp>
|
||||
|
||||
struct X { int a; };
|
||||
|
||||
@ -40,29 +43,32 @@ void category_test()
|
||||
using namespace boost::detail;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!is_tag<
|
||||
input_output_iterator_tag
|
||||
, std::input_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
!is_tag<
|
||||
input_output_iterator_tag
|
||||
, std::output_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
!boost::is_convertible<
|
||||
std::input_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
!boost::is_convertible<
|
||||
std::output_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_tag<
|
||||
boost::is_convertible<
|
||||
input_output_iterator_tag
|
||||
, std::forward_iterator_tag>::value));
|
||||
, std::input_iterator_tag>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<
|
||||
input_output_iterator_tag
|
||||
, std::output_iterator_tag>::value));
|
||||
|
||||
#if 0 // This seems wrong; we're not advertising
|
||||
// input_output_iterator_tag are we?
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_convertible<
|
||||
std::forward_iterator_tag
|
||||
, input_output_iterator_tag>::value));
|
||||
#endif
|
||||
|
||||
int test = static_assert_min_cat<
|
||||
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
|
||||
@ -72,9 +78,11 @@ void category_test()
|
||||
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
|
||||
>::value;
|
||||
|
||||
#if 0
|
||||
test = static_assert_min_cat<
|
||||
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
|
||||
>::value;
|
||||
#endif
|
||||
|
||||
test = static_assert_min_cat<
|
||||
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
|
||||
@ -84,29 +92,13 @@ void category_test()
|
||||
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
|
||||
>::value;
|
||||
|
||||
#if 0 // This would be wrong: a random access iterator is not
|
||||
// neccessarily writable, as is an output iterator.
|
||||
test = static_assert_min_cat<
|
||||
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
||||
>::value;
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< incrementable_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< single_pass_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< forward_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< bidirectional_traversal_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_traversal_tag< random_access_traversal_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_traversal_tag< readable_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< swappable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_writable_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< readable_lvalue_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((is_access_tag< writable_lvalue_iterator_tag >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< std::input_iterator_tag >::value));
|
||||
BOOST_STATIC_ASSERT((!is_access_tag< incrementable_traversal_tag >::value));
|
||||
|
||||
(void)test;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user