OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [doc/] [xml/] [manual/] [iterators.xml] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
2
3
 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
4
[ ]>
5
 
6
7
8
 
9
10
  
11
    
12
      ISO C++
13
    
14
    
15
      library
16
    
17
  
18
19
 
20
</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>21</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>  Iterators</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>22</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>  <indexterm><primary>Iterators</primary></indexterm></code></pre></td>
      </tr>
      <tr valign="middle">
         <td>23</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>
24
 
25
26
27
  Predefined
28
 
29
  
30
    Iterators vs. Pointers
31
   
32
     The following
33
FAQ entry points out that
34
iterators are not implemented as pointers.  They are a generalization
35
of pointers, but they are implemented in libstdc++ as separate
36
classes.
37
   
38
   
39
     Keeping that simple fact in mind as you design your code will
40
      prevent a whole lot of difficult-to-understand bugs.
41
   
42
   
43
     You can think of it the other way 'round, even.  Since iterators
44
     are a generalization, that means
45
     that pointers are
46
      iterators, and that pointers can be used
47
     whenever an iterator would be.  All those functions in the
48
     Algorithms sect1 of the Standard will work just as well on plain
49
     arrays and their pointers.
50
   
51
   
52
     That doesn't mean that when you pass in a pointer, it gets
53
      wrapped into some special delegating iterator-to-pointer class
54
      with a layer of overhead.  (If you think that's the case
55
      anywhere, you don't understand templates to begin with...)  Oh,
56
      no; if you pass in a pointer, then the compiler will instantiate
57
      that template using T* as a type, and good old high-speed
58
      pointer arithmetic as its operations, so the resulting code will
59
      be doing exactly the same things as it would be doing if you had
60
      hand-coded it yourself (for the 273rd time).
61
   
62
   
63
     How much overhead is there when using an
64
      iterator class?  Very little.  Most of the layering classes
65
      contain nothing but typedefs, and typedefs are
66
      "meta-information" that simply tell the compiler some
67
      nicknames; they don't create code.  That information gets passed
68
      down through inheritance, so while the compiler has to do work
69
      looking up all the names, your runtime code does not.  (This has
70
      been a prime concern from the beginning.)
71
   
72
 
73
 
74
  
75
 
76
  
77
    One Past the End
78
 
79
   This starts off sounding complicated, but is actually very easy,
80
      especially towards the end.  Trust me.
81
   
82
   Beginners usually have a little trouble understand the whole
83
      'past-the-end' thing, until they remember their early algebra classes
84
      (see, they told you that stuff would come in handy!) and
85
      the concept of half-open ranges.
86
   
87
   First, some history, and a reminder of some of the funkier rules in
88
      C and C++ for builtin arrays.  The following rules have always been
89
      true for both languages:
90
   
91
   
92
      
93
        You can point anywhere in the array, or to the first element
94
          past the end of the array.  A pointer that points to one
95
          past the end of the array is guaranteed to be as unique as a
96
          pointer to somewhere inside the array, so that you can compare
97
          such pointers safely.
98
        
99
      
100
      
101
        You can only dereference a pointer that points into an array.
102
          If your array pointer points outside the array -- even to just
103
          one past the end -- and you dereference it, Bad Things happen.
104
        
105
      
106
      
107
        Strictly speaking, simply pointing anywhere else invokes
108
          undefined behavior.  Most programs won't puke until such a
109
          pointer is actually dereferenced, but the standards leave that
110
          up to the platform.
111
        
112
      
113
   
114
   The reason this past-the-end addressing was allowed is to make it
115
      easy to write a loop to go over an entire array, e.g.,
116
      while (*d++ = *s++);.
117
   
118
   So, when you think of two pointers delimiting an array, don't think
119
      of them as indexing 0 through n-1.  Think of them as boundary
120
      markers:
121
   
122
   
123
 
124
   beginning            end
125
     |                   |
126
     |                   |               This is bad.  Always having to
127
     |                   |               remember to add or subtract one.
128
     |                   |               Off-by-one bugs very common here.
129
     V                   V
130
        array of N elements
131
     |---|---|--...--|---|---|
132
     | 0 | 1 |  ...  |N-2|N-1|
133
     |---|---|--...--|---|---|
134
 
135
     ^                       ^
136
     |                       |
137
     |                       |           This is good.  This is safe.  This
138
     |                       |           is guaranteed to work.  Just don't
139
     |                       |           dereference 'end'.
140
   beginning                end
141
 
142
   
143
   See?  Everything between the boundary markers is chapter of the array.
144
      Simple.
145
   
146
   Now think back to your junior-high school algebra course, when you
147
      were learning how to draw graphs.  Remember that a graph terminating
148
      with a solid dot meant, "Everything up through this point,"
149
      and a graph terminating with an open dot meant, "Everything up
150
      to, but not including, this point," respectively called closed
151
      and open ranges?  Remember how closed ranges were written with
152
      brackets, [a,b], and open ranges were written with parentheses,
153
      (a,b)?
154
   
155
   The boundary markers for arrays describe a half-open range,
156
      starting with (and including) the first element, and ending with (but
157
      not including) the last element:  [beginning,end).  See, I
158
      told you it would be simple in the end.
159
   
160
   Iterators, and everything working with iterators, follows this same
161
      time-honored tradition.  A container's begin() method returns
162
      an iterator referring to the first element, and its end()
163
      method returns a past-the-end iterator, which is guaranteed to be
164
      unique and comparable against any other iterator pointing into the
165
      middle of the container.
166
   
167
   Container constructors, container methods, and algorithms, all take
168
      pairs of iterators describing a range of values on which to operate.
169
      All of these ranges are half-open ranges, so you pass the beginning
170
      iterator as the starting parameter, and the one-past-the-end iterator
171
      as the finishing parameter.
172
   
173
   This generalizes very well.  You can operate on sub-ranges quite
174
      easily this way; functions accepting a [first,last) range
175
      don't know or care whether they are the boundaries of an entire {array,
176
      sequence, container, whatever}, or whether they only enclose a few
177
      elements from the center.  This approach also makes zero-length
178
      sequences very simple to recognize:  if the two endpoints compare
179
      equal, then the {array, sequence, container, whatever} is empty.
180
   
181
   Just don't dereference end().
182
   
183
 
184
  
185
186
 
187
188
 
189

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.