1 // iterator standard header
2 #pragma once
3 #ifndef _ITERATOR_
4 #define _ITERATOR_
5 #ifndef RC_INVOKED
6 #include <xutility>
7
8 #ifdef _MSC_VER
9  #pragma pack(push,_CRT_PACKING)
10  #pragma warning(push,3)
11 #endif  /* _MSC_VER */
12
13 _STD_BEGIN
14
15         // TEMPLATE CLASS back_insert_iterator
16 template<class _Container>
17     class back_insert_iterator
18         : public _Outit
19     {    // wrap pushes to back of container as output iterator
20 public:
21     typedef _Container container_type;
22     typedef typename _Container::reference reference;
23
24     typedef _Range_checked_iterator_tag _Checked_iterator_category;
25
26     explicit back_insert_iterator(_Container& _Cont)
27         : container(&_Cont)
28         {    // construct with container
29         }
30
31     back_insert_iterator<_Container>& operator=(
32         typename _Container::const_reference _Val)
33         {    // push value into container
34         container->push_back(_Val);
35         return (*this);
36         }
37
38     back_insert_iterator<_Container>& operator*()
39         {    // pretend to return designated value
40         return (*this);
41         }
42
43     back_insert_iterator<_Container>& operator++()
44         {    // pretend to preincrement
45         return (*this);
46         }
47
48     back_insert_iterator<_Container> operator++(int)
49         {    // pretend to postincrement
50         return (*this);
51         }
52
53 protected:
54     _Container *container;    // pointer to container
55     };
56
57         // TEMPLATE FUNCTION back_inserter
58 template<class _Container> inline
59     back_insert_iterator<_Container> back_inserter(_Container& _Cont)
60     {    // return a back_insert_iterator
61     return (std::back_insert_iterator<_Container>(_Cont));
62     }
63
64         // TEMPLATE CLASS front_insert_iterator
65 template<class _Container>
66     class front_insert_iterator
67         : public _Outit
68     {    // wrap pushes to front of container as output iterator
69 public:
70     typedef _Container container_type;
71     typedef typename _Container::reference reference;
72
73     typedef _Range_checked_iterator_tag _Checked_iterator_category;
74
75     explicit front_insert_iterator(_Container& _Cont)
76         : container(&_Cont)
77         {    // construct with container
78         }
79
80     front_insert_iterator<_Container>& operator=(
81         typename _Container::const_reference _Val)
82         {    // push value into container
83         container->push_front(_Val);
84         return (*this);
85         }
86
87     front_insert_iterator<_Container>& operator*()
88         {    // pretend to return designated value
89         return (*this);
90         }
91
92     front_insert_iterator<_Container>& operator++()
93         {    // pretend to preincrement
94         return (*this);
95         }
96
97     front_insert_iterator<_Container> operator++(int)
98         {    // pretend to postincrement
99         return (*this);
100         }
101
102 protected:
103     _Container *container;    // pointer to container
104     };
105
106         // TEMPLATE FUNCTION front_inserter
107 template<class _Container> inline
108     front_insert_iterator<_Container> front_inserter(_Container& _Cont)
109     {    // return front_insert_iterator
110     return (std::front_insert_iterator<_Container>(_Cont));
111     }
112
113         // TEMPLATE CLASS insert_iterator
114 template<class _Container>
115     class insert_iterator
116         : public _Outit
117     {    // wrap inserts into container as output iterator
118 public:
119     typedef _Container container_type;
120     typedef typename _Container::reference reference;
121
122     typedef _Range_checked_iterator_tag _Checked_iterator_category;
123
124     insert_iterator(_Container& _Cont, typename _Container::iterator _Where)
125         : container(&_Cont), iter(_Where)
126         {    // construct with container and iterator
127         }
128
129     insert_iterator<_Container>& operator=(
130         typename _Container::const_reference _Val)
131         {    // insert into container and increment stored iterator
132         iter = container->insert(iter, _Val);
133         ++iter;
134         return (*this);
135         }
136
137     insert_iterator<_Container>& operator*()
138         {    // pretend to return designated value
139         return (*this);
140         }
141
142     insert_iterator<_Container>& operator++()
143         {    // pretend to preincrement
144         return (*this);
145         }
146
147     insert_iterator<_Container>& operator++(int)
148         {    // pretend to postincrement
149         return (*this);
150         }
151
152 protected:
153     _Container *container;    // pointer to container
154     typename _Container::iterator iter;    // iterator into container
155     };
156
157         // TEMPLATE FUNCTION inserter
158 template<class _Container,
159     class _Iter> inline
160     insert_iterator<_Container> inserter(_Container& _Cont, _Iter _Where)
161     {    // return insert_iterator
162     return (std::insert_iterator<_Container>(_Cont, _Where));
163     }
164
165         // TEMPLATE CLASS istream_iterator
166 template<class _Ty,
167     class _Elem = char,
168     class _Traits = char_traits<_Elem>,
169     class _Diff = ptrdiff_t>
170     class istream_iterator
171         : public iterator<input_iterator_tag, _Ty, _Diff,
172             const _Ty *, const _Ty&>
173     {    // wrap _Ty extracts from input stream as input iterator
174     typedef istream_iterator<_Ty, _Elem, _Traits, _Diff> _Myt;
175 public:
176     typedef _Elem char_type;
177     typedef _Traits traits_type;
178     typedef basic_istream<_Elem, _Traits> istream_type;
179
180 #if _SECURE_SCL
181     typedef _Range_checked_iterator_tag _Checked_iterator_category;
182 #endif
183
184     istream_iterator()
185         : _Myistr(0)
186         {    // construct singular iterator
187         }
188
189     istream_iterator(istream_type& _Istr)
190         : _Myistr(&_Istr)
191         {    // construct with input stream
192         _Getval();
193         }
194
195     const _Ty& operator*() const
196         {    // return designated value
197
198  #if _HAS_ITERATOR_DEBUGGING
199         if (_Myistr == 0)
200             {
201             _DEBUG_ERROR("istream_iterator is not dereferencable");
202             _SCL_SECURE_OUT_OF_RANGE;
203             }
204  #else
205         _SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
206  #endif /* _HAS_ITERATOR_DEBUGGING */
207
208         return (_Myval);
209         }
210
211     const _Ty *operator->() const
212         {    // return pointer to class object
213         return (&**this);
214         }
215
216     _Myt& operator++()
217         {    // preincrement
218
219  #if _HAS_ITERATOR_DEBUGGING
220         if (_Myistr == 0)
221             {
222             _DEBUG_ERROR("istream_iterator is not incrementable");
223             _SCL_SECURE_OUT_OF_RANGE;
224             }
225  #else
226         _SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
227  #endif /* _HAS_ITERATOR_DEBUGGING */
228
229         _Getval();
230         return (*this);
231         }
232
233     _Myt operator++(int)
234         {    // postincrement
235         _Myt _Tmp = *this;
236         ++*this;
237         return (_Tmp);
238         }
239
240     bool _Equal(const _Myt& _Right) const
241         {    // test for iterator equality
242         return (_Myistr == _Right._Myistr);
243         }
244
245 protected:
246     void _Getval()
247         {    // get a _Ty value if possible
248         if (_Myistr != 0 && !(*_Myistr >> _Myval))
249             _Myistr = 0;
250         }
251
252     static void _Xran()
253         {    // report an out_of_range error
254         _THROW(out_of_range, "invalid istream_iterator");
255         }
256
257     istream_type *_Myistr;    // pointer to input stream
258     _Ty _Myval;    // lookahead value (valid if _Myistr is not null)
259     };
260
261         // istream_iterator TEMPLATE OPERATORS
262 template<class _Ty,
263     class _Elem,
264     class _Traits,
265     class _Diff> inline
266     bool operator==(
267         const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left,
268         const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right)
269     {    // test for istream_iterator equality
270     return (_Left._Equal(_Right));
271     }
272
273 template<class _Ty,
274     class _Elem,
275     class _Traits,
276     class _Diff> inline
277     bool operator!=(
278         const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Left,
279         const istream_iterator<_Ty, _Elem, _Traits, _Diff>& _Right)
280     {    // test for istream_iterator inequality
281     return (!(_Left == _Right));
282     }
283
284         // TEMPLATE CLASS ostream_iterator
285 template<class _Ty,
286     class _Elem = char,
287     class _Traits = char_traits<_Elem> >
288     class ostream_iterator
289         : public _Outit
290     {    // wrap _Ty inserts to output stream as output iterator
291 public:
292     typedef _Elem char_type;
293     typedef _Traits traits_type;
294     typedef basic_ostream<_Elem, _Traits> ostream_type;
295
296 #if _SECURE_SCL
297     typedef _Range_checked_iterator_tag _Checked_iterator_category;
298 #endif
299
300     ostream_iterator(ostream_type& _Ostr,
301         const _Elem *_Delim = 0)
302         : _Myostr(&_Ostr), _Mydelim(_Delim)
303         {    // construct from output stream and delimiter
304         }
305
306     ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
307         {    // insert value into output stream, followed by delimiter
308         *_Myostr << _Val;
309         if (_Mydelim != 0)
310             *_Myostr << _Mydelim;
311
312  #if _HAS_ITERATOR_DEBUGGING
313         if (!*_Myostr)
314             {
315             _DEBUG_ERROR("ostream_iterator is not dereferencable");
316             _SCL_SECURE_OUT_OF_RANGE;
317             }
318  #else
319         _SCL_SECURE_VALIDATE_RANGE(*_Myostr != NULL);
320  #endif /* _HAS_ITERATOR_DEBUGGING */
321
322         return (*this);
323         }
324
325     ostream_iterator<_Ty, _Elem, _Traits>& operator*()
326         {    // pretend to return designated value
327         return (*this);
328         }
329
330     ostream_iterator<_Ty, _Elem, _Traits>& operator++()
331         {    // pretend to preincrement
332         return (*this);
333         }
334
335     ostream_iterator<_Ty, _Elem, _Traits> operator++(int)
336         {    // pretend to postincrement
337         return (*this);
338         }
339
340 protected:
341     static void _Xran()
342         {    // report an out_of_range error
343         _THROW(out_of_range, "invalid ostream_iterator");
344         }
345
346     const _Elem *_Mydelim;    // pointer to delimiter string (NB: not freed)
347     ostream_type *_Myostr;    // pointer to output stream
348     };
349
350 _STD_END
351
352 _STDEXT_BEGIN
353
354 // checked_iterator
355 template <class _Cont, class _Iter = typename _Cont::iterator>
356     class checked_iterator
357         : public _STD iterator<
358             typename _STD iterator_traits<_Iter>::iterator_category, 
359             typename _STD iterator_traits<_Iter>::value_type, 
360             typename _STD iterator_traits<_Iter>::difference_type, 
361             typename _STD iterator_traits<_Iter>::pointer, 
362             typename _STD iterator_traits<_Iter>::reference>
363     {
364     friend class checked_iterator;
365 public:
366     typedef checked_iterator<_Cont, _Iter> _Myt;
367     typedef typename _STD iterator_traits<_Iter>::difference_type difference_type;
368     typedef typename _STD iterator_traits<_Iter>::pointer pointer;
369     typedef typename _STD iterator_traits<_Iter>::reference reference;
370
371     typedef _STD _Range_checked_iterator_tag _Checked_iterator_category;
372     typedef _Iter _Inner_type;
373
374     typedef _Iter _Checked_iterator_base_type;
375  
376     _Checked_iterator_base_type _Checked_iterator_base() const
377     {
378         return _Current;
379     }
380
381     void _Checked_iterator_assign_from_base(_Checked_iterator_base_type _Base)
382     {
383         _Current = _Base;
384     }
385
386     // use default copy constructor and copy assignement
387
388     checked_iterator()
389         : _Mycont(NULL)
390     {
391     }
392
393     checked_iterator(_Cont& _C, _Iter _Ptr)
394         : _Mycont(&_C), _Current(_Ptr)
395     {
396     }
397
398     checked_iterator(const _Myt &_Right)
399         : _Mycont(_Right._Mycont), _Current(_Right._Current)
400     {
401     }
402
403     template <class Iter2>
404     checked_iterator(const checked_iterator<_Cont, Iter2> &_Right)
405         : _Mycont(_Right._Mycont), _Current(_Right._Current)
406     {
407     }
408
409     _Iter base() const
410     {
411         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
412         return _Current;
413     }
414
415     template <class Iter2>
416     bool operator==(const checked_iterator<_Cont, Iter2>& _Right) const
417     {
418         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont == _Right._Mycont);
419         return _Current == _Right._Current;
420     }
421
422     template <class Iter2>
423     bool operator!=(const checked_iterator<_Cont, Iter2>& _Right) const
424     {
425         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
426         return !(*this == _Right);
427     }
Lines 428 ... 437 are skipped.
438     {
439         return _Right < *this;
440     }
441
442     template <class Iter2>
443     bool operator<=(const checked_iterator<_Cont, Iter2>& _Right) const
444     {
445         return !(_Right < *this);
446     }
447
448     template <class Iter2>
449     bool operator>=(const checked_iterator<_Cont, Iter2>& _Right) const
450     {
451         return !(*this < _Right);
452     }
453
454     reference operator*() const
455     {
456         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
457         _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->end());
458         return *_Current;
459     }
460
461     pointer operator->() const
462     {
463         return (&**this);
464     }
465
466     _Myt& operator++()
467     {
468         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
469         _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->end());
470         ++_Current;
471         return *this;
472     }
473
474     _Myt operator++(int)
475     {
476         _Myt _Tmp = *this;
477         ++*this;
478         return _Tmp;
479     }
480
481     _Myt& operator--()
482     {
483         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
484         _SCL_SECURE_ALWAYS_VALIDATE_RANGE(_Current != _Mycont->begin());
485         --_Current;
486         return *this;
487     }
488
489     _Myt operator--(int)
490     {
491         _Myt _Tmp = *this;
492         --*this;
493         return _Tmp;
494     }
495
496     // random access iterators methods
497
498     _Myt& operator+=(difference_type _Off)
499     {
500         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
501         _SCL_SECURE_ALWAYS_VALIDATE_RANGE((_Mycont->end() - _Current) >= _Off && (_Mycont->begin() - _Current) <= _Off);
502         _Current += _Off;
503         return *this;
504     }
505
506     _Myt operator+(difference_type _Off) const
507     {
508         _Myt _Tmp = *this;
509         return (_Tmp += _Off);
510     }
511
512     _Myt& operator-=(difference_type _Off)
513     {
514         return (*this += -_Off);
515     }
516
517     _Myt operator-(difference_type _Off) const
518     {
519         _Myt _Tmp = *this;
520         return (_Tmp -= _Off);
521     }
522
523     difference_type operator-(const _Myt& _Right) const
524     {
525         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL && _Mycont == _Right._Mycont);
526         return _Current - _Right._Current;
527     }
528
529     reference operator[](difference_type _Off) const
530     {
531         _SCL_SECURE_ALWAYS_VALIDATE(_Mycont != NULL);
532         _SCL_SECURE_ALWAYS_VALIDATE_RANGE((_Mycont->end() - _Current) > _Off && (_Mycont->begin() - _Current) <= _Off);
533         return _Current[_Off];
534     }
535
536 protected:
537     void _Xran() const
538     {    // report an out_of_range error
539         _THROW(_STD out_of_range, "invalid checked_iterator<T> subscript");
540     }
541
542     void _Xinvarg() const
543     {    // report an invalid_argument error
544         _THROW(_STD invalid_argument, "invalid checked_iterator<T> argument");
545     }
546
547     _Cont *_Mycont; // the container of the iterator
548     _Iter _Current; // the wrapped iterator
549     };
550
551 _STDEXT_END
552
553 #ifdef _MSC_VER
554  #pragma warning(pop)
555  #pragma pack(pop)
556 #endif  /* _MSC_VER */
557
558 #endif /* RC_INVOKED */
559 #endif /* _ITERATOR_ */
560
561 /*
562  * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
563  * Consult your license regarding permissions and restrictions.
564  */
565
566 /*
567  * This file is derived from software bearing the following
568  * restrictions:
569  *
570  * Copyright (c) 1994
571  * Hewlett-Packard Company
572  *
573  * Permission to use, copy, modify, distribute and sell this
574  * software and its documentation for any purpose is hereby
575  * granted without fee, provided that the above copyright notice
576  * appear in all copies and that both that copyright notice and
577  * this permission notice appear in supporting documentation.
578  * Hewlett-Packard Company makes no representations about the
579  * suitability of this software for any purpose. It is provided
580  * "as is" without express or implied warranty.
581  V5.03:0009 */
582