mirror of
https://github.com/boostorg/iterator.git
synced 2025-06-29 14:01:01 +02:00
Compare commits
40 Commits
boost-1.22
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
abffbb8300 | |||
34c159dd8d | |||
b22a3adc02 | |||
4a24e0f401 | |||
3844edc4bf | |||
fdd1601ba4 | |||
e9b33b336c | |||
2574365b5c | |||
12b9366f33 | |||
4772bb099e | |||
2be5179020 | |||
8cb49713b4 | |||
bd666dc0e9 | |||
57251d58cc | |||
ebcb4d861a | |||
15a7a839f9 | |||
76a307d31e | |||
37aee7c13b | |||
50a502bb81 | |||
8a4839354e | |||
4da7371246 | |||
e162a75e53 | |||
e60df6ad92 | |||
4c2b3a9d2c | |||
75023a1dd3 | |||
79370a6dfb | |||
4566798afc | |||
3fd1c4bc5d | |||
2d6f48d5ab | |||
d1c7594344 | |||
ac327f51e9 | |||
4e18b11263 | |||
81e3df2b36 | |||
ac05307515 | |||
552a1e6785 | |||
134b8b51aa | |||
efecfd17b9 | |||
799158841e | |||
582ebfd054 | |||
42e4db1539 |
@ -1,199 +0,0 @@
|
|||||||
#ifndef BOOST_ITERATOR_CONCEPTS_HPP
|
|
||||||
#define BOOST_ITERATOR_CONCEPTS_HPP
|
|
||||||
|
|
||||||
#include <boost/concept_check.hpp>
|
|
||||||
#include <boost/iterator_traits.hpp>
|
|
||||||
#include <boost/type_traits/conversion_traits.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
namespace boost_concepts {
|
|
||||||
// Used a different namespace here (instead of "boost") so that the
|
|
||||||
// concept descriptions do not take for granted the names in
|
|
||||||
// namespace boost.
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// Iterator Access Concepts
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class ReadableIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::value_type value_type;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::reference reference;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::return_category
|
|
||||||
return_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
|
||||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
|
||||||
boost::readable_iterator_tag*>::value));
|
|
||||||
|
|
||||||
reference r = *i; // or perhaps read(x)
|
|
||||||
value_type v(r);
|
|
||||||
boost::ignore_unused_variable_warning(v);
|
|
||||||
}
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator, typename ValueType>
|
|
||||||
class WritableIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::return_category
|
|
||||||
return_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
|
||||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
|
||||||
boost::writable_iterator_tag*>::value));
|
|
||||||
|
|
||||||
*i = v; // an alternative could be something like write(x, v)
|
|
||||||
}
|
|
||||||
ValueType v;
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class ConstantLvalueIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::value_type value_type;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::reference reference;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::return_category
|
|
||||||
return_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
|
||||||
boost::constant_lvalue_iterator_tag*>::value));
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<reference,
|
|
||||||
const value_type&>::value));
|
|
||||||
|
|
||||||
reference v = *i;
|
|
||||||
boost::ignore_unused_variable_warning(v);
|
|
||||||
}
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class MutableLvalueIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::value_type value_type;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::reference reference;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::return_category
|
|
||||||
return_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< ReadableIteratorConcept<Iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
WritableIteratorConcept<Iterator, value_type> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<return_category*,
|
|
||||||
boost::mutable_lvalue_iterator_tag*>::value));
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<reference, value_type&>::value));
|
|
||||||
|
|
||||||
reference v = *i;
|
|
||||||
boost::ignore_unused_variable_warning(v);
|
|
||||||
}
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// Iterator Traversal Concepts
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class SinglePassIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::traversal_category
|
|
||||||
traversal_category;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::difference_type
|
|
||||||
difference_type;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< boost::SGIAssignableConcept<Iterator> >();
|
|
||||||
boost::function_requires< boost::EqualityComparableConcept<Iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost::DefaultConstructibleConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
|
||||||
boost::single_pass_iterator_tag*>::value));
|
|
||||||
|
|
||||||
// difference_type must be a signed integral type
|
|
||||||
|
|
||||||
++i;
|
|
||||||
(void)i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class ForwardIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::traversal_category
|
|
||||||
traversal_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< SinglePassIteratorConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
|
||||||
boost::forward_iterator_tag*>::value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class BidirectionalIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::traversal_category
|
|
||||||
traversal_category;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< ForwardIteratorConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
|
||||||
boost::bidirectional_iterator_tag*>::value));
|
|
||||||
|
|
||||||
--i;
|
|
||||||
(void)i--;
|
|
||||||
}
|
|
||||||
Iterator i;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class RandomAccessIteratorConcept {
|
|
||||||
public:
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::traversal_category
|
|
||||||
traversal_category;
|
|
||||||
typedef typename boost::iterator_traits<Iterator>::difference_type
|
|
||||||
difference_type;
|
|
||||||
|
|
||||||
void constraints() {
|
|
||||||
boost::function_requires< BidirectionalIteratorConcept<Iterator> >();
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_convertible<traversal_category*,
|
|
||||||
boost::random_access_iterator_tag*>::value));
|
|
||||||
|
|
||||||
i += n;
|
|
||||||
i = i + n;
|
|
||||||
i = n + i;
|
|
||||||
i -= n;
|
|
||||||
i = i - n;
|
|
||||||
n = i - j;
|
|
||||||
}
|
|
||||||
difference_type n;
|
|
||||||
Iterator i, j;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost_concepts
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_CONCEPTS_HPP
|
|
@ -1,137 +0,0 @@
|
|||||||
#ifndef BOOST_ITERATOR_TRAITS_HPP
|
|
||||||
#define BOOST_ITERATOR_TRAITS_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/type_traits/conversion_traits.hpp>
|
|
||||||
#include <boost/type_traits/cv_traits.hpp>
|
|
||||||
#include <boost/pending/ct_if.hpp>
|
|
||||||
#include <boost/detail/iterator.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Traversal Categories
|
|
||||||
struct single_pass_iterator_tag { };
|
|
||||||
struct forward_iterator_tag : public single_pass_iterator_tag { };
|
|
||||||
struct bidirectional_iterator_tag : public forward_iterator_tag { };
|
|
||||||
struct random_access_iterator_tag : public bidirectional_iterator_tag { };
|
|
||||||
|
|
||||||
// Return Type Categories
|
|
||||||
struct readable_iterator_tag { };
|
|
||||||
struct writable_iterator_tag { };
|
|
||||||
struct mutable_lvalue_iterator_tag : virtual public writable_iterator_tag,
|
|
||||||
virtual public readable_iterator_tag { };
|
|
||||||
struct constant_lvalue_iterator_tag : public readable_iterator_tag { };
|
|
||||||
|
|
||||||
struct error_iterator_tag { };
|
|
||||||
|
|
||||||
// Inherit from iterator_base if your iterator defines its own
|
|
||||||
// return_category and traversal_category. Otherwise, the "old style"
|
|
||||||
// iterator category will be mapped to the return_category and
|
|
||||||
// traversal_category.
|
|
||||||
struct new_iterator_base { };
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
struct iter_traits_from_nested_types {
|
|
||||||
template <typename Iterator> struct bind {
|
|
||||||
typedef typename Iterator::value_type value_type;
|
|
||||||
typedef typename Iterator::reference reference;
|
|
||||||
typedef typename Iterator::pointer pointer;
|
|
||||||
typedef typename Iterator::difference_type difference_type;
|
|
||||||
typedef typename Iterator::return_category return_category;
|
|
||||||
typedef typename Iterator::traversal_category traversal_category;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
struct choose_lvalue_return {
|
|
||||||
typedef typename ct_if<is_const<ValueType>::value,
|
|
||||||
boost::constant_lvalue_iterator_tag,
|
|
||||||
boost::mutable_lvalue_iterator_tag>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Category, typename ValueType>
|
|
||||||
struct iter_category_to_return {
|
|
||||||
typedef typename ct_if<
|
|
||||||
is_convertible<Category*, std::forward_iterator_tag*>::value,
|
|
||||||
typename choose_lvalue_return<ValueType>::type,
|
|
||||||
typename ct_if<
|
|
||||||
is_convertible<Category*, std::input_iterator_tag*>::value,
|
|
||||||
boost::readable_iterator_tag,
|
|
||||||
typename ct_if<
|
|
||||||
is_convertible<Category*, std::output_iterator_tag*>::value,
|
|
||||||
boost::writable_iterator_tag,
|
|
||||||
boost::error_iterator_tag
|
|
||||||
>::type
|
|
||||||
>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Category>
|
|
||||||
struct iter_category_to_traversal {
|
|
||||||
typedef typename ct_if<
|
|
||||||
is_convertible<Category*, std::random_access_iterator_tag*>::value,
|
|
||||||
boost::random_access_iterator_tag,
|
|
||||||
typename ct_if<
|
|
||||||
is_convertible<Category*, std::bidirectional_iterator_tag*>::value,
|
|
||||||
boost::bidirectional_iterator_tag,
|
|
||||||
typename ct_if<
|
|
||||||
is_convertible<Category*, std::forward_iterator_tag*>::value,
|
|
||||||
boost::forward_iterator_tag,
|
|
||||||
boost::single_pass_iterator_tag>::type
|
|
||||||
>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct iter_traits_from_old_traits {
|
|
||||||
template <typename Iterator> class bind {
|
|
||||||
typedef boost::detail::iterator_traits<Iterator> OldTraits;
|
|
||||||
typedef typename OldTraits::iterator_category Cat;
|
|
||||||
public:
|
|
||||||
typedef typename OldTraits::value_type value_type;
|
|
||||||
typedef typename OldTraits::reference reference;
|
|
||||||
typedef typename OldTraits::pointer pointer;
|
|
||||||
typedef typename OldTraits::difference_type difference_type;
|
|
||||||
typedef iter_category_to_return<Cat,value_type>::type return_category;
|
|
||||||
typedef iter_category_to_traversal<Cat>::type traversal_category;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class choose_iter_traits {
|
|
||||||
typedef typename ct_if<is_convertible<Iterator*,
|
|
||||||
new_iterator_base*>::value,
|
|
||||||
iter_traits_from_nested_types,
|
|
||||||
iter_traits_from_old_traits>::type Choice;
|
|
||||||
public:
|
|
||||||
typedef typename Choice:: template bind<Iterator> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
class iterator_traits
|
|
||||||
: public detail::choose_iter_traits<Iterator>::type { };
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct iterator_traits<T*>
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef T* pointer;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef typename ct_if<is_const<T>::value,
|
|
||||||
boost::constant_lvalue_iterator_tag,
|
|
||||||
boost::mutable_lvalue_iterator_tag>::type
|
|
||||||
return_category;
|
|
||||||
typedef boost::random_access_iterator_tag traversal_category;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_TRAITS_HPP
|
|
@ -1,76 +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_iterator_tag traversal_category;
|
|
||||||
typedef boost::mutable_lvalue_iterator_tag return_category;
|
|
||||||
|
|
||||||
int& operator*() const { return *m_x; }
|
|
||||||
new_iterator& operator++() { return *this; }
|
|
||||||
new_iterator operator++(int) { return *this; }
|
|
||||||
new_iterator& operator--() { return *this; }
|
|
||||||
new_iterator operator--(int) { return *this; }
|
|
||||||
new_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
|
||||||
new_iterator operator+(std::ptrdiff_t) { return *this; }
|
|
||||||
new_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
|
||||||
std::ptrdiff_t operator-(const new_iterator&) const { return 0; }
|
|
||||||
new_iterator operator-(std::ptrdiff_t) const { return *this; }
|
|
||||||
bool operator==(const new_iterator&) const { return false; }
|
|
||||||
bool operator!=(const new_iterator&) const { return false; }
|
|
||||||
bool operator<(const new_iterator&) const { return false; }
|
|
||||||
int* m_x;
|
|
||||||
};
|
|
||||||
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
|
|
||||||
|
|
||||||
struct old_iterator
|
|
||||||
: public boost::iterator<std::random_access_iterator_tag, int>
|
|
||||||
{
|
|
||||||
int& operator*() const { return *m_x; }
|
|
||||||
old_iterator& operator++() { return *this; }
|
|
||||||
old_iterator operator++(int) { return *this; }
|
|
||||||
old_iterator& operator--() { return *this; }
|
|
||||||
old_iterator operator--(int) { return *this; }
|
|
||||||
old_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
|
||||||
old_iterator operator+(std::ptrdiff_t) { return *this; }
|
|
||||||
old_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
|
||||||
old_iterator operator-(std::ptrdiff_t) const { return *this; }
|
|
||||||
std::ptrdiff_t operator-(const old_iterator&) const { return 0; }
|
|
||||||
bool operator==(const old_iterator&) const { return false; }
|
|
||||||
bool operator!=(const old_iterator&) const { return false; }
|
|
||||||
bool operator<(const old_iterator&) const { return false; }
|
|
||||||
int* m_x;
|
|
||||||
};
|
|
||||||
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
|
||||||
|
|
||||||
struct bar { };
|
|
||||||
void foo(bar) { }
|
|
||||||
|
|
||||||
int
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::MutableLvalueIteratorConcept<int*> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::RandomAccessIteratorConcept<int*> >();
|
|
||||||
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::ConstantLvalueIteratorConcept<const int*> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::RandomAccessIteratorConcept<const int*> >();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::MutableLvalueIteratorConcept<new_iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::RandomAccessIteratorConcept<new_iterator> >();
|
|
||||||
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::MutableLvalueIteratorConcept<old_iterator> >();
|
|
||||||
boost::function_requires<
|
|
||||||
boost_concepts::RandomAccessIteratorConcept<old_iterator> >();
|
|
||||||
return 0;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB |
@ -1,606 +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 concepts (the iterator requirements defined
|
|
||||||
in the C++ Standard) have a flaw. They glom together two separate
|
|
||||||
issues into a single set of concepts. The two issues are iterator
|
|
||||||
traversal and dereference return type semantics. These two issues are
|
|
||||||
inherently orthogonal and therefore ought to be represented by two
|
|
||||||
separate sets of concepts. The concepts described here do just
|
|
||||||
that.</p>
|
|
||||||
|
|
||||||
One set of concepts handles the return type semantics:
|
|
||||||
<ul>
|
|
||||||
<li><a href="#concept:ReadableIterator">Readable Iterator</a></li>
|
|
||||||
<li><a href="#concept:WritableIterator">Writable Iterator</a></li>
|
|
||||||
<li><a href="#concept:MutableLvalueIterator">Mutable Lvalue Iterator</a></li>
|
|
||||||
<li><a href="#concept:ConstantLvalueIterator">Constant Lvalue Iterator</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
The other set of concepts handles iterator traversal:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="#concept:SinglePassIterator">Single-Pass Iterator</a></li>
|
|
||||||
<li><a href="#concept:ForwardIterator">Forward Iterator</a></li>
|
|
||||||
<li><a href="#concept:BidirectionalIterator">Bidirectional Iterator</a></li>
|
|
||||||
<li><a href="#concept:RandomAccessIterator">Random Access Iterator</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p></p>
|
|
||||||
<DIV ALIGN="CENTER"><A NAME="fig:graph-concepts"></A></A>
|
|
||||||
<TABLE>
|
|
||||||
<CAPTION ALIGN="TOP"><STRONG>Figure 1:</STRONG>
|
|
||||||
The iterator concepts and refinement relationships.
|
|
||||||
</CAPTION>
|
|
||||||
<TR><TD><IMG SRC="./iterator_concepts.gif" width="541" height="214"></TD></TR>
|
|
||||||
</TABLE>
|
|
||||||
</DIV>
|
|
||||||
<p></p>
|
|
||||||
|
|
||||||
<h2>Relationship with the standard iterator concepts</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
std::Input Iterator refines boost::Single-Pass Iterator and
|
|
||||||
boost::ReadableIterator.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
std::Output Iterator refines boost::Single-Pass Iterator and
|
|
||||||
boost::Writable Iterator.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
std::Forward Iterator refines boost::Forward Iterator and
|
|
||||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
std::Bidirectional Iterator refines boost::Bidirectional Iterator and
|
|
||||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
std::Random Access Iterator refines boost::Random Access Iterator and
|
|
||||||
boost::Constant Lvalue Iterator or boost::Mutable Lvalue Iterator.
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Notation</h3>
|
|
||||||
<Table>
|
|
||||||
<TR>
|
|
||||||
<TD><tt>X</tt></TD>
|
|
||||||
<TD>The iterator type.</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD><tt>T</tt></TD>
|
|
||||||
<TD>The value type of <tt>X</tt>.</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD><tt>x</tt>, <tt>y</tt></TD>
|
|
||||||
<TD>An object of type <tt>X</tt>.</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD><tt>t</tt></TD>
|
|
||||||
<TD>An object of type <tt>T</tt>.</TD>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:ReadableIterator"></A>
|
|
||||||
Readable Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
A Readable Iterator is an iterator that dereferences to produce an
|
|
||||||
rvalue that is convertible to the <tt>value_type</tt> of the
|
|
||||||
iterator. For example, derefencing may return a temporary object and
|
|
||||||
therefore it would be a mistake to bind the result to a reference.
|
|
||||||
Also, an attempt to assign a value to the result will most likely
|
|
||||||
cause an error.
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
template <class Readable Iterator>
|
|
||||||
void foo(Readable Iterator x)
|
|
||||||
{
|
|
||||||
typedef std::iterator_traits<Readable Iterator>::value_type T;
|
|
||||||
T t = *x; // Read a value. This is OK.
|
|
||||||
T& s = *x; // Bind to a reference. This is a bad idea.
|
|
||||||
*x = t; // Try to assign. This is a really bad idea.
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Associated Types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Value type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::value_type</tt></TD>
|
|
||||||
<TD>
|
|
||||||
The type of the value obtained by dereferencing a LvalueIterator
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Return Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::return_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::readable_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>,
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/EqualityComparable.html">Equality Comparable</A>,
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">Default Constructible</A>
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Dereference</TD>
|
|
||||||
<TD><tt>*x</tt></TD>
|
|
||||||
<TD> </TD>
|
|
||||||
<TD>Convertible to <tt>T</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>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:WritableIterator"></A>
|
|
||||||
Writable Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
A Writable Iterator is an iterator that can be used to store a value
|
|
||||||
using the dereference-assignment expression.
|
|
||||||
|
|
||||||
<h3>Definitions</h3>
|
|
||||||
|
|
||||||
If <tt>x</tt> is an Writable Iterator of type <tt>X</tt>, then the
|
|
||||||
expression <tt>*x = a;</tt> stores the value <tt>a</tt> into
|
|
||||||
<tt>x</tt>. Note that <tt>operator=</tt>, like other C++ functions,
|
|
||||||
may be overloaded; it may, in fact, even be a template function. In
|
|
||||||
general, then, <tt>a</tt> may be any of several different types. A
|
|
||||||
type <tt>A</tt> belongs to the <i>set of value types</i> of <tt>X</tt>
|
|
||||||
if, for an object <tt>a</tt> of type <tt>A</tt>, <tt>*x = a;</tt> is
|
|
||||||
well-defined and does not require performing any non-trivial
|
|
||||||
conversions on <tt>a</tt>.
|
|
||||||
|
|
||||||
<h3>Associated Types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Return Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::return_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::writable_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>,
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/EqualityComparable.html">Equality Comparable</A>,
|
|
||||||
<A href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">Default Constructible</A>
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TH>Name</TH><TH>Expression</TH><TH>Return type</TH>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Dereference assignment</TD>
|
|
||||||
<TD><tt>*x = a</tt></TD>
|
|
||||||
<TD>unspecified</TD>
|
|
||||||
</TR>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:ConstantLvalueIterator"></A>
|
|
||||||
Constant Lvalue Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
A Constant Lvalue Iterator is an iterator that dereferences to produce a
|
|
||||||
const reference to the pointed-to object, i.e., the associated
|
|
||||||
<tt>reference</tt> type is <tt>const T&</tt>. Changing the value
|
|
||||||
of or destroying an iterator that models Constant Lvalue Iterator does
|
|
||||||
not invalidate pointers and references previously obtained from that
|
|
||||||
iterator.
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<a href="#concept:Readable Iterator">Readable Iterator</a>
|
|
||||||
|
|
||||||
<h3>Associated Types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Value type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::value_type</tt></TD>
|
|
||||||
<TD>
|
|
||||||
The type of the value obtained by dereferencing a Constant Lvalue Iterator.
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Reference type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::reference</tt></TD>
|
|
||||||
<TD>
|
|
||||||
The return type of <tt>operator*()</tt>, which must be
|
|
||||||
<tt>const T&</tt>.
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>POinter type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><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><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::return_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::constant_lvalue_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Dereference</TD>
|
|
||||||
<TD><tt>*x</tt></TD>
|
|
||||||
<TD> </TD>
|
|
||||||
<TD><tt>const T&</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>
|
|
||||||
|
|
||||||
|
|
||||||
<H2><A NAME="concept:MutableLvalueIterator"></A>
|
|
||||||
Mutable Lvalue Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
A Mutable Lvalue Iterator is an iterator that dereferences to produce a
|
|
||||||
reference to the pointed-to object. The associated <tt>reference</tt>
|
|
||||||
type is <tt>T&</tt>. Changing the value of or destroying an
|
|
||||||
iterator that models Mutable Lvalue Iterator does not invalidate
|
|
||||||
pointers and references previously obtained from that iterator.
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<a href="#concept:Readable Iterator">Readable Iterator</a> and
|
|
||||||
<a href="#concept:WritableIterator">Writable Iterator</a>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Associated Types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Value type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::value_type</tt></TD>
|
|
||||||
<TD>
|
|
||||||
The type of the value obtained by dereferencing a Mutable Lvalue Iterator.
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Reference type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::reference</tt></TD>
|
|
||||||
<TD>
|
|
||||||
The return type of <tt>operator*()</tt>, which is
|
|
||||||
<tt>T&</tt>.
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Pointer type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><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><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::return_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::mutable_lvalue_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH><TH>Return type</TH></TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Dereference</TD>
|
|
||||||
<TD><tt>*x</tt></TD>
|
|
||||||
<TD> </TD>
|
|
||||||
<TD> <tt>T&</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>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:SinglePassIterator"></A>
|
|
||||||
Single-Pass Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
A Single-Pass Iterator is an iterator that can be incremented to
|
|
||||||
traverse through a sequence of objects, but the sequence can only be
|
|
||||||
traversed a single time.
|
|
||||||
|
|
||||||
<h3>Associated types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TD>Difference type</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::difference_type</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A signed integral type used to represent the distance from one
|
|
||||||
iterator to another, or the number of elements in a range.
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD>Traversal Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::traversal_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::single_pass_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
|
||||||
<TH>Return type</TH>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Preincrement</TD>
|
|
||||||
<TD><tt>++i</tt></TD><TD> </TD><TD><tt>X&</tt></TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>Postincrement</TD>
|
|
||||||
<TD><tt>(void)i++</tt></TD><TD> </TD><TD> </TD>
|
|
||||||
</TR>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:ForwardIterator"></A>
|
|
||||||
Forward Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
The Forward Iterator is an iterator that can be incremented. Also, it
|
|
||||||
is permissible to make multiple passes through the sequence.
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<a href="#concept:SinglePassIterator">Single-Pass Iterator</a>
|
|
||||||
|
|
||||||
<h3>Associated types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TD>Traversal Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::traversal_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::forward_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:BidirectionalIterator"></A>
|
|
||||||
Bidirectional Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
An iterator that can be incremented and decremented.
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<a href="#concept:ForwardIterator">Forward Iterator</a>
|
|
||||||
|
|
||||||
<h3>Associated types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TD>Traversal Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::traversal_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::bidirectional_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
|
||||||
<TH>Return type</TH>
|
|
||||||
</TR>
|
|
||||||
<TR><TD>Predecrement</TD>
|
|
||||||
<TD><tt>--i</tt></TD><TD> </TD><TD><tt>X&</tt></TD>
|
|
||||||
</TR>
|
|
||||||
<TR><TD>Postdecrement</TD>
|
|
||||||
<TD><tt>i--</tt></TD><TD> </TD><TD><tt>X</tt></TD>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<H2><A NAME="concept:RandomAccessIterator"></A>
|
|
||||||
Random Access Iterator
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
An iterator that provides constant-time methods for moving forward and
|
|
||||||
backward in arbitrary-sized steps
|
|
||||||
|
|
||||||
<h3>Refinement of</h3>
|
|
||||||
|
|
||||||
<a href="#concept:BidirectionalIterator">Bidirectional Iterator</a>
|
|
||||||
|
|
||||||
<h3>Associated types</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TD>Traversal Category</TD>
|
|
||||||
<TD><tt><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::traversal_category</tt></TD>
|
|
||||||
<TD>
|
|
||||||
A type convertible to <tt>boost::random_access_iterator_tag</tt>
|
|
||||||
</TD>
|
|
||||||
</tr>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<h3>Valid expressions</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR><TH>Name</TH><TH>Expression</TH><TH>Type requirements</TH>
|
|
||||||
<TH>Return type</TH>
|
|
||||||
</TR>
|
|
||||||
<TR><TD>Iterator addition</TD>
|
|
||||||
<TD><tt>i += n</tt></TD><TD> </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><a href="./iterator_traits.htm">boost::iterator_traits</a><X>::difference_type</tt></TD>
|
|
||||||
</TR>
|
|
||||||
<TR><TD>Element operator</TD>
|
|
||||||
<TD><tt>i[n]</tt></TD>
|
|
||||||
<TD><tt>X</tt> must be a model of
|
|
||||||
<a href="#concept:Readable Iterator">Readable Iterator</a>. </TD>
|
|
||||||
<TD>The same return type as <tt>*i</tt>.</TD>
|
|
||||||
</TR>
|
|
||||||
<TR><TD>Element assignment</TD>
|
|
||||||
<TD><tt>i[n] = t</tt></TD>
|
|
||||||
<TD><tt>X</tt> must be a model of
|
|
||||||
<a href="#concept:WritableIterator">Writable Iterator</a>.</TD>
|
|
||||||
<TD>unspecified</TD>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<HR>
|
|
||||||
<TABLE>
|
|
||||||
<TR valign=top>
|
|
||||||
<TD nowrap>Copyright © 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>
|
|
@ -1,137 +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.
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Boost Iterator Traits</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
|
||||||
ALINK="#ff0000">
|
|
||||||
<IMG SRC="../../../../c++boost.gif"
|
|
||||||
ALT="C++ Boost" width="277" height="86">
|
|
||||||
<BR Clear>
|
|
||||||
|
|
||||||
<h1>Boost Iterator Traits</h1>
|
|
||||||
Header <tt><a href="../../boost/iterator_traits.hpp">boost/iterator_traits.hpp</a></tt>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <tt>boost::iterator_traits</tt> class provides access to the
|
|
||||||
associated types of iterators that model the Boost <a
|
|
||||||
href="./iterator_concepts.htm">Iterator Concepts</a>, which are a
|
|
||||||
replacement for the iterator requirements in the C++ standard.
|
|
||||||
The main difference between <tt>std::iterator_traits</tt> and
|
|
||||||
<tt>boost::iterator_traits</tt> is that the <tt>iterator_category</tt>
|
|
||||||
type has been removed, and replaced with two new types:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><tt>traversal_category</tt>: Can the iterator go forward, backward, etc.?
|
|
||||||
<li><tt>return_category</tt>: Is the iterator read or write only?
|
|
||||||
Is the dereferenced type an lvalue?
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
An important feature of the <tt>boost::iterator_traits</tt> is that it
|
|
||||||
is <b>backwards compatible</b>, i.e., it will automatically work for
|
|
||||||
iterators for which there are valid definitions of
|
|
||||||
<tt>std::iterator_traits</tt>. The old <tt>iterator_category</tt> is
|
|
||||||
mapped to the appropriate traversal and return categories.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
When creating a new iterator type that is meant to work with
|
|
||||||
<tt>boost::iterator_traits</tt>, you can either create a
|
|
||||||
specialization of <tt>boost::iterator_traits</tt> for your iterator
|
|
||||||
type, or you can provide all the necessary associated types as nested
|
|
||||||
typedefs. In this case, your iterator class will need to inherit from
|
|
||||||
<tt>new_iterator_base</tt> to let <tt>boost::iterator_traits</tt> know
|
|
||||||
that it will be able to find typedefs for <tt>traversal_category</tt>
|
|
||||||
and <tt>return_category</tt> in you iterator class.
|
|
||||||
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
<i>// Inherit from iterator_base if your iterator defines its own
|
|
||||||
// return_category and traversal_category. Otherwise, the "old style"
|
|
||||||
// iterator category will be mapped to the return_category and
|
|
||||||
// traversal_category.</i>
|
|
||||||
struct new_iterator_base { };
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
struct iterator_traits
|
|
||||||
{
|
|
||||||
if (Iterator inherits from new_iterator_base) {
|
|
||||||
typedef typename Iterator::value_type value_type;
|
|
||||||
typedef typename Iterator::reference reference;
|
|
||||||
typedef typename Iterator::pointer pointer;
|
|
||||||
typedef typename Iterator::difference_type difference_type;
|
|
||||||
typedef typename Iterator::return_category return_category;
|
|
||||||
typedef typename Iterator::traversal_category traversal_category;
|
|
||||||
} else {
|
|
||||||
typedef std::iterator_traits<Iterator> OldTraits;
|
|
||||||
typedef typename OldTraits::value_type value_type;
|
|
||||||
typedef typename OldTraits::reference reference;
|
|
||||||
typedef typename OldTraits::pointer pointer;
|
|
||||||
typedef typename OldTraits::difference_type difference_type;
|
|
||||||
|
|
||||||
typedef typename OldTraits::iterator_category Cat;
|
|
||||||
|
|
||||||
<i>// Determine the traversal_category based on the old iterator_category</i>
|
|
||||||
if (Cat inherits from std::random_access_iterator_tag)
|
|
||||||
typedef boost::random_access_iterator_tag traversal_category;
|
|
||||||
else if (Cat inherits from std::bidirectional_iterator_tag)
|
|
||||||
typedef boost::bidirectional_iterator_tag traversal_category;
|
|
||||||
else if (Cat inherits from std::forward_iterator_tag)
|
|
||||||
typedef boost::forward_iterator_tag traversal_category;
|
|
||||||
else
|
|
||||||
typedef boost::single_pass_iterator_tag traversal_category;
|
|
||||||
|
|
||||||
<i>// Determine the return_category based on the old iterator_category and value_type</i>
|
|
||||||
if (Cat inherits from std::forward_iterator_tag)
|
|
||||||
if (is-const(T))
|
|
||||||
typedef boost::constant_lvalue_iterator_tag return_category;
|
|
||||||
else
|
|
||||||
typedef boost::mutable_lvalue_iterator_tag return_category;
|
|
||||||
else if (Cat inherits from std::input_iterator_tag)
|
|
||||||
typedef boost::readable_iterator_tag return_category;
|
|
||||||
else if (Cat inherits from std::output_iterator_tag)
|
|
||||||
typedef boost::writable_iterator_tag return_category;
|
|
||||||
else
|
|
||||||
typedef boost::error_iterator_tag return_category;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct iterator_traits<T*>
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef T* pointer;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
if (is-const(T))
|
|
||||||
typedef boost::constant_lvalue_iterator_tag return_category;
|
|
||||||
else
|
|
||||||
typedef boost::mutable_lvalue_iterator_tag return_category;
|
|
||||||
typedef boost::random_access_iterator_tag traversal_category;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<address><a href="mailto:jsiek@lsc.nd.edu">jeremy siek</a></address>
|
|
||||||
<!-- Created: Sun Mar 18 14:06:57 EST 2001 -->
|
|
||||||
<!-- hhmts start -->
|
|
||||||
Last modified: Mon Mar 19 12:59:30 EST 2001
|
|
||||||
<!-- hhmts end -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -56,9 +56,7 @@
|
|||||||
# include <boost/type_traits.hpp>
|
# include <boost/type_traits.hpp>
|
||||||
# include <boost/detail/numeric_traits.hpp>
|
# include <boost/detail/numeric_traits.hpp>
|
||||||
# include <boost/static_assert.hpp>
|
# include <boost/static_assert.hpp>
|
||||||
# ifndef BOOST_NO_LIMITS
|
# include <boost/limits.hpp>
|
||||||
# include <limits>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@ -135,7 +133,15 @@ namespace detail {
|
|||||||
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||||
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||||
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
# if defined(BOOST_HAS_LONG_LONG)
|
||||||
|
BOOST_STATIC_CONSTANT(bool,
|
||||||
|
value = (
|
||||||
|
std::numeric_limits<T>::is_specialized
|
||||||
|
| boost::is_same<T,long long>::value
|
||||||
|
| boost::is_same<T,unsigned long long>::value));
|
||||||
|
# else
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||||
|
# endif
|
||||||
# else
|
# else
|
||||||
# if !defined(__BORLANDC__)
|
# if !defined(__BORLANDC__)
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
BOOST_STATIC_CONSTANT(bool, value = (
|
||||||
@ -173,14 +179,17 @@ struct counting_iterator_traits {
|
|||||||
template <class Incrementable>
|
template <class Incrementable>
|
||||||
struct counting_iterator_policies : public default_iterator_policies
|
struct counting_iterator_policies : public default_iterator_policies
|
||||||
{
|
{
|
||||||
const Incrementable& dereference(type<const Incrementable&>, const Incrementable& i) const
|
template <class IteratorAdaptor>
|
||||||
{ return i; }
|
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& i) const
|
||||||
|
{ return i.base(); }
|
||||||
template <class Difference, class Iterator1, class Iterator2>
|
|
||||||
Difference distance(type<Difference>, const Iterator1& x,
|
template <class Iterator1, class Iterator2>
|
||||||
const Iterator2& y) const
|
typename Iterator1::difference_type distance(
|
||||||
|
const Iterator1& x, const Iterator2& y) const
|
||||||
{
|
{
|
||||||
return boost::detail::any_distance<Difference>(x, y);//,(Difference*)());
|
typedef typename Iterator1::difference_type difference_type;
|
||||||
|
return boost::detail::any_distance<difference_type>(
|
||||||
|
x.base(), y.base());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -188,15 +197,20 @@ struct counting_iterator_policies : public default_iterator_policies
|
|||||||
template <class Incrementable>
|
template <class Incrementable>
|
||||||
struct counting_iterator_generator
|
struct counting_iterator_generator
|
||||||
{
|
{
|
||||||
typedef counting_iterator_traits<Incrementable> traits;
|
typedef typename boost::remove_const<
|
||||||
|
Incrementable
|
||||||
|
>::type value_type;
|
||||||
|
|
||||||
typedef iterator_adaptor<Incrementable,
|
typedef counting_iterator_traits<value_type> traits;
|
||||||
counting_iterator_policies<Incrementable>,
|
|
||||||
Incrementable,
|
typedef iterator_adaptor<
|
||||||
const Incrementable&,
|
value_type
|
||||||
const Incrementable*,
|
, counting_iterator_policies<value_type>
|
||||||
typename traits::iterator_category,
|
, value_type
|
||||||
typename traits::difference_type
|
, value_type const&
|
||||||
|
, value_type const*
|
||||||
|
, typename traits::iterator_category
|
||||||
|
, typename traits::difference_type
|
||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,17 +99,17 @@ struct half_open_range
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef iter_t const_iterator;
|
typedef iter_t const_iterator;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::value_type value_type;
|
typedef typename iterator::value_type value_type;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::difference_type difference_type;
|
typedef typename iterator::difference_type difference_type;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::reference reference;
|
typedef typename iterator::reference reference;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::reference const_reference;
|
typedef typename iterator::reference const_reference;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::pointer pointer;
|
typedef typename iterator::pointer pointer;
|
||||||
typedef typename counting_iterator_traits<Incrementable>::pointer const_pointer;
|
typedef typename iterator::pointer const_pointer;
|
||||||
|
|
||||||
// It would be nice to select an unsigned type, but this is appropriate
|
// 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
|
// since the library makes an attempt to select a difference_type which can
|
||||||
// hold the difference between any two iterators.
|
// hold the difference between any two iterators.
|
||||||
typedef typename counting_iterator_traits<Incrementable>::difference_type size_type;
|
typedef typename iterator::difference_type size_type;
|
||||||
|
|
||||||
half_open_range(Incrementable start, Incrementable finish)
|
half_open_range(Incrementable start, Incrementable finish)
|
||||||
: m_start(start),
|
: m_start(start),
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
# ifdef BOOST_NO_STD_ITERATOR
|
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
template <class Category, class T,
|
template <class Category, class T,
|
||||||
class Distance = std::ptrdiff_t,
|
class Distance = std::ptrdiff_t,
|
||||||
class Pointer = T*, class Reference = T&>
|
class Pointer = T*, class Reference = T&>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,10 @@
|
|||||||
// test suite for STL concepts such as iterators and containers.
|
// test suite for STL concepts such as iterators and containers.
|
||||||
//
|
//
|
||||||
// Revision History:
|
// 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
|
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||||
// --i is no longer a precondition.
|
// --i is no longer a precondition.
|
||||||
// (Jeremy Siek)
|
// (Jeremy Siek)
|
||||||
@ -74,22 +78,40 @@ void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
|||||||
template <class Iterator, class T>
|
template <class Iterator, class T>
|
||||||
void input_iterator_test(Iterator i, T v1, T v2)
|
void input_iterator_test(Iterator i, T v1, T v2)
|
||||||
{
|
{
|
||||||
Iterator i1 = i, i2 = i;
|
Iterator i1(i);
|
||||||
|
|
||||||
assert(i == i1++);
|
|
||||||
assert(i != ++i2);
|
|
||||||
|
|
||||||
trivial_iterator_test(i, i1, v1);
|
|
||||||
trivial_iterator_test(i, i2, v1);
|
|
||||||
|
|
||||||
++i;
|
|
||||||
assert(i == i1);
|
assert(i == i1);
|
||||||
assert(i == i2);
|
assert(!(i != i1));
|
||||||
++i1;
|
|
||||||
++i2;
|
|
||||||
|
|
||||||
trivial_iterator_test(i, i1, v2);
|
// I can see no generic way to create an input iterator
|
||||||
trivial_iterator_test(i, i2, v2);
|
// 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?
|
// how to test output iterator?
|
||||||
@ -124,6 +146,23 @@ void forward_iterator_test(Iterator i, T v1, T v2)
|
|||||||
{
|
{
|
||||||
input_iterator_test(i, v1, v2);
|
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
|
// borland doesn't allow non-type template parameters
|
||||||
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
|
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
|
||||||
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
|
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
|
||||||
|
72
include/boost/permutation_iterator.hpp
Normal file
72
include/boost/permutation_iterator.hpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// (C) Copyright Toon Knapen 2001. Permission to copy, use,
|
||||||
|
// modify, sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef boost_permutation_iterator_hpp
|
||||||
|
#define boost_permutation_iterator_hpp
|
||||||
|
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template < typename IndexIterator >
|
||||||
|
struct permutation_iterator_policies : public default_iterator_policies
|
||||||
|
{
|
||||||
|
permutation_iterator_policies() {}
|
||||||
|
|
||||||
|
permutation_iterator_policies(IndexIterator order_it)
|
||||||
|
: order_it_( order_it )
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <class IteratorAdaptor>
|
||||||
|
typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const
|
||||||
|
{ return *(x.base() + *order_it_); }
|
||||||
|
|
||||||
|
template <class IteratorAdaptor>
|
||||||
|
void increment(IteratorAdaptor&)
|
||||||
|
{ ++order_it_; }
|
||||||
|
|
||||||
|
template <class IteratorAdaptor>
|
||||||
|
void decrement(IteratorAdaptor&)
|
||||||
|
{ --order_it_; }
|
||||||
|
|
||||||
|
template <class IteratorAdaptor, class DifferenceType>
|
||||||
|
void advance(IteratorAdaptor& x, DifferenceType n)
|
||||||
|
{ std::advance( order_it_, n ); }
|
||||||
|
|
||||||
|
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||||
|
typename IteratorAdaptor1::difference_type
|
||||||
|
distance(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||||
|
{ return std::distance( x.policies().order_it_, y.policies().order_it_ ); }
|
||||||
|
|
||||||
|
template <class IteratorAdaptor1, class IteratorAdaptor2>
|
||||||
|
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
|
||||||
|
{ return x.policies().order_it_ == y.policies().order_it_; }
|
||||||
|
|
||||||
|
IndexIterator order_it_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename ElementIterator, typename IndexIterator >
|
||||||
|
struct permutation_iterator_generator
|
||||||
|
{
|
||||||
|
typedef boost::iterator_adaptor
|
||||||
|
< ElementIterator,
|
||||||
|
permutation_iterator_policies< IndexIterator >
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < class IndexIterator, class ElementIterator >
|
||||||
|
inline typename permutation_iterator_generator< ElementIterator, IndexIterator >::type
|
||||||
|
make_permutation_iterator(ElementIterator base, IndexIterator order)
|
||||||
|
{
|
||||||
|
typedef typename permutation_iterator_generator< ElementIterator, IndexIterator >::type result_t;
|
||||||
|
return result_t( base, order );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // boost_permutation_iterator_hpp
|
||||||
|
|
Reference in New Issue
Block a user