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