File: indirect_iterator.htm

package info (click to toggle)
boost 1.27.0-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 19,908 kB
  • ctags: 26,546
  • sloc: cpp: 122,225; ansic: 10,956; python: 4,412; sh: 855; yacc: 803; makefile: 257; perl: 165; lex: 90; csh: 6
file content (444 lines) | stat: -rw-r--r-- 15,531 bytes parent folder | download
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">

<html>
<head>
    <meta name="generator" content="HTML Tidy, see www.w3.org">
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
    <meta name="ProgId" content="FrontPage.Editor.Document">

    <title>Indirect Iterator Adaptor Documentation</title>
</head>

<body bgcolor="#FFFFFF" text="#000000">
	
    <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
    "center" width="277" height="86"> 

    <h1>Indirect Iterator Adaptor</h1>
    Defined in header <a href=
    "../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> 

    <p>The indirect iterator adaptor augments an iterator by applying an
    <b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this
    iterator makes it possible to view a container of pointers or
    smart-pointers (e.g. <tt>std::list&lt;boost::shared_ptr&lt;foo&gt;
    &gt;</tt>) as if it were a container of the pointed-to type. The following
    <b>pseudo-code</b> shows the basic idea of the indirect iterator:

    <blockquote>
<pre>
// inside a hypothetical indirect_iterator class...
typedef std::iterator_traits&lt;BaseIterator&gt;::value_type Pointer;
typedef std::iterator_traits&lt;Pointer&gt;::reference reference;

reference indirect_iterator::operator*() const {
  return **this-&gt;base_iterator;
}
</pre>
    </blockquote>

    <h2>Synopsis</h2>

    <blockquote>
<pre>
namespace boost {
  template &lt;class BaseIterator,
            class Value, class Reference, class Category, class Pointer&gt;
  struct indirect_iterator_generator;
  
  template &lt;class BaseIterator,
            class Value, class Reference, class ConstReference, 
            class Category, class Pointer, class ConstPointer&gt;
  struct indirect_iterator_pair_generator;

  template &lt;class BaseIterator&gt;
  typename indirect_iterator_generator&lt;BaseIterator&gt;::type
  make_indirect_iterator(BaseIterator base)  
}
</pre>
    </blockquote>
    <hr>

    <h2><a name="indirect_iterator_generator">The Indirect Iterator Type
    Generator</a></h2>
    The <tt>indirect_iterator_generator</tt> template is a <a href=
    "../../more/generic_programming.html#type_generator">generator</a> of
    indirect iterator types. The main template parameter for this class is the
    <tt>BaseIterator</tt> type that is being wrapped. In most cases the type of
    the elements being pointed to can be deduced using
    <tt>std::iterator_traits</tt>, but in some situations the user may want to
    override this type, so there are also template parameters that allow a user
    to control the <tt>value_type</tt>, <tt>pointer</tt>, and
    <tt>reference</tt> types of the resulting iterators. 

    <blockquote>
<pre>
template &lt;class BaseIterator,
          class Value, class Reference, class Pointer&gt;
class indirect_iterator_generator
{
public:
  typedef <tt><a href=
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> type; // the resulting indirect iterator type 
};
</pre>
    </blockquote>

    <h3>Example</h3>
    This example uses the <tt>indirect_iterator_generator</tt> to create
    indirect iterators which dereference the pointers stored in the
    <tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the
    <tt>characters</tt> array. 

    <blockquote>
<pre>
#include &lt;boost/config.hpp&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;boost/iterator_adaptors.hpp&gt;

int main(int, char*[])
{
  char characters[] = "abcdefg";
  const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
  char* pointers_to_chars[N];                        // at the end.
  for (int i = 0; i &lt; N; ++i)
    pointers_to_chars[i] = &amp;characters[i];
  
  boost::indirect_iterator_generator&lt;char**, char&gt;::type 
    indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);

  std::copy(indirect_first, indirect_last, std::ostream_iterator&lt;char&gt;(std::cout, ","));
  std::cout &lt;&lt; std::endl;
  
  // to be continued...
</pre>
    </blockquote>

    <h3>Template Parameters</h3>

    <table border>
      <tr>
        <th>Parameter

        <th>Description

      <tr>
        <td><tt>BaseIterator</tt> 

        <td>The iterator type being wrapped. The <tt>value_type</tt>
        of the base iterator should itself be dereferenceable.  
        The return type of the <tt>operator*</tt> for the
        <tt>value_type</tt> should match the <tt>Reference</tt> type.

      <tr>
        <td><tt>Value</tt> 

        <td>The <tt>value_type</tt> of the resulting iterator, unless const. If
        Value is <tt>const X</tt>, a conforming compiler makes the
        <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
        "iterator_adaptors.htm#1">[1]</a>. Note that if the default
         is used for <tt>Value</tt>, then there must be a valid specialization
         of <tt>iterator_traits</tt> for the value type of the base iterator.
         <br>
         <b>Default:</b> <tt>std::iterator_traits&lt;<br>
          std::iterator_traits&lt;BaseIterator&gt;::value_type
        &gt;::value_type</tt><a href="#2">[2]</a> 

      <tr>
        <td><tt>Reference</tt> 

        <td>The <tt>reference</tt> type of the resulting iterator, and in
        particular, the result type of <tt>operator*()</tt>.<br>
         <b>Default:</b> <tt>Value&amp;</tt> 

      <tr>
        <td><tt>Pointer</tt> 

        <td>The <tt>pointer</tt> type of the resulting iterator, and in
        particular, the result type of <tt>operator-&gt;()</tt>.<br>
         <b>Default:</b> <tt>Value*</tt> 

      <tr>
        <td><tt>Category</tt> 
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
         <b>Default:</b>
        <tt>std::iterator_traits&lt;BaseIterator&gt;::iterator_category</tt> 

    </table>

    <h3>Concept Model</h3>
    The indirect iterator will model whichever <a href=
    "http://www.sgi.com/tech/stl/Iterators.html">standard iterator
    concept category</a> is modeled by the base iterator. Thus, if the
    base iterator is a model of <a href=
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
    Access Iterator</a> then so is the resulting indirect iterator. If
    the base iterator models a more restrictive concept, the resulting
    indirect iterator will model the same concept <a href="#3">[3]</a>.

    <h3>Members</h3>
    The indirect iterator type implements the member functions and operators
    required of the <a href=
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
    Iterator</a> concept. In addition it has the following constructor: 
<pre>
explicit indirect_iterator_generator::type(const BaseIterator&amp; it)
</pre>
    <br>
     <br>
     
    <hr>

    <p>

    <h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair
    Generator</a></h2>
    Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is
    needed, such as when implementing a container. The
    <tt>indirect_iterator_pair_generator</tt> class makes it more convenient to
    create this pair of iterator types. 

    <blockquote>
<pre>
  template &lt;class BaseIterator,
            class Value, class Reference, class ConstReference, 
            class Category, class Pointer, class ConstPointer&gt;
  struct indirect_iterator_pair_generator;
{
public:
  typedef <tt><a href=
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> iterator;       // the mutable indirect iterator type 
  typedef <tt><a href=
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> const_iterator; // the immutable indirect iterator type 
};
</pre>
    </blockquote>

    <h3>Example</h3>

    <blockquote>
<pre>
  // continuing from the last example...

  typedef boost::indirect_iterator_pair_generator&lt;char**,
    char, char*, char&amp;, const char*, const char&amp;&gt; PairGen;

  char mutable_characters[N];
  char* pointers_to_mutable_chars[N];
  for (int i = 0; i &lt; N; ++i)
    pointers_to_mutable_chars[i] = &amp;mutable_characters[i];

  PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
    mutable_indirect_last(pointers_to_mutable_chars + N);
  PairGen::const_iterator const_indirect_first(pointers_to_chars),
    const_indirect_last(pointers_to_chars + N);

  std::transform(const_indirect_first, const_indirect_last,
     mutable_indirect_first, std::bind1st(std::plus&lt;char&gt;(), 1));

  std::copy(mutable_indirect_first, mutable_indirect_last,
      std::ostream_iterator&lt;char&gt;(std::cout, ","));
  std::cout &lt;&lt; std::endl;
  // to be continued...
</pre>
    </blockquote>

    <p>The output is:

    <blockquote>
<pre>
b,c,d,e,f,g,h,
</pre>
    </blockquote>

    <h3>Template Parameters</h3>

    <table border>
      <tr>
        <th>Parameter

        <th>Description

      <tr>
        <td><tt>BaseIterator</tt> 

        <td>The iterator type being wrapped. The <tt>value_type</tt> of the
        base iterator should itself be dereferenceable.
        The return type of the <tt>operator*</tt> for the
        <tt>value_type</tt> should match the <tt>Reference</tt> type.

      <tr>
        <td><tt>Value</tt> 

        <td>The <tt>value_type</tt> of the resulting iterators.
         If Value is <tt>const X</tt>, a conforming compiler makes the
         <tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
         "iterator_adaptors.htm#1">[1]</a>. Note that if the default
         is used for <tt>Value</tt>, then there must be a valid
         specialization of <tt>iterator_traits</tt> for the value type
         of the base iterator.<br>

         <b>Default:</b> <tt>std::iterator_traits&lt;<br>
          std::iterator_traits&lt;BaseIterator&gt;::value_type
        &gt;::value_type</tt><a href="#2">[2]</a> 

      <tr>
        <td><tt>Reference</tt> 

        <td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and
        in particular, the result type of its <tt>operator*()</tt>.<br>
         <b>Default:</b> <tt>Value&amp;</tt> 

      <tr>
        <td><tt>ConstReference</tt> 

        <td>The <tt>reference</tt> type of the resulting
        <tt>const_iterator</tt>, and in particular, the result type of its
        <tt>operator*()</tt>.<br>
         <b>Default:</b> <tt>const Value&amp;</tt> 

      <tr>
        <td><tt>Category</tt> 
        <td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
         <b>Default:</b>
        <tt>std::iterator_traits&lt;BaseIterator&gt;::iterator_category</tt> 

      <tr>
        <td><tt>Pointer</tt> 

        <td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and
        in particular, the result type of its <tt>operator-&gt;()</tt>.<br>
         <b>Default:</b> <tt>Value*</tt> 

      <tr>
        <td><tt>ConstPointer</tt> 

        <td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>,
        and in particular, the result type of its <tt>operator-&gt;()</tt>.<br>
         <b>Default:</b> <tt>const Value*</tt> 

    </table>

    <h3>Concept Model</h3>

    The indirect iterators will model whichever <a href=
    "http://www.sgi.com/tech/stl/Iterators.html">standard iterator
    concept category</a> is modeled by the base iterator. Thus, if the
    base iterator is a model of <a href=
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
    Access Iterator</a> then so are the resulting indirect
    iterators. If the base iterator models a more restrictive concept,
    the resulting indirect iterators will model the same concept <a
    href="#3">[3]</a>.


    <h3>Members</h3>
    The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement
    the member functions and operators required of the <a href=
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
    Iterator</a> concept. In addition they support the following constructors: 

    <blockquote>
<pre>
explicit indirect_iterator_pair_generator::iterator(const BaseIterator&amp; it)
explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator&amp; it)
</pre>
    </blockquote>
    <br>
     <br>
     
    <hr>

    <p>

    <h2><a name="make_indirect_iterator">The Indirect Iterator Object
    Generator</a></h2>
    The <tt>make_indirect_iterator()</tt> function provides a more convenient
    way to create indirect iterator objects. The function saves the user the
    trouble of explicitly writing out the iterator types. 

    <blockquote>
<pre>
template &lt;class BaseIterator&gt;
typename indirect_iterator_generator&lt;BaseIterator&gt;::type
make_indirect_iterator(BaseIterator base)  
</pre>
    </blockquote>

    <h3>Example</h3>
    Here we again print the <tt>char</tt>s from the array <tt>characters</tt>
    by accessing them through the array of pointers <tt>pointer_to_chars</tt>,
    but this time we use the <tt>make_indirect_iterator()</tt> function which
    saves us some typing. 

    <blockquote>
<pre>
  // continuing from the last example...

  std::copy(boost::make_indirect_iterator(pointers_to_chars), 
      boost::make_indirect_iterator(pointers_to_chars + N),
      std::ostream_iterator&lt;char&gt;(std::cout, ","));
  std::cout &lt;&lt; std::endl;

  return 0;
}
</pre>
    </blockquote>
    The output is: 

    <blockquote>
<pre>
a,b,c,d,e,f,g,
</pre>
    </blockquote>
    <hr>

    <h3>Notes</h3>

    <p>

    <p><a name="2">[2]</a> If your compiler does not support partial
    specialization and the base iterator or its <tt>value_type</tt> is a
    builtin pointer type, you will not be able to use the default for
    <tt>Value</tt> and will need to specify this type explicitly.

    <p><a name="3">[3]</a>There is a caveat to which concept the
    indirect iterator can model.  If the return type of the
    <tt>operator*</tt> for the base iterator's value type is not a
    true reference, then strickly speaking, the indirect iterator can
    not be a model of <a href=
    "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
    Iterator</a> or any of the concepts that refine it. In this case
    the <tt>Category</tt> for the indirect iterator should be
    specified as <tt>std::input_iterator_tag</tt>. However, even in
    this case, if the base iterator is a random access iterator, the
    resulting indirect iterator will still satisfy most of the
    requirements for <a href=
    "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
    Access Iterator</a>.
    
    <hr>

    <p>Revised 
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->18 Sep 2001<!--webbot bot="Timestamp" endspan i-checksum="14941" -->


    <p>&copy; Copyright Jeremy Siek and David Abrahams 2001. Permission to
    copy, use, modify, sell and distribute this document is granted provided
    this copyright notice appears in all copies. This document is provided "as
    is" without express or implied warranty, and with no claim as to its
    suitability for any purpose. 
    <!--  LocalWords:  html charset alt gif hpp BaseIterator const namespace struct
             -->
     
    <!--  LocalWords:  ConstPointer ConstReference typename iostream int abcdefg
             -->
     <!--  LocalWords:  sizeof  PairGen pre Jeremy Siek David Abrahams
             -->


</body>
</html>