4 * Hewlett-Packard Company
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.
16 * Silicon Graphics Computer Systems, Inc.
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.
27 #ifndef __SGI_STL_ITERATOR_H
28 #define __SGI_STL_ITERATOR_H
34 struct input_iterator_tag {};
35 struct output_iterator_tag {};
36 struct forward_iterator_tag : public input_iterator_tag {};
37 struct bidirectional_iterator_tag : public forward_iterator_tag {};
38 struct random_access_iterator_tag : public bidirectional_iterator_tag {};
40 template <class T, class Distance> struct input_iterator {
41 typedef input_iterator_tag iterator_category;
43 typedef Distance difference_type;
48 struct output_iterator {
49 typedef output_iterator_tag iterator_category;
50 typedef void value_type;
51 typedef void difference_type;
53 typedef void reference;
56 template <class T, class Distance> struct forward_iterator {
57 typedef forward_iterator_tag iterator_category;
59 typedef Distance difference_type;
65 template <class T, class Distance> struct bidirectional_iterator {
66 typedef bidirectional_iterator_tag iterator_category;
68 typedef Distance difference_type;
73 template <class T, class Distance> struct random_access_iterator {
74 typedef random_access_iterator_tag iterator_category;
76 typedef Distance difference_type;
82 template <class Category, class T, class Distance = ptrdiff_t,
83 class Pointer = T*, class Reference = T&>
85 typedef Category iterator_category;
87 typedef Distance difference_type;
88 typedef Pointer pointer;
89 typedef Reference reference;
93 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
95 template <class Iterator>
96 struct iterator_traits {
97 typedef typename Iterator::iterator_category iterator_category;
98 typedef typename Iterator::value_type value_type;
99 typedef typename Iterator::difference_type difference_type;
100 typedef typename Iterator::pointer pointer;
101 typedef typename Iterator::reference reference;
105 struct iterator_traits<T*> {
106 typedef random_access_iterator_tag iterator_category;
107 typedef T value_type;
108 typedef ptrdiff_t difference_type;
110 typedef T& reference;
114 struct iterator_traits<const T*> {
115 typedef random_access_iterator_tag iterator_category;
116 typedef T value_type;
117 typedef ptrdiff_t difference_type;
118 typedef const T* pointer;
119 typedef const T& reference;
122 template <class Iterator>
123 inline iterator_traits<Iterator>::iterator_category
124 iterator_category(const Iterator&) {
125 return iterator_traits<Iterator>::iterator_category();
128 template <class Iterator>
129 inline iterator_traits<Iterator>::difference_type*
130 distance_type(const Iterator&) {
131 return static_cast<iterator_traits<Iterator>::difference_type*>(0);
134 template <class Iterator>
135 inline iterator_traits<Iterator>::value_type*
136 value_type(const Iterator&) {
137 return static_cast<iterator_traits<Iterator>::value_type*>(0);
140 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
142 template <class T, class Distance>
143 inline input_iterator_tag
144 iterator_category(const input_iterator<T, Distance>&) {
145 return input_iterator_tag();
148 inline output_iterator_tag iterator_category(const output_iterator&) {
149 return output_iterator_tag();
152 template <class T, class Distance>
153 inline forward_iterator_tag
154 iterator_category(const forward_iterator<T, Distance>&) {
155 return forward_iterator_tag();
158 template <class T, class Distance>
159 inline bidirectional_iterator_tag
160 iterator_category(const bidirectional_iterator<T, Distance>&) {
161 return bidirectional_iterator_tag();
164 template <class T, class Distance>
165 inline random_access_iterator_tag
166 iterator_category(const random_access_iterator<T, Distance>&) {
167 return random_access_iterator_tag();
171 inline random_access_iterator_tag iterator_category(const T*) {
172 return random_access_iterator_tag();
175 template <class T, class Distance>
176 inline T* value_type(const input_iterator<T, Distance>&) {
180 template <class T, class Distance>
181 inline T* value_type(const forward_iterator<T, Distance>&) {
185 template <class T, class Distance>
186 inline T* value_type(const bidirectional_iterator<T, Distance>&) {
190 template <class T, class Distance>
191 inline T* value_type(const random_access_iterator<T, Distance>&) {
196 inline T* value_type(const T*) { return (T*)(0); }
198 template <class T, class Distance>
199 inline Distance* distance_type(const input_iterator<T, Distance>&) {
200 return (Distance*)(0);
203 template <class T, class Distance>
204 inline Distance* distance_type(const forward_iterator<T, Distance>&) {
205 return (Distance*)(0);
208 template <class T, class Distance>
210 distance_type(const bidirectional_iterator<T, Distance>&) {
211 return (Distance*)(0);
214 template <class T, class Distance>
216 distance_type(const random_access_iterator<T, Distance>&) {
217 return (Distance*)(0);
221 inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
223 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
225 template <class Container>
226 class back_insert_iterator {
228 Container* container;
230 typedef output_iterator_tag iterator_category;
231 typedef void value_type;
232 typedef void difference_type;
233 typedef void pointer;
234 typedef void reference;
236 explicit back_insert_iterator(Container& x) : container(&x) {}
237 back_insert_iterator<Container>&
238 operator=(const typename Container::value_type& value) {
239 container->push_back(value);
242 back_insert_iterator<Container>& operator*() { return *this; }
243 back_insert_iterator<Container>& operator++() { return *this; }
244 back_insert_iterator<Container>& operator++(int) { return *this; }
247 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
249 template <class Container>
250 inline output_iterator_tag
251 iterator_category(const back_insert_iterator<Container>&)
253 return output_iterator_tag();
256 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
258 template <class Container>
259 inline back_insert_iterator<Container> back_inserter(Container& x) {
260 return back_insert_iterator<Container>(x);
263 template <class Container>
264 class front_insert_iterator {
266 Container* container;
268 typedef output_iterator_tag iterator_category;
269 typedef void value_type;
270 typedef void difference_type;
271 typedef void pointer;
272 typedef void reference;
274 explicit front_insert_iterator(Container& x) : container(&x) {}
275 front_insert_iterator<Container>&
276 operator=(const typename Container::value_type& value) {
277 container->push_front(value);
280 front_insert_iterator<Container>& operator*() { return *this; }
281 front_insert_iterator<Container>& operator++() { return *this; }
282 front_insert_iterator<Container>& operator++(int) { return *this; }
285 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
287 template <class Container>
288 inline output_iterator_tag
289 iterator_category(const front_insert_iterator<Container>&)
291 return output_iterator_tag();
294 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
296 template <class Container>
297 inline front_insert_iterator<Container> front_inserter(Container& x) {
298 return front_insert_iterator<Container>(x);
301 template <class Container>
302 class insert_iterator {
304 Container* container;
305 typename Container::iterator iter;
307 typedef output_iterator_tag iterator_category;
308 typedef void value_type;
309 typedef void difference_type;
310 typedef void pointer;
311 typedef void reference;
313 insert_iterator(Container& x, typename Container::iterator i)
314 : container(&x), iter(i) {}
315 insert_iterator<Container>&
316 operator=(const typename Container::value_type& value) {
317 iter = container->insert(iter, value);
321 insert_iterator<Container>& operator*() { return *this; }
322 insert_iterator<Container>& operator++() { return *this; }
323 insert_iterator<Container>& operator++(int) { return *this; }
326 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
328 template <class Container>
329 inline output_iterator_tag
330 iterator_category(const insert_iterator<Container>&)
332 return output_iterator_tag();
335 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
337 template <class Container, class Iterator>
338 inline insert_iterator<Container> inserter(Container& x, Iterator i) {
339 typedef typename Container::iterator iter;
340 return insert_iterator<Container>(x, iter(i));
343 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
344 template <class BidirectionalIterator, class T, class Reference = T&,
345 class Distance = ptrdiff_t>
347 template <class BidirectionalIterator, class T, class Reference,
350 class reverse_bidirectional_iterator {
351 typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
353 friend bool operator==(const self& x, const self& y);
355 BidirectionalIterator current;
357 typedef bidirectional_iterator_tag iterator_category;
358 typedef T value_type;
359 typedef Distance difference_type;
361 typedef Reference reference;
363 reverse_bidirectional_iterator() {}
364 explicit reverse_bidirectional_iterator(BidirectionalIterator x)
366 BidirectionalIterator base() { return current; }
367 Reference operator*() const {
368 BidirectionalIterator tmp = current;
371 #ifndef __SGI_STL_NO_ARROW_OPERATOR
372 pointer operator->() const { return &(operator*()); }
373 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
378 self operator++(int) {
387 self operator--(int) {
394 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
396 template <class BidirectionalIterator, class T, class Reference,
398 inline bidirectional_iterator_tag
399 iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator,
401 Reference, Distance>&) {
402 return bidirectional_iterator_tag();
405 template <class BidirectionalIterator, class T, class Reference,
408 value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
409 Reference, Distance>&) {
413 template <class BidirectionalIterator, class T, class Reference,
416 distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
417 Reference, Distance>&) {
418 return (Distance*) 0;
421 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
423 template <class BidirectionalIterator, class T, class Reference,
425 inline bool operator==(
426 const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
428 const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
430 return x.current == y.current;
433 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
435 // This is the new version of reverse_iterator, as defined in the
436 // draft C++ standard. It relies on the iterator_traits template,
437 // which in turn relies on partial specialization. The class
438 // reverse_bidirectional_iterator is no longer part of the draft
439 // standard, but it is retained for backward compatibility.
441 template <class Iterator>
442 class reverse_iterator : public iterator_traits<Iterator>
447 typedef Iterator iterator_type;
448 typedef reverse_iterator<Iterator> self;
451 reverse_iterator() {}
452 explicit reverse_iterator(iterator_type x) : current(x) {}
454 reverse_iterator(const self& x) : current(x.current) {}
455 #ifdef __STL_MEMBER_TEMPLATES
456 template <class Iter>
457 reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {}
458 #endif /* __STL_MEMBER_TEMPLATES */
460 iterator_type base() const { return current; }
461 reference operator*() const {
462 Iterator tmp = current;
465 #ifndef __SGI_STL_NO_ARROW_OPERATOR
466 pointer operator->() const { return &(operator*()); }
467 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
473 self operator++(int) {
482 self operator--(int) {
488 self operator+(difference_type n) const {
489 return self(current - n);
491 self& operator+=(difference_type n) {
495 self operator-(difference_type n) const {
496 return self(current + n);
498 self& operator-=(difference_type n) {
502 reference operator[](difference_type n) { return *(*this + n); }
505 template <class Iterator>
506 inline bool operator==(const reverse_iterator<Iterator>& x,
507 const reverse_iterator<Iterator>& y) {
508 return x.base() == y.base();
511 template <class Iterator>
512 inline bool operator<(const reverse_iterator<Iterator>& x,
513 const reverse_iterator<Iterator>& y) {
514 return y.base() < x.base();
517 template <class Iterator>
518 inline reverse_iterator<Iterator>::difference_type
519 operator-(const reverse_iterator<Iterator>& x,
520 const reverse_iterator<Iterator>& y) {
521 return y.base() - x.base();
524 template <class Iterator>
525 inline reverse_iterator<Iterator>
526 operator+(reverse_iterator<Iterator>::difference_type n,
527 const reverse_iterator<Iterator>& x) {
528 return reverse_iterator<Iterator>(x.base() - n);
531 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
533 // This is the old version of reverse_iterator, as found in the original
534 // HP STL. It does not use partial specialization.
536 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
537 template <class RandomAccessIterator, class T, class Reference = T&,
538 class Distance = ptrdiff_t>
540 template <class RandomAccessIterator, class T, class Reference,
543 class reverse_iterator {
544 typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
546 friend bool operator==(const self& x, const self& y);
547 friend bool operator<(const self& x, const self& y);
548 friend Distance operator-(const self& x, const self& y);
549 friend self operator+(Distance n, const self& x);
551 RandomAccessIterator current;
553 typedef random_access_iterator_tag iterator_category;
554 typedef T value_type;
555 typedef Distance difference_type;
557 typedef Reference reference;
559 reverse_iterator() {}
560 explicit reverse_iterator(RandomAccessIterator x) : current(x) {}
561 RandomAccessIterator base() { return current; }
562 Reference operator*() const { return *(current - 1); }
563 #ifndef __SGI_STL_NO_ARROW_OPERATOR
564 pointer operator->() const { return &(operator*()); }
565 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
570 self operator++(int) {
579 self operator--(int) {
584 self operator+(Distance n) const {
585 return self(current - n);
587 self& operator+=(Distance n) {
591 self operator-(Distance n) const {
592 return self(current + n);
594 self& operator-=(Distance n) {
598 Reference operator[](Distance n) { return *(*this + n); }
601 template <class RandomAccessIterator, class T, class Reference, class Distance>
602 inline random_access_iterator_tag
603 iterator_category(const reverse_iterator<RandomAccessIterator, T,
604 Reference, Distance>&) {
605 return random_access_iterator_tag();
608 template <class RandomAccessIterator, class T, class Reference, class Distance>
609 inline T* value_type(const reverse_iterator<RandomAccessIterator, T,
610 Reference, Distance>&) {
614 template <class RandomAccessIterator, class T, class Reference, class Distance>
615 inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T,
616 Reference, Distance>&) {
617 return (Distance*) 0;
621 template <class RandomAccessIterator, class T, class Reference, class Distance>
622 inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
623 Reference, Distance>& x,
624 const reverse_iterator<RandomAccessIterator, T,
625 Reference, Distance>& y) {
626 return x.current == y.current;
629 template <class RandomAccessIterator, class T, class Reference, class Distance>
630 inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
631 Reference, Distance>& x,
632 const reverse_iterator<RandomAccessIterator, T,
633 Reference, Distance>& y) {
634 return y.current < x.current;
637 template <class RandomAccessIterator, class T, class Reference, class Distance>
638 inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
639 Reference, Distance>& x,
640 const reverse_iterator<RandomAccessIterator, T,
641 Reference, Distance>& y) {
642 return y.current - x.current;
645 template <class RandomAccessIterator, class T, class Reference, class Distance>
646 inline reverse_iterator<RandomAccessIterator, T, Reference, Distance>
647 operator+(Distance n,
648 const reverse_iterator<RandomAccessIterator, T, Reference,
650 return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
654 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
656 template <class ForwardIterator, class T>
657 class raw_storage_iterator {
659 ForwardIterator iter;
661 typedef output_iterator_tag iterator_category;
662 typedef void value_type;
663 typedef void difference_type;
664 typedef void pointer;
665 typedef void reference;
667 explicit raw_storage_iterator(ForwardIterator x) : iter(x) {}
668 raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; }
669 raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) {
670 construct(&*iter, element);
673 raw_storage_iterator<ForwardIterator, T>& operator++() {
677 raw_storage_iterator<ForwardIterator, T> operator++(int) {
678 raw_storage_iterator<ForwardIterator, T> tmp = *this;
684 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
686 template <class ForwardIterator, class T>
687 inline output_iterator_tag
688 iterator_category(const raw_storage_iterator<ForwardIterator, T>&)
690 return output_iterator_tag();
693 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
695 template <class T, class Distance = ptrdiff_t>
696 class istream_iterator {
697 friend bool operator==(const istream_iterator<T, Distance>& x,
698 const istream_iterator<T, Distance>& y);
704 end_marker = (*stream) ? true : false;
705 if (end_marker) *stream >> value;
706 end_marker = (*stream) ? true : false;
709 typedef input_iterator_tag iterator_category;
710 typedef T value_type;
711 typedef Distance difference_type;
712 typedef const T* pointer;
713 typedef const T& reference;
715 istream_iterator() : stream(&cin), end_marker(false) {}
716 istream_iterator(istream& s) : stream(&s) { read(); }
717 reference operator*() const { return value; }
718 #ifndef __SGI_STL_NO_ARROW_OPERATOR
719 pointer operator->() const { return &(operator*()); }
720 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
721 istream_iterator<T, Distance>& operator++() {
725 istream_iterator<T, Distance> operator++(int) {
726 istream_iterator<T, Distance> tmp = *this;
732 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
734 template <class T, class Distance>
735 inline input_iterator_tag
736 iterator_category(const istream_iterator<T, Distance>&) {
737 return input_iterator_tag();
740 template <class T, class Distance>
741 inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; }
743 template <class T, class Distance>
744 inline Distance* distance_type(const istream_iterator<T, Distance>&) {
745 return (Distance*) 0;
748 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
750 template <class T, class Distance>
751 bool operator==(const istream_iterator<T, Distance>& x,
752 const istream_iterator<T, Distance>& y) {
753 return x.stream == y.stream && x.end_marker == y.end_marker ||
754 x.end_marker == false && y.end_marker == false;
758 class ostream_iterator {
763 typedef output_iterator_tag iterator_category;
764 typedef void value_type;
765 typedef void difference_type;
766 typedef void pointer;
767 typedef void reference;
769 ostream_iterator(ostream& s) : stream(&s), string(0) {}
770 ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {}
771 ostream_iterator<T>& operator=(const T& value) {
773 if (string) *stream << string;
776 ostream_iterator<T>& operator*() { return *this; }
777 ostream_iterator<T>& operator++() { return *this; }
778 ostream_iterator<T>& operator++(int) { return *this; }
781 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
784 inline output_iterator_tag
785 iterator_category(const ostream_iterator<T>&) {
786 return output_iterator_tag();
789 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
791 #endif /* __SGI_STL_ITERATOR_H */