]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/iterator/doc/quickbook/indirect_iterator.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / iterator / doc / quickbook / indirect_iterator.qbk
CommitLineData
7c673cae
FG
1
2[section:indirect Indirect Iterator]
3
4`indirect_iterator` adapts an iterator by applying an
5*extra* dereference inside of `operator*()`. For example, this
6iterator adaptor makes it possible to view a container of pointers
7(e.g. `list<foo*>`) as if it were a container of the pointed-to type
8(e.g. `list<foo>`). `indirect_iterator` depends on two
9auxiliary traits, `pointee` and `indirect_reference`, to
10provide support for underlying iterators whose `value_type` is
11not an iterator.
12
13[h2 Example]
14
15This example prints an array of characters, using
16`indirect_iterator` to access the array of characters through an
17array of pointers. Next `indirect_iterator` is used with the
18`transform` algorithm to copy the characters (incremented by one) to
19another array. A constant indirect iterator is used for the source and
20a mutable indirect iterator is used for the destination. The last part
21of the example prints the original array of characters, but this time
22using the `make_indirect_iterator` helper function.
23
24
25 char characters[] = "abcdefg";
26 const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
27 char* pointers_to_chars[N]; // at the end.
28 for (int i = 0; i < N; ++i)
29 pointers_to_chars[i] = &characters[i];
30
31 // Example of using indirect_iterator
32
33 boost::indirect_iterator<char**, char>
34 indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
35
36 std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
37 std::cout << std::endl;
38
39
40 // Example of making mutable and constant indirect iterators
41
42 char mutable_characters[N];
43 char* pointers_to_mutable_chars[N];
44 for (int j = 0; j < N; ++j)
45 pointers_to_mutable_chars[j] = &mutable_characters[j];
46
47 boost::indirect_iterator<char* const*> mutable_indirect_first(pointers_to_mutable_chars),
48 mutable_indirect_last(pointers_to_mutable_chars + N);
49 boost::indirect_iterator<char* const*, char const> const_indirect_first(pointers_to_chars),
50 const_indirect_last(pointers_to_chars + N);
51
52 std::transform(const_indirect_first, const_indirect_last,
53 mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
54
55 std::copy(mutable_indirect_first, mutable_indirect_last,
56 std::ostream_iterator<char>(std::cout, ","));
57 std::cout << std::endl;
58
59
60 // Example of using make_indirect_iterator()
61
62 std::copy(boost::make_indirect_iterator(pointers_to_chars),
63 boost::make_indirect_iterator(pointers_to_chars + N),
64 std::ostream_iterator<char>(std::cout, ","));
65 std::cout << std::endl;
66
67
68The output is:
69
70 a,b,c,d,e,f,g,
71 b,c,d,e,f,g,h,
72 a,b,c,d,e,f,g,
73
74
75The source code for this example can be found
76[@../example/indirect_iterator_example.cpp here].
77
78
79[h2 Reference]
80
81[h3 Synopsis]
82
83 template <
84 class Iterator
85 , class Value = use_default
86 , class CategoryOrTraversal = use_default
87 , class Reference = use_default
88 , class Difference = use_default
89 >
90 class indirect_iterator
91 {
92 public:
93 typedef /* see below */ value_type;
94 typedef /* see below */ reference;
95 typedef /* see below */ pointer;
96 typedef /* see below */ difference_type;
97 typedef /* see below */ iterator_category;
98
99 indirect_iterator();
100 indirect_iterator(Iterator x);
101
102 template <
103 class Iterator2, class Value2, class Category2
104 , class Reference2, class Difference2
105 >
106 indirect_iterator(
107 indirect_iterator<
108 Iterator2, Value2, Category2, Reference2, Difference2
109 > const& y
110 , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
111 );
112
113 Iterator const& base() const;
114 reference operator*() const;
115 indirect_iterator& operator++();
116 indirect_iterator& operator--();
117 private:
118 Iterator m_iterator; // exposition
119 };
120
121
122The member types of `indirect_iterator` are defined according to
123the following pseudo-code, where `V` is
124`iterator_traits<Iterator>::value_type`
125
126[pre
127 if (Value is use_default) then
128 typedef remove_const<pointee<V>::type>::type value_type;
129 else
130 typedef remove_const<Value>::type value_type;
131
132 if (Reference is use_default) then
133 if (Value is use_default) then
134 typedef indirect_reference<V>::type reference;
135 else
136 typedef Value& reference;
137 else
138 typedef Reference reference;
139
140 if (Value is use_default) then
141 typedef pointee<V>::type\* pointer;
142 else
143 typedef Value\* pointer;
144
145 if (Difference is use_default)
146 typedef iterator_traits<Iterator>::difference_type difference_type;
147 else
148 typedef Difference difference_type;
149
150 if (CategoryOrTraversal is use_default)
151 typedef *iterator-category* (
152 iterator_traversal<Iterator>::type,`reference`,`value_type`
153 ) iterator_category;
154 else
155 typedef *iterator-category* (
156 CategoryOrTraversal,`reference`,`value_type`
157 ) iterator_category;
158]
159
160
161[h3 Requirements]
162
163The expression `*v`, where `v` is an object of
164`iterator_traits<Iterator>::value_type`, shall be valid
165expression and convertible to `reference`. `Iterator` shall
166model the traversal concept indicated by `iterator_category`.
167`Value`, `Reference`, and `Difference` shall be chosen so
168that `value_type`, `reference`, and `difference_type` meet
169the requirements indicated by `iterator_category`.
170
171[blurb Note: there are further requirements on the
172`iterator_traits<Iterator>::value_type` if the `Value`
173parameter is not `use_default`, as implied by the algorithm for
174deducing the default for the `value_type` member.]
175
176[h3 Concepts]
177
178In addition to the concepts indicated by `iterator_category`
179and by `iterator_traversal<indirect_iterator>::type`, a
180specialization of `indirect_iterator` models the following
181concepts, Where `v` is an object of
182`iterator_traits<Iterator>::value_type`:
183
184Readable Iterator if `reference(*v)` is convertible to
185`value_type`.
186
187Writable Iterator if `reference(*v) = t` is a valid
188expression (where `t` is an object of type
189`indirect_iterator::value_type`)
190
191Lvalue Iterator if `reference` is a reference type.
192
193`indirect_iterator<X,V1,C1,R1,D1>` is interoperable with
194`indirect_iterator<Y,V2,C2,R2,D2>` if and only if `X` is
195interoperable with `Y`.
196
197[h3 Operations]
198
199In addition to the operations required by the concepts described
200above, specializations of `indirect_iterator` provide the
201following operations:
202
203
204 indirect_iterator();
205
206[*Requires: ] `Iterator` must be Default Constructible.[br]
207[*Effects: ] Constructs an instance of `indirect_iterator` with
208 a default-constructed `m_iterator`.
209
210
211 indirect_iterator(Iterator x);
212
213[*Effects: ] Constructs an instance of `indirect_iterator` with
214 `m_iterator` copy constructed from `x`.
215
216
217 template <
218 class Iterator2, class Value2, unsigned Access, class Traversal
219 , class Reference2, class Difference2
220 >
221 indirect_iterator(
222 indirect_iterator<
223 Iterator2, Value2, Access, Traversal, Reference2, Difference2
224 > const& y
225 , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
226 );
227
228[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
229[*Effects: ] Constructs an instance of `indirect_iterator` whose
230 `m_iterator` subobject is constructed from `y.base()`.
231
232
233 Iterator const& base() const;
234
235[*Returns: ] `m_iterator`
236
237
238 reference operator*() const;
239
240[*Returns: ] `**m_iterator`
241
242
243 indirect_iterator& operator++();
244
245[*Effects: ] `++m_iterator`[br]
246[*Returns: ] `*this`
247
248
249 indirect_iterator& operator--();
250
251[*Effects: ] `--m_iterator`[br]
252[*Returns: ] `*this`
253
254[endsect]