1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
[section:counting Counting Iterator]
A `counting_iterator` adapts an object by adding an `operator*` that
returns the current value of the object. All other iterator operations
are forwarded to the adapted object.
[h2 Example]
This example fills an array with numbers and a second array with
pointers into the first array, using `counting_iterator` for both
tasks. Finally `indirect_iterator` is used to print out the numbers
into the first array via indirection through the second array.
int N = 7;
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
[pre
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
]
The source code for this example can be found [example_link counting_iterator_example.cpp..here].
[h2 Reference]
[h3 Synopsis]
template <
class Incrementable
, class CategoryOrTraversal = use_default
, class Difference = use_default
>
class counting_iterator
{
public:
typedef Incrementable value_type;
typedef const Incrementable& reference;
typedef const Incrementable* pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
counting_iterator();
counting_iterator(counting_iterator const& rhs);
explicit counting_iterator(Incrementable x);
Incrementable const& base() const;
reference operator*() const;
counting_iterator& operator++();
counting_iterator& operator--();
private:
Incrementable m_inc; // exposition
};
If the `Difference` argument is `use_default` then
`difference_type` is an unspecified signed integral
type. Otherwise `difference_type` is `Difference`.
`iterator_category` is determined according to the following
algorithm:
if (CategoryOrTraversal is not use_default)
return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
return |iterator-category|_\ (
random_access_traversal_tag, Incrementable, const Incrementable&)
else
return |iterator-category|_\ (
iterator_traversal<Incrementable>::type,
Incrementable, const Incrementable&)
[blurb *Note:* implementers are encouraged to provide an implementation of
`operator-` and a `difference_type` that avoids overflows in
the cases where `std::numeric_limits<Incrementable>::is_specialized`
is true.]
[h3 Requirements]
The `Incrementable` argument shall be Copy Constructible and Assignable.
If `iterator_category` is convertible to `forward_iterator_tag`
or `forward_traversal_tag`, the following must be well-formed:
Incrementable i, j;
++i; // pre-increment
i == j; // operator equal
If `iterator_category` is convertible to
`bidirectional_iterator_tag` or `bidirectional_traversal_tag`,
the following expression must also be well-formed:
--i
If `iterator_category` is convertible to
`random_access_iterator_tag` or `random_access_traversal_tag`,
the following must must also be valid:
counting_iterator::difference_type n;
i += n;
n = i - j;
i < j;
[h3 Concepts]
Specializations of `counting_iterator` model Readable Lvalue
Iterator. In addition, they model the concepts corresponding to the
iterator tags to which their `iterator_category` is convertible.
Also, if `CategoryOrTraversal` is not `use_default` then
`counting_iterator` models the concept corresponding to the iterator
tag `CategoryOrTraversal`. Otherwise, if
`numeric_limits<Incrementable>::is_specialized`, then
`counting_iterator` models Random Access Traversal Iterator.
Otherwise, `counting_iterator` models the same iterator traversal
concepts modeled by `Incrementable`.
`counting_iterator<X,C1,D1>` is interoperable with
`counting_iterator<Y,C2,D2>` if and only if `X` is
interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the concepts modeled by
`counting_iterator`, `counting_iterator` provides the following
operations.
counting_iterator();
[*Requires: ] `Incrementable` is Default Constructible.[br]
[*Effects: ] Default construct the member `m_inc`.
counting_iterator(counting_iterator const& rhs);
[*Effects: ] Construct member `m_inc` from `rhs.m_inc`.
explicit counting_iterator(Incrementable x);
[*Effects: ] Construct member `m_inc` from `x`.
reference operator*() const;
[*Returns: ] `m_inc`
counting_iterator& operator++();
[*Effects: ] `++m_inc`[br]
[*Returns: ] `*this`
counting_iterator& operator--();
[*Effects: ] `--m_inc`[br]
[*Returns: ] `*this`
Incrementable const& base() const;
[*Returns: ] `m_inc`
[endsect]
|