OSDN Git Service

* algo.h, algobase.h, alloc.h, bvector.h, deque.h, hashtable.h,
[pf3gnuchains/gcc-fork.git] / libstdc++ / 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
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 #ifndef __SGI_STL_ITERATOR_H
28 #define __SGI_STL_ITERATOR_H
29
30 #include <stddef.h>
31 #include <iostream.h>
32 #include <function.h>
33
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 {};
39
40 template <class T, class Distance> struct input_iterator {
41   typedef input_iterator_tag iterator_category;
42   typedef T                  value_type;
43   typedef Distance           difference_type;
44   typedef T*                 pointer;
45   typedef T&                 reference;
46 };
47
48 struct output_iterator {
49   typedef output_iterator_tag iterator_category;
50   typedef void                value_type;
51   typedef void                difference_type;
52   typedef void                pointer;
53   typedef void                reference;
54 };
55
56 template <class T, class Distance> struct forward_iterator {
57   typedef forward_iterator_tag iterator_category;
58   typedef T                    value_type;
59   typedef Distance             difference_type;
60   typedef T*                   pointer;
61   typedef T&                   reference;
62 };
63
64
65 template <class T, class Distance> struct bidirectional_iterator {
66   typedef bidirectional_iterator_tag iterator_category;
67   typedef T                          value_type;
68   typedef Distance                   difference_type;
69   typedef T*                         pointer;
70   typedef T&                         reference;
71 };
72
73 template <class T, class Distance> struct random_access_iterator {
74   typedef random_access_iterator_tag iterator_category;
75   typedef T                          value_type;
76   typedef Distance                   difference_type;
77   typedef T*                         pointer;
78   typedef T&                         reference;
79 };
80
81 #if 0
82 template <class Category, class T, class Distance = ptrdiff_t,
83           class Pointer = T*, class Reference = T&>
84 struct iterator {
85   typedef Category  iterator_category;
86   typedef T         value_type;
87   typedef Distance  difference_type;
88   typedef Pointer   pointer;
89   typedef Reference reference;
90 };
91 #endif
92
93 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
94
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;
102 };
103
104 template <class T>
105 struct iterator_traits<T*> {
106   typedef random_access_iterator_tag iterator_category;
107   typedef T                          value_type;
108   typedef ptrdiff_t                  difference_type;
109   typedef T*                         pointer;
110   typedef T&                         reference;
111 };
112
113 template <class T>
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;
120 };
121
122 template <class Iterator>
123 inline iterator_traits<Iterator>::iterator_category
124 iterator_category(const Iterator&) {
125   return iterator_traits<Iterator>::iterator_category();
126 }
127
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);
132 }
133
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);
138 }
139
140 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
141
142 template <class T, class Distance> 
143 inline input_iterator_tag 
144 iterator_category(const input_iterator<T, Distance>&) {
145     return input_iterator_tag();
146 }
147
148 inline output_iterator_tag iterator_category(const output_iterator&) {
149     return output_iterator_tag();
150 }
151
152 template <class T, class Distance> 
153 inline forward_iterator_tag
154 iterator_category(const forward_iterator<T, Distance>&) {
155     return forward_iterator_tag();
156 }
157
158 template <class T, class Distance> 
159 inline bidirectional_iterator_tag
160 iterator_category(const bidirectional_iterator<T, Distance>&) {
161     return bidirectional_iterator_tag();
162 }
163
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();
168 }
169
170 template <class T>
171 inline random_access_iterator_tag iterator_category(const T*) {
172     return random_access_iterator_tag();
173 }
174
175 template <class T, class Distance> 
176 inline T* value_type(const input_iterator<T, Distance>&) {
177     return (T*)(0); 
178 }
179
180 template <class T, class Distance> 
181 inline T* value_type(const forward_iterator<T, Distance>&) {
182     return (T*)(0);
183 }
184
185 template <class T, class Distance> 
186 inline T* value_type(const bidirectional_iterator<T, Distance>&) {
187     return (T*)(0);
188 }
189
190 template <class T, class Distance> 
191 inline T* value_type(const random_access_iterator<T, Distance>&) {
192     return (T*)(0);
193 }
194
195 template <class T>
196 inline T* value_type(const T*) { return (T*)(0); }
197
198 template <class T, class Distance> 
199 inline Distance* distance_type(const input_iterator<T, Distance>&) {
200     return (Distance*)(0);
201 }
202
203 template <class T, class Distance> 
204 inline Distance* distance_type(const forward_iterator<T, Distance>&) {
205     return (Distance*)(0);
206 }
207
208 template <class T, class Distance> 
209 inline Distance* 
210 distance_type(const bidirectional_iterator<T, Distance>&) {
211     return (Distance*)(0);
212 }
213
214 template <class T, class Distance> 
215 inline Distance* 
216 distance_type(const random_access_iterator<T, Distance>&) {
217     return (Distance*)(0);
218 }
219
220 template <class T>
221 inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
222
223 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
224
225 template <class Container>
226 class back_insert_iterator {
227 protected:
228     Container* container;
229 public:
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;
235
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);
240         return *this;
241     }
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; }
245 };
246
247 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
248
249 template <class Container>
250 inline output_iterator_tag
251 iterator_category(const back_insert_iterator<Container>&)
252 {
253   return output_iterator_tag();
254 }
255
256 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
257
258 template <class Container>
259 inline back_insert_iterator<Container> back_inserter(Container& x) {
260   return back_insert_iterator<Container>(x);
261 }
262
263 template <class Container>
264 class front_insert_iterator {
265 protected:
266     Container* container;
267 public:
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;
273
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);
278         return *this;
279     }
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; }
283 };
284
285 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
286
287 template <class Container>
288 inline output_iterator_tag
289 iterator_category(const front_insert_iterator<Container>&)
290 {
291   return output_iterator_tag();
292 }
293
294 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
295
296 template <class Container>
297 inline front_insert_iterator<Container> front_inserter(Container& x) {
298   return front_insert_iterator<Container>(x);
299 }
300
301 template <class Container>
302 class insert_iterator {
303 protected:
304     Container* container;
305     typename Container::iterator iter;
306 public:
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;
312
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);
318         ++iter;
319         return *this;
320     }
321     insert_iterator<Container>& operator*() { return *this; }
322     insert_iterator<Container>& operator++() { return *this; }
323     insert_iterator<Container>& operator++(int) { return *this; }
324 };
325
326 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
327
328 template <class Container>
329 inline output_iterator_tag
330 iterator_category(const insert_iterator<Container>&)
331 {
332   return output_iterator_tag();
333 }
334
335 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
336
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));
341 }
342
343 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
344 template <class BidirectionalIterator, class T, class Reference = T&, 
345           class Distance = ptrdiff_t> 
346 #else
347 template <class BidirectionalIterator, class T, class Reference, 
348           class Distance> 
349 #endif
350 class reverse_bidirectional_iterator {
351     typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
352                                            Distance> self;
353     friend bool operator==(const self& x, const self& y);
354 protected:
355     BidirectionalIterator current;
356 public:
357     typedef bidirectional_iterator_tag iterator_category;
358     typedef T                          value_type;
359     typedef Distance                   difference_type;
360     typedef T*                         pointer;
361     typedef Reference                  reference;
362
363     reverse_bidirectional_iterator() {}
364     explicit reverse_bidirectional_iterator(BidirectionalIterator x)
365       : current(x) {}
366     BidirectionalIterator base() { return current; }
367     Reference operator*() const {
368         BidirectionalIterator tmp = current;
369         return *--tmp;
370     }
371 #ifndef __SGI_STL_NO_ARROW_OPERATOR
372     pointer operator->() const { return &(operator*()); }
373 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
374     self& operator++() {
375         --current;
376         return *this;
377     }
378     self operator++(int) {
379         self tmp = *this;
380         --current;
381         return tmp;
382     }
383     self& operator--() {
384         ++current;
385         return *this;
386     }
387     self operator--(int) {
388         self tmp = *this;
389         ++current;
390         return tmp;
391     }
392 };
393
394 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
395
396 template <class BidirectionalIterator, class T, class Reference, 
397           class Distance>
398 inline bidirectional_iterator_tag
399 iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator,
400                                                        T,
401                                                        Reference, Distance>&) {
402   return bidirectional_iterator_tag();
403 }
404
405 template <class BidirectionalIterator, class T, class Reference, 
406           class Distance>
407 inline T*
408 value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
409                                                Reference, Distance>&) {
410   return (T*) 0;
411 }
412
413 template <class BidirectionalIterator, class T, class Reference, 
414           class Distance>
415 inline Distance*
416 distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
417                                                   Reference, Distance>&) {
418   return (Distance*) 0;
419 }
420
421 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
422
423 template <class BidirectionalIterator, class T, class Reference,
424           class Distance>
425 inline bool operator==(
426     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
427                                          Distance>& x, 
428     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
429                                          Distance>& y) {
430     return x.current == y.current;
431 }
432
433 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
434
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.
440
441 template <class Iterator>
442 class reverse_iterator : public iterator_traits<Iterator>
443 {
444 protected:
445   Iterator current;
446 public:
447   typedef Iterator iterator_type;
448   typedef reverse_iterator<Iterator> self;
449
450 public:
451   reverse_iterator() {}
452   explicit reverse_iterator(iterator_type x) : current(x) {}
453
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 */
459     
460   iterator_type base() const { return current; }
461   reference operator*() const {
462     Iterator tmp = current;
463     return *--tmp;
464   }
465 #ifndef __SGI_STL_NO_ARROW_OPERATOR
466   pointer operator->() const { return &(operator*()); }
467 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
468
469   self& operator++() {
470     --current;
471     return *this;
472   }
473   self operator++(int) {
474     self tmp = *this;
475     --current;
476     return tmp;
477   }
478   self& operator--() {
479     ++current;
480     return *this;
481   }
482   self operator--(int) {
483     self tmp = *this;
484     ++current;
485     return tmp;
486   }
487
488   self operator+(difference_type n) const {
489     return self(current - n);
490   }
491   self& operator+=(difference_type n) {
492     current -= n;
493     return *this;
494   }
495   self operator-(difference_type n) const {
496     return self(current + n);
497   }
498   self& operator-=(difference_type n) {
499     current += n;
500     return *this;
501   }
502   reference operator[](difference_type n) { return *(*this + n); }  
503 }; 
504  
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();
509 }
510
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();
515 }
516
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();
522 }
523
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);
529 }
530
531 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
532
533 // This is the old version of reverse_iterator, as found in the original
534 //  HP STL.  It does not use partial specialization.
535
536 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
537 template <class RandomAccessIterator, class T, class Reference = T&,
538           class Distance = ptrdiff_t> 
539 #else
540 template <class RandomAccessIterator, class T, class Reference,
541           class Distance> 
542 #endif
543 class reverse_iterator {
544     typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
545         self;
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);
550 protected:
551     RandomAccessIterator current;
552 public:
553     typedef random_access_iterator_tag iterator_category;
554     typedef T                          value_type;
555     typedef Distance                   difference_type;
556     typedef T*                         pointer;
557     typedef Reference                  reference;
558
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 */
566     self& operator++() {
567         --current;
568         return *this;
569     }
570     self operator++(int) {
571         self tmp = *this;
572         --current;
573         return tmp;
574     }
575     self& operator--() {
576         ++current;
577         return *this;
578     }
579     self operator--(int) {
580         self tmp = *this;
581         ++current;
582         return tmp;
583     }
584     self operator+(Distance n) const {
585         return self(current - n);
586     }
587     self& operator+=(Distance n) {
588         current -= n;
589         return *this;
590     }
591     self operator-(Distance n) const {
592         return self(current + n);
593     }
594     self& operator-=(Distance n) {
595         current += n;
596         return *this;
597     }
598     Reference operator[](Distance n) { return *(*this + n); }
599 };
600
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();
606 }
607
608 template <class RandomAccessIterator, class T, class Reference, class Distance>
609 inline T* value_type(const reverse_iterator<RandomAccessIterator, T,
610                                             Reference, Distance>&) {
611   return (T*) 0;
612 }
613
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;
618 }
619
620
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;
627 }
628
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;
635 }
636
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;
643 }
644
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,
649                                  Distance>& x) {
650     return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
651         (x.current - n);
652 }
653
654 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
655
656 template <class ForwardIterator, class T>
657 class raw_storage_iterator {
658 protected:
659     ForwardIterator iter;
660 public:
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;
666
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);
671         return *this;
672     }        
673     raw_storage_iterator<ForwardIterator, T>& operator++() {
674         ++iter;
675         return *this;
676     }
677     raw_storage_iterator<ForwardIterator, T> operator++(int) {
678         raw_storage_iterator<ForwardIterator, T> tmp = *this;
679         ++iter;
680         return tmp;
681     }
682 };
683
684 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
685
686 template <class ForwardIterator, class T>
687 inline output_iterator_tag
688 iterator_category(const raw_storage_iterator<ForwardIterator, T>&)
689 {
690   return output_iterator_tag();
691 }
692
693 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
694
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);
699 protected:
700     istream* stream;
701     T value;
702     bool end_marker;
703     void read() {
704         end_marker = (*stream) ? true : false;
705         if (end_marker) *stream >> value;
706         end_marker = (*stream) ? true : false;
707     }
708 public:
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;
714
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++() { 
722         read(); 
723         return *this;
724     }
725     istream_iterator<T, Distance> operator++(int)  {
726         istream_iterator<T, Distance> tmp = *this;
727         read();
728         return tmp;
729     }
730 };
731
732 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
733
734 template <class T, class Distance>
735 inline input_iterator_tag 
736 iterator_category(const istream_iterator<T, Distance>&) {
737   return input_iterator_tag();
738 }
739
740 template <class T, class Distance>
741 inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; }
742
743 template <class T, class Distance>
744 inline Distance* distance_type(const istream_iterator<T, Distance>&) {
745   return (Distance*) 0;
746 }
747
748 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
749
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;
755 }
756
757 template <class T>
758 class ostream_iterator {
759 protected:
760     ostream* stream;
761     const char* string;
762 public:
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;
768
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) { 
772         *stream << value;
773         if (string) *stream << string;
774         return *this;
775     }
776     ostream_iterator<T>& operator*() { return *this; }
777     ostream_iterator<T>& operator++() { return *this; } 
778     ostream_iterator<T>& operator++(int) { return *this; } 
779 };
780
781 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
782
783 template <class T>
784 inline output_iterator_tag 
785 iterator_category(const ostream_iterator<T>&) {
786   return output_iterator_tag();
787 }
788
789 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
790
791 #endif /* __SGI_STL_ITERATOR_H */