stl_iterator.h (istream_iterator::operator->): Fix return values.
[gcc.git] / libstdc++-v3 / include / bits / stl_iterator.h
1 /*
2 *
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
5 *
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 *
15 * Copyright (c) 1996-1998
16 * Silicon Graphics Computer Systems, Inc.
17 *
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
25 */
26
27 /* NOTE: This is an internal header file, included by other STL headers.
28 * You should not attempt to use it directly.
29 */
30
31 #ifndef __SGI_STL_INTERNAL_ITERATOR_H
32 #define __SGI_STL_INTERNAL_ITERATOR_H
33
34 namespace std
35 {
36 // 24.4.1 Reverse iterators
37 template<typename _Iterator>
38 class reverse_iterator
39 : public iterator<typename iterator_traits<_Iterator>::iterator_category,
40 typename iterator_traits<_Iterator>::value_type,
41 typename iterator_traits<_Iterator>::difference_type,
42 typename iterator_traits<_Iterator>::pointer,
43 typename iterator_traits<_Iterator>::reference>
44 {
45 protected:
46 _Iterator _M_current;
47
48 public:
49 typedef _Iterator iterator_type;
50 typedef typename iterator_traits<_Iterator>::difference_type
51 difference_type;
52 typedef typename iterator_traits<_Iterator>::reference reference;
53 typedef typename iterator_traits<_Iterator>::pointer pointer;
54
55 public:
56 reverse_iterator() {}
57
58 explicit
59 reverse_iterator(iterator_type __x) : _M_current(__x) {}
60
61 reverse_iterator(const reverse_iterator& __x)
62 : _M_current(__x._M_current) { }
63
64 template<typename _Iter>
65 reverse_iterator(const reverse_iterator<_Iter>& __x)
66 : _M_current(__x.base()) {}
67
68 iterator_type
69 base() const { return _M_current; }
70
71 reference
72 operator*() const
73 {
74 _Iterator __tmp = _M_current;
75 return *--__tmp;
76 }
77
78 pointer
79 operator->() const { return &(operator*()); }
80
81 reverse_iterator&
82 operator++()
83 {
84 --_M_current;
85 return *this;
86 }
87
88 reverse_iterator
89 operator++(int)
90 {
91 reverse_iterator __tmp = *this;
92 --_M_current;
93 return __tmp;
94 }
95
96 reverse_iterator&
97 operator--()
98 {
99 ++_M_current;
100 return *this;
101 }
102
103 reverse_iterator operator--(int)
104 {
105 reverse_iterator __tmp = *this;
106 ++_M_current;
107 return __tmp;
108 }
109
110 reverse_iterator
111 operator+(difference_type __n) const
112 { return reverse_iterator(_M_current - __n); }
113
114 reverse_iterator&
115 operator+=(difference_type __n)
116 {
117 _M_current -= __n;
118 return *this;
119 }
120
121 reverse_iterator
122 operator-(difference_type __n) const
123 { return reverse_iterator(_M_current + __n); }
124
125 reverse_iterator&
126 operator-=(difference_type __n)
127 {
128 _M_current += __n;
129 return *this;
130 }
131
132 reference
133 operator[](difference_type __n) const { return *(*this + __n); }
134 };
135
136 template<typename _Iterator>
137 inline bool
138 operator==(const reverse_iterator<_Iterator>& __x,
139 const reverse_iterator<_Iterator>& __y)
140 { return __x.base() == __y.base(); }
141
142 template<typename _Iterator>
143 inline bool
144 operator<(const reverse_iterator<_Iterator>& __x,
145 const reverse_iterator<_Iterator>& __y)
146 { return __y.base() < __x.base(); }
147
148 template<typename _Iterator>
149 inline bool
150 operator!=(const reverse_iterator<_Iterator>& __x,
151 const reverse_iterator<_Iterator>& __y)
152 { return !(__x == __y); }
153
154 template<typename _Iterator>
155 inline bool
156 operator>(const reverse_iterator<_Iterator>& __x,
157 const reverse_iterator<_Iterator>& __y)
158 { return __y < __x; }
159
160 template<typename _Iterator>
161 inline bool
162 operator<=(const reverse_iterator<_Iterator>& __x,
163 const reverse_iterator<_Iterator>& __y)
164 { return !(__y < __x); }
165
166 template<typename _Iterator>
167 inline bool
168 operator>=(const reverse_iterator<_Iterator>& __x,
169 const reverse_iterator<_Iterator>& __y)
170 { return !(__x < __y); }
171
172 template<typename _Iterator>
173 inline typename reverse_iterator<_Iterator>::difference_type
174 operator-(const reverse_iterator<_Iterator>& __x,
175 const reverse_iterator<_Iterator>& __y)
176 { return __y.base() - __x.base(); }
177
178 template<typename _Iterator>
179 inline reverse_iterator<_Iterator>
180 operator+(typename reverse_iterator<_Iterator>::difference_type __n,
181 const reverse_iterator<_Iterator>& __x)
182 { return reverse_iterator<_Iterator>(__x.base() - __n); }
183
184 // 24.4.2.2.1 back_insert_iterator
185 template<typename _Container>
186 class back_insert_iterator
187 : public iterator<output_iterator_tag, void, void, void, void>
188 {
189 protected:
190 _Container* container;
191
192 public:
193 typedef _Container container_type;
194
195 explicit
196 back_insert_iterator(_Container& __x) : container(&__x) {}
197
198 back_insert_iterator<_Container>&
199 operator=(const typename _Container::value_type& __value)
200 {
201 container->push_back(__value);
202 return *this;
203 }
204
205 back_insert_iterator<_Container>&
206 operator*() { return *this; }
207
208 back_insert_iterator<_Container>&
209 operator++() { return *this; }
210
211 back_insert_iterator<_Container>&
212 operator++(int) { return *this; }
213 };
214
215 template<typename _Container>
216 inline back_insert_iterator<_Container>
217 back_inserter(_Container& __x)
218 { return back_insert_iterator<_Container>(__x); }
219
220 template<typename _Container>
221 class front_insert_iterator
222 : public iterator<output_iterator_tag, void, void, void, void>
223 {
224 protected:
225 _Container* container;
226
227 public:
228 typedef _Container container_type;
229
230 explicit front_insert_iterator(_Container& __x) : container(&__x) {}
231 front_insert_iterator<_Container>&
232 operator=(const typename _Container::value_type& __value) {
233 container->push_front(__value);
234 return *this;
235 }
236 front_insert_iterator<_Container>& operator*() { return *this; }
237 front_insert_iterator<_Container>& operator++() { return *this; }
238 front_insert_iterator<_Container>& operator++(int) { return *this; }
239 };
240
241 template<typename _Container>
242 inline front_insert_iterator<_Container> front_inserter(_Container& __x)
243 { return front_insert_iterator<_Container>(__x); }
244
245 template<typename _Container>
246 class insert_iterator
247 : public iterator<output_iterator_tag, void, void, void, void>
248 {
249 protected:
250 _Container* container;
251 typename _Container::iterator iter;
252
253 public:
254 typedef _Container container_type;
255
256 insert_iterator(_Container& __x, typename _Container::iterator __i)
257 : container(&__x), iter(__i) {}
258
259 insert_iterator<_Container>&
260 operator=(const typename _Container::value_type& __value) {
261 iter = container->insert(iter, __value);
262 ++iter;
263 return *this;
264 }
265 insert_iterator<_Container>& operator*() { return *this; }
266 insert_iterator<_Container>& operator++() { return *this; }
267 insert_iterator<_Container>& operator++(int) { return *this; }
268 };
269
270 template<typename _Container, typename _Iterator>
271 inline
272 insert_iterator<_Container> inserter(_Container& __x, _Iterator __i)
273 {
274 typedef typename _Container::iterator __iter;
275 return insert_iterator<_Container>(__x, __iter(__i));
276 }
277
278
279 template<typename _Tp, typename _CharT = char,
280 typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
281 class istream_iterator
282 : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
283 {
284 public:
285 typedef _CharT char_type;
286 typedef _Traits traits_type;
287 typedef basic_istream<_CharT, _Traits> istream_type;
288
289 private:
290 istream_type* _M_stream;
291 _Tp _M_value;
292 bool _M_ok;
293
294 public:
295 istream_iterator() : _M_stream(0), _M_ok(false) {}
296 istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); }
297
298 const _Tp&
299 operator*() const { return _M_value; }
300
301 const _Tp*
302 operator->() const { return &(operator*()); }
303
304 istream_iterator&
305 operator++()
306 { _M_read(); return *this; }
307
308 istream_iterator
309 operator++(int)
310 {
311 istream_iterator __tmp = *this;
312 _M_read();
313 return __tmp;
314 }
315
316 bool
317 _M_equal(const istream_iterator& __x) const
318 { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream);}
319
320 private:
321 void _M_read()
322 {
323 _M_ok = (_M_stream && *_M_stream) ? true : false;
324 if (_M_ok)
325 {
326 *_M_stream >> _M_value;
327 _M_ok = *_M_stream ? true : false;
328 }
329 }
330 };
331
332 template<typename _Tp, typename _CharT, typename _Traits, typename _Dist>
333 inline bool
334 operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
335 const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
336 { return __x._M_equal(__y); }
337
338 template <class _Tp, class _CharT, class _Traits, class _Dist>
339 inline bool
340 operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
341 const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y)
342 { return !__x._M_equal(__y); }
343
344
345 template<typename _Tp, typename _CharT = char,
346 typename _Traits = char_traits<_CharT> >
347 class ostream_iterator
348 : public iterator<output_iterator_tag, void, void, void, void>
349 {
350 public:
351 typedef _CharT char_type;
352 typedef _Traits traits_type;
353 typedef basic_ostream<_CharT, _Traits> ostream_type;
354
355 private:
356 ostream_type* _M_stream;
357 const _CharT* _M_string;
358
359 public:
360 ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
361 ostream_iterator(ostream_type& __s, const _CharT* __c)
362 : _M_stream(&__s), _M_string(__c) { }
363
364 ostream_iterator&
365 operator=(const _Tp& __value)
366 {
367 *_M_stream << __value;
368 if (_M_string) *_M_stream << _M_string;
369 return *this;
370 }
371
372 ostream_iterator&
373 operator*() { return *this; }
374
375 ostream_iterator&
376 operator++() { return *this; }
377
378 ostream_iterator&
379 operator++(int) { return *this; }
380 };
381
382
383 // This iterator adapter is 'normal' in the sense that it does not
384 // change the semantics of any of the operators of its itererator
385 // parameter. Its primary purpose is to convert an iterator that is
386 // not a class, e.g. a pointer, into an iterator that is a class.
387 // The _Container parameter exists solely so that different containers
388 // using this template can instantiate different types, even if the
389 // _Iterator parameter is the same.
390 template<typename _Iterator, typename _Container>
391 class __normal_iterator
392 : public iterator<typename iterator_traits<_Iterator>::iterator_category,
393 typename iterator_traits<_Iterator>::value_type,
394 typename iterator_traits<_Iterator>::difference_type,
395 typename iterator_traits<_Iterator>::pointer,
396 typename iterator_traits<_Iterator>::reference>
397 {
398 protected:
399 _Iterator _M_current;
400
401 public:
402 typedef typename iterator_traits<_Iterator>::difference_type
403 difference_type;
404 typedef typename iterator_traits<_Iterator>::reference reference;
405 typedef typename iterator_traits<_Iterator>::pointer pointer;
406
407 __normal_iterator() : _M_current(_Iterator()) { }
408
409 explicit
410 __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
411
412 // Allow iterator to const_iterator conversion
413 template<typename _Iter>
414 inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
415 : _M_current(__i.base()) { }
416
417 // Forward iterator requirements
418 reference
419 operator*() const { return *_M_current; }
420
421 pointer
422 operator->() const { return _M_current; }
423
424 __normal_iterator&
425 operator++() { ++_M_current; return *this; }
426
427 __normal_iterator
428 operator++(int) { return __normal_iterator(_M_current++); }
429
430 // Bidirectional iterator requirements
431 __normal_iterator&
432 operator--() { --_M_current; return *this; }
433
434 __normal_iterator
435 operator--(int) { return __normal_iterator(_M_current--); }
436
437 // Random access iterator requirements
438 reference
439 operator[](const difference_type& __n) const
440 { return _M_current[__n]; }
441
442 __normal_iterator&
443 operator+=(const difference_type& __n)
444 { _M_current += __n; return *this; }
445
446 __normal_iterator
447 operator+(const difference_type& __n) const
448 { return __normal_iterator(_M_current + __n); }
449
450 __normal_iterator&
451 operator-=(const difference_type& __n)
452 { _M_current -= __n; return *this; }
453
454 __normal_iterator
455 operator-(const difference_type& __n) const
456 { return __normal_iterator(_M_current - __n); }
457
458 difference_type
459 operator-(const __normal_iterator& __i) const
460 { return _M_current - __i._M_current; }
461
462 const _Iterator&
463 base() const { return _M_current; }
464 };
465
466 // Forward iterator requirements
467 template<typename _IteratorL, typename _IteratorR, typename _Container>
468 inline bool
469 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
470 const __normal_iterator<_IteratorR, _Container>& __rhs)
471 { return __lhs.base() == __rhs.base(); }
472
473 template<typename _IteratorL, typename _IteratorR, typename _Container>
474 inline bool
475 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
476 const __normal_iterator<_IteratorR, _Container>& __rhs)
477 { return !(__lhs == __rhs); }
478
479 // Random access iterator requirements
480 template<typename _IteratorL, typename _IteratorR, typename _Container>
481 inline bool
482 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
483 const __normal_iterator<_IteratorR, _Container>& __rhs)
484 { return __lhs.base() < __rhs.base(); }
485
486 template<typename _IteratorL, typename _IteratorR, typename _Container>
487 inline bool
488 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
489 const __normal_iterator<_IteratorR, _Container>& __rhs)
490 { return __rhs < __lhs; }
491
492 template<typename _IteratorL, typename _IteratorR, typename _Container>
493 inline bool
494 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
495 const __normal_iterator<_IteratorR, _Container>& __rhs)
496 { return !(__rhs < __lhs); }
497
498 template<typename _IteratorL, typename _IteratorR, typename _Container>
499 inline bool
500 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
501 const __normal_iterator<_IteratorR, _Container>& __rhs)
502 { return !(__lhs < __rhs); }
503
504 template<typename _Iterator, typename _Container>
505 inline __normal_iterator<_Iterator, _Container>
506 operator+(__normal_iterator<_Iterator, _Container>::difference_type __n,
507 const __normal_iterator<_Iterator, _Container>& __i)
508 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
509 } // namespace std
510
511 #endif
512
513 // Local Variables:
514 // mode:C++
515 // End: