home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Compilers / digital marsC compier / dm / stl / stl_iterator.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-08  |  29.3 KB  |  965 lines

  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. __STL_BEGIN_NAMESPACE
  35.  
  36.  
  37. template <class _Container>
  38. class back_insert_iterator {
  39. protected:
  40.   _Container* container;
  41. public:
  42.   typedef _Container          container_type;
  43.   typedef output_iterator_tag iterator_category;
  44.   typedef void                value_type;
  45.   typedef void                difference_type;
  46.   typedef void                pointer;
  47.   typedef void                reference;
  48.  
  49.   explicit back_insert_iterator(_Container& __x) : container(&__x) {}
  50.   back_insert_iterator<_Container>&
  51.   operator=(const typename _Container::value_type& __value) { 
  52.     container->push_back(__value);
  53.     return *this;
  54.   }
  55.   back_insert_iterator<_Container>& operator*() { return *this; }
  56.   back_insert_iterator<_Container>& operator++() { return *this; }
  57.   back_insert_iterator<_Container>& operator++(int) { return *this; }
  58. };
  59.  
  60. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  61.  
  62. template <class _Container>
  63. inline output_iterator_tag
  64. iterator_category(const back_insert_iterator<_Container>&)
  65. {
  66.   return output_iterator_tag();
  67. }
  68.  
  69. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  70.  
  71. template <class _Container>
  72. inline back_insert_iterator<_Container> back_inserter(_Container& __x) {
  73.   return back_insert_iterator<_Container>(__x);
  74. }
  75.  
  76. template <class _Container>
  77. class front_insert_iterator {
  78. protected:
  79.   _Container* container;
  80. public:
  81.   typedef _Container          container_type;
  82.   typedef output_iterator_tag iterator_category;
  83.   typedef void                value_type;
  84.   typedef void                difference_type;
  85.   typedef void                pointer;
  86.   typedef void                reference;
  87.  
  88.   explicit front_insert_iterator(_Container& __x) : container(&__x) {}
  89.   front_insert_iterator<_Container>&
  90.   operator=(const typename _Container::value_type& __value) { 
  91.     container->push_front(__value);
  92.     return *this;
  93.   }
  94.   front_insert_iterator<_Container>& operator*() { return *this; }
  95.   front_insert_iterator<_Container>& operator++() { return *this; }
  96.   front_insert_iterator<_Container>& operator++(int) { return *this; }
  97. };
  98.  
  99. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  100.  
  101. template <class _Container>
  102. inline output_iterator_tag
  103. iterator_category(const front_insert_iterator<_Container>&)
  104. {
  105.   return output_iterator_tag();
  106. }
  107.  
  108. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  109.  
  110. template <class _Container>
  111. inline front_insert_iterator<_Container> front_inserter(_Container& __x) {
  112.   return front_insert_iterator<_Container>(__x);
  113. }
  114.  
  115. template <class _Container>
  116. class insert_iterator {
  117. protected:
  118.   _Container* container;
  119.   typename _Container::iterator iter;
  120. public:
  121.   typedef _Container          container_type;
  122.   typedef output_iterator_tag iterator_category;
  123.   typedef void                value_type;
  124.   typedef void                difference_type;
  125.   typedef void                pointer;
  126.   typedef void                reference;
  127.  
  128.   insert_iterator(_Container& __x, typename _Container::iterator __i) 
  129.     : container(&__x), iter(__i) {}
  130.   insert_iterator<_Container>&
  131.   operator=(const typename _Container::value_type& __value) { 
  132.     iter = container->insert(iter, __value);
  133.     ++iter;
  134.     return *this;
  135.   }
  136.   insert_iterator<_Container>& operator*() { return *this; }
  137.   insert_iterator<_Container>& operator++() { return *this; }
  138.   insert_iterator<_Container>& operator++(int) { return *this; }
  139. };
  140.  
  141. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  142.  
  143. template <class _Container>
  144. inline output_iterator_tag
  145. iterator_category(const insert_iterator<_Container>&)
  146. {
  147.   return output_iterator_tag();
  148. }
  149.  
  150. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  151.  
  152. template <class _Container, class _Iterator>
  153. inline 
  154. insert_iterator<_Container> inserter(_Container& __x, _Iterator __i)
  155. {
  156.   typedef typename _Container::iterator __iter;
  157.   return insert_iterator<_Container>(__x, __iter(__i));
  158. }
  159.  
  160. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  161. template <class _BidirectionalIterator, class _Tp, class _Reference = _Tp&, 
  162.           class _Distance = ptrdiff_t> 
  163. #else
  164. template <class _BidirectionalIterator, class _Tp, class _Reference, 
  165.           class _Distance> 
  166. #endif
  167. class reverse_bidirectional_iterator {
  168.   typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, 
  169.                                          _Reference, _Distance>  _Self;
  170. protected:
  171.   _BidirectionalIterator current;
  172. public:
  173.   typedef bidirectional_iterator_tag iterator_category;
  174.   typedef _Tp                        value_type;
  175.   typedef _Distance                  difference_type;
  176.   typedef _Tp*                       pointer;
  177.   typedef _Reference                 reference;
  178.  
  179.   reverse_bidirectional_iterator() {}
  180.   explicit reverse_bidirectional_iterator(_BidirectionalIterator __x)
  181.     : current(__x) {}
  182.   _BidirectionalIterator base() const { return current; }
  183.   _Reference operator*() const {
  184.     _BidirectionalIterator __tmp = current;
  185.     return *--__tmp;
  186.   }
  187. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  188.   pointer operator->() const { return &(operator*()); }
  189. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  190.   _Self& operator++() {
  191.     --current;
  192.     return *this;
  193.   }
  194.   _Self operator++(int) {
  195.     _Self __tmp = *this;
  196.     --current;
  197.     return __tmp;
  198.   }
  199.   _Self& operator--() {
  200.     ++current;
  201.     return *this;
  202.   }
  203.   _Self operator--(int) {
  204.     _Self __tmp = *this;
  205.     ++current;
  206.     return __tmp;
  207.   }
  208. };
  209.  
  210. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  211.  
  212. template <class _BidirectionalIterator, class _Tp, class _Reference, 
  213.           class _Distance>
  214. inline bidirectional_iterator_tag
  215. iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator,
  216.                                                        _Tp, _Reference, 
  217.                                                        _Distance>&) 
  218. {
  219.   return bidirectional_iterator_tag();
  220. }
  221.  
  222. template <class _BidirectionalIterator, class _Tp, class _Reference, 
  223.           class _Distance>
  224. inline _Tp*
  225. value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp,
  226.                                                _Reference, _Distance>&)
  227. {
  228.   return (_Tp*) 0;
  229. }
  230.  
  231. template <class _BidirectionalIterator, class _Tp, class _Reference, 
  232.           class _Distance>
  233. inline _Distance*
  234. distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, 
  235.                                                    _Tp,
  236.                                                    _Reference, _Distance>&)
  237. {
  238.   return (_Distance*) 0;
  239. }
  240.  
  241. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  242.  
  243. template <class _BiIter, class _Tp, class _Ref, class _Distance>
  244. inline bool operator==(
  245.     const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, 
  246.     const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y)
  247. {
  248.   return __x.base() == __y.base();
  249. }
  250.  
  251. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  252.  
  253. template <class _BiIter, class _Tp, class _Ref, class _Distance>
  254. inline bool operator!=(
  255.     const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, 
  256.     const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y)
  257. {
  258.   return !(__x == __y);
  259. }
  260.  
  261. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  262.  
  263.  
  264. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  265.  
  266. // This is the new version of reverse_iterator, as defined in the
  267. //  draft C++ standard.  It relies on the iterator_traits template,
  268. //  which in turn relies on partial specialization.  The class
  269. //  reverse_bidirectional_iterator is no longer part of the draft
  270. //  standard, but it is retained for backward compatibility.
  271.  
  272. template <class _Iterator>
  273. class reverse_iterator 
  274. {
  275. protected:
  276.   _Iterator current;
  277. public:
  278.   typedef typename iterator_traits<_Iterator>::iterator_category
  279.           iterator_category;
  280.   typedef typename iterator_traits<_Iterator>::value_type
  281.           value_type;
  282.   typedef typename iterator_traits<_Iterator>::difference_type
  283.           difference_type;
  284.   typedef typename iterator_traits<_Iterator>::pointer
  285.           pointer;
  286.   typedef typename iterator_traits<_Iterator>::reference
  287.           reference;
  288.  
  289.   typedef _Iterator iterator_type;
  290.   typedef reverse_iterator<_Iterator> _Self;
  291.  
  292. public:
  293.   reverse_iterator() {}
  294.   explicit reverse_iterator(iterator_type __x) : current(__x) {}
  295.  
  296.   reverse_iterator(const _Self& __x) : current(__x.current) {}
  297. #ifdef __STL_MEMBER_TEMPLATES
  298.   template <class _Iter>
  299.   reverse_iterator(const reverse_iterator<_Iter>& __x)
  300.     : current(__x.base()) {}
  301. #endif /* __STL_MEMBER_TEMPLATES */
  302.     
  303.   iterator_type base() const { return current; }
  304.   reference operator*() const {
  305.     _Iterator __tmp = current;
  306.     return *--__tmp;
  307.   }
  308. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  309.   pointer operator->() const { return &(operator*()); }
  310. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  311.  
  312.   _Self& operator++() {
  313.     --current;
  314.     return *this;
  315.   }
  316.   _Self operator++(int) {
  317.     _Self __tmp = *this;
  318.     --current;
  319.     return __tmp;
  320.   }
  321.   _Self& operator--() {
  322.     ++current;
  323.     return *this;
  324.   }
  325.   _Self operator--(int) {
  326.     _Self __tmp = *this;
  327.     ++current;
  328.     return __tmp;
  329.   }
  330.  
  331.   _Self operator+(difference_type __n) const {
  332.     return _Self(current - __n);
  333.   }
  334.   _Self& operator+=(difference_type __n) {
  335.     current -= __n;
  336.     return *this;
  337.   }
  338.   _Self operator-(difference_type __n) const {
  339.     return _Self(current + __n);
  340.   }
  341.   _Self& operator-=(difference_type __n) {
  342.     current += __n;
  343.     return *this;
  344.   }
  345.   reference operator[](difference_type __n) const { return *(*this + __n); }  
  346. }; 
  347.  
  348. template <class _Iterator>
  349. inline bool operator==(const reverse_iterator<_Iterator>& __x, 
  350.                        const reverse_iterator<_Iterator>& __y) {
  351.   return __x.base() == __y.base();
  352. }
  353.  
  354. template <class _Iterator>
  355. inline bool operator<(const reverse_iterator<_Iterator>& __x, 
  356.                       const reverse_iterator<_Iterator>& __y) {
  357.   return __y.base() < __x.base();
  358. }
  359.  
  360. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  361.  
  362. template <class _Iterator>
  363. inline bool operator!=(const reverse_iterator<_Iterator>& __x, 
  364.                        const reverse_iterator<_Iterator>& __y) {
  365.   return !(__x == __y);
  366. }
  367.  
  368. template <class _Iterator>
  369. inline bool operator>(const reverse_iterator<_Iterator>& __x, 
  370.                       const reverse_iterator<_Iterator>& __y) {
  371.   return __y < __x;
  372. }
  373.  
  374. template <class _Iterator>
  375. inline bool operator<=(const reverse_iterator<_Iterator>& __x, 
  376.                        const reverse_iterator<_Iterator>& __y) {
  377.   return !(__y < __x);
  378. }
  379.  
  380. template <class _Iterator>
  381. inline bool operator>=(const reverse_iterator<_Iterator>& __x, 
  382.                       const reverse_iterator<_Iterator>& __y) {
  383.   return !(__x < __y);
  384. }
  385.  
  386. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  387.  
  388. template <class _Iterator>
  389. inline typename reverse_iterator<_Iterator>::difference_type
  390. operator-(const reverse_iterator<_Iterator>& __x, 
  391.           const reverse_iterator<_Iterator>& __y) {
  392.   return __y.base() - __x.base();
  393. }
  394.  
  395. template <class _Iterator>
  396. inline reverse_iterator<_Iterator> 
  397. operator+(typename reverse_iterator<_Iterator>::difference_type __n,
  398.           const reverse_iterator<_Iterator>& __x) {
  399.   return reverse_iterator<_Iterator>(__x.base() - __n);
  400. }
  401.  
  402. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  403.  
  404. // This is the old version of reverse_iterator, as found in the original
  405. //  HP STL.  It does not use partial specialization.
  406.  
  407. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  408. template <class _RandomAccessIterator, class _Tp, class _Reference = _Tp&,
  409.           class _Distance = ptrdiff_t> 
  410. #else
  411. template <class _RandomAccessIterator, class _Tp, class _Reference,
  412.           class _Distance> 
  413. #endif
  414. class reverse_iterator {
  415.   typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance>
  416.         _Self;
  417. protected:
  418.   _RandomAccessIterator current;
  419. public:
  420.   typedef random_access_iterator_tag iterator_category;
  421.   typedef _Tp                        value_type;
  422.   typedef _Distance                  difference_type;
  423.   typedef _Tp*                       pointer;
  424.   typedef _Reference                 reference;
  425.  
  426.   reverse_iterator() {}
  427.   explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {}
  428.   _RandomAccessIterator base() const { return current; }
  429.   _Reference operator*() const { return *(current - 1); }
  430. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  431.   pointer operator->() const { return &(operator*()); }
  432. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  433.   _Self& operator++() {
  434.     --current;
  435.     return *this;
  436.   }
  437.   _Self operator++(int) {
  438.     _Self __tmp = *this;
  439.     --current;
  440.     return __tmp;
  441.   }
  442.   _Self& operator--() {
  443.     ++current;
  444.     return *this;
  445.   }
  446.   _Self operator--(int) {
  447.     _Self __tmp = *this;
  448.     ++current;
  449.     return __tmp;
  450.   }
  451.   _Self operator+(_Distance __n) const {
  452.     return _Self(current - __n);
  453.   }
  454.   _Self& operator+=(_Distance __n) {
  455.     current -= __n;
  456.     return *this;
  457.   }
  458.   _Self operator-(_Distance __n) const {
  459.     return _Self(current + __n);
  460.   }
  461.   _Self& operator-=(_Distance __n) {
  462.     current += __n;
  463.     return *this;
  464.   }
  465.   _Reference operator[](_Distance __n) const { return *(*this + __n); }
  466. };
  467.  
  468. template <class _RandomAccessIterator, class _Tp, 
  469.           class _Reference, class _Distance>
  470. inline random_access_iterator_tag
  471. iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp,
  472.                                          _Reference, _Distance>&)
  473. {
  474.   return random_access_iterator_tag();
  475. }
  476.  
  477. template <class _RandomAccessIterator, class _Tp,
  478.           class _Reference, class _Distance>
  479. inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp,
  480.                                               _Reference, _Distance>&)
  481. {
  482.   return (_Tp*) 0;
  483. }
  484.  
  485. template <class _RandomAccessIterator, class _Tp,
  486.           class _Reference, class _Distance>
  487. inline _Distance* 
  488. distance_type(const reverse_iterator<_RandomAccessIterator, 
  489.                                      _Tp, _Reference, _Distance>&)
  490. {
  491.   return (_Distance*) 0;
  492. }
  493.  
  494.  
  495. template <class _RandomAccessIterator, class _Tp,
  496.           class _Reference, class _Distance>
  497. inline bool 
  498. operator==(const reverse_iterator<_RandomAccessIterator, _Tp,
  499.                                   _Reference, _Distance>& __x, 
  500.            const reverse_iterator<_RandomAccessIterator, _Tp,
  501.                                   _Reference, _Distance>& __y)
  502. {
  503.   return __x.base() == __y.base();
  504. }
  505.  
  506. template <class _RandomAccessIterator, class _Tp,
  507.           class _Reference, class _Distance>
  508. inline bool 
  509. operator<(const reverse_iterator<_RandomAccessIterator, _Tp,
  510.                                  _Reference, _Distance>& __x, 
  511.           const reverse_iterator<_RandomAccessIterator, _Tp,
  512.                                  _Reference, _Distance>& __y)
  513. {
  514.   return __y.base() < __x.base();
  515. }
  516.  
  517. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  518.  
  519. template <class _RandomAccessIterator, class _Tp,
  520.           class _Reference, class _Distance>
  521. inline bool 
  522. operator!=(const reverse_iterator<_RandomAccessIterator, _Tp,
  523.                                   _Reference, _Distance>& __x, 
  524.            const reverse_iterator<_RandomAccessIterator, _Tp,
  525.                                   _Reference, _Distance>& __y) {
  526.   return !(__x == __y);
  527. }
  528.  
  529. template <class _RandomAccessIterator, class _Tp,
  530.           class _Reference, class _Distance>
  531. inline bool 
  532. operator>(const reverse_iterator<_RandomAccessIterator, _Tp,
  533.                                  _Reference, _Distance>& __x, 
  534.           const reverse_iterator<_RandomAccessIterator, _Tp,
  535.                                  _Reference, _Distance>& __y) {
  536.   return __y < __x;
  537. }
  538.  
  539. template <class _RandomAccessIterator, class _Tp,
  540.           class _Reference, class _Distance>
  541. inline bool 
  542. operator<=(const reverse_iterator<_RandomAccessIterator, _Tp,
  543.                                   _Reference, _Distance>& __x, 
  544.            const reverse_iterator<_RandomAccessIterator, _Tp,
  545.                                   _Reference, _Distance>& __y) {
  546.   return !(__y < __x);
  547. }
  548.  
  549. template <class _RandomAccessIterator, class _Tp,
  550.           class _Reference, class _Distance>
  551. inline bool 
  552. operator>=(const reverse_iterator<_RandomAccessIterator, _Tp,
  553.                                   _Reference, _Distance>& __x, 
  554.            const reverse_iterator<_RandomAccessIterator, _Tp,
  555.                                   _Reference, _Distance>& __y) {
  556.   return !(__x < __y);
  557. }
  558.  
  559. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  560.  
  561. template <class _RandomAccessIterator, class _Tp,
  562.           class _Reference, class _Distance>
  563. inline _Distance 
  564. operator-(const reverse_iterator<_RandomAccessIterator, _Tp,
  565.                                  _Reference, _Distance>& __x, 
  566.           const reverse_iterator<_RandomAccessIterator, _Tp,
  567.                                  _Reference, _Distance>& __y)
  568. {
  569.   return __y.base() - __x.base();
  570. }
  571.  
  572. template <class _RandAccIter, class _Tp, class _Ref, class _Dist>
  573. inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> 
  574. operator+(_Dist __n,
  575.           const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x)
  576. {
  577.   return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n);
  578. }
  579.  
  580. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  581.  
  582. // istream_iterator and ostream_iterator look very different if we're
  583. // using new, templatized iostreams than if we're using the old cfront
  584. // version.
  585.  
  586. #ifdef __STL_USE_NEW_IOSTREAMS
  587.  
  588. template <class _Tp, 
  589.           class _CharT = char, class _Traits = char_traits<_CharT>,
  590.           class _Dist = ptrdiff_t> 
  591. class istream_iterator {
  592. public:
  593.   typedef _CharT                         char_type;
  594.   typedef _Traits                        traits_type;
  595.   typedef basic_istream<_CharT, _Traits> istream_type;
  596.  
  597.   typedef input_iterator_tag             iterator_category;
  598.   typedef _Tp                            value_type;
  599.   typedef _Dist                          difference_type;
  600.   typedef const _Tp*                     pointer;
  601.   typedef const _Tp&                     reference;
  602.  
  603.   istream_iterator() : _M_stream(0), _M_ok(false) {}
  604.   istream_iterator(istream_type& __s) : _M_stream(&__s) { _M_read(); }
  605.  
  606.   reference operator*() const { return _M_value; }
  607.   pointer operator->() const { return &(operator*()); }
  608.  
  609.   istream_iterator& operator++() { 
  610.     _M_read(); 
  611.     return *this;
  612.   }
  613.   istream_iterator operator++(int)  {
  614.     istream_iterator __tmp = *this;
  615.     _M_read();
  616.     return __tmp;
  617.   }
  618.  
  619.   bool _M_equal(const istream_iterator& __x) const
  620.     { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
  621.  
  622. private:
  623.   istream_type* _M_stream;
  624.   _Tp _M_value;
  625.   bool _M_ok;
  626.  
  627.   void _M_read() {
  628.     _M_ok = (_M_stream && *_M_stream) ? true : false;
  629.     if (_M_ok) {
  630.       *_M_stream >> _M_value;
  631.       _M_ok = *_M_stream ? true : false;
  632.     }
  633.   }
  634. };
  635.  
  636. template <class _Tp, class _CharT, class _Traits, class _Dist>
  637. inline bool 
  638. operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
  639.            const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) {
  640.   return __x._M_equal(__y);
  641. }
  642.  
  643. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  644.  
  645. template <class _Tp, class _CharT, class _Traits, class _Dist>
  646. inline bool 
  647. operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x,
  648.            const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) {
  649.   return !__x._M_equal(__y);
  650. }
  651.  
  652. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  653.  
  654. template <class _Tp,
  655.           class _CharT = char, class _Traits = char_traits<_CharT> >
  656. class ostream_iterator {
  657. public:
  658.   typedef _CharT                         char_type;
  659.   typedef _Traits                        traits_type;
  660.   typedef basic_ostream<_CharT, _Traits> ostream_type;
  661.  
  662.   typedef output_iterator_tag            iterator_category;
  663.   typedef void                           value_type;
  664.   typedef void                           difference_type;
  665.   typedef void                           pointer;
  666.   typedef void                           reference;
  667.  
  668.   ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}
  669.   ostream_iterator(ostream_type& __s, const _CharT* __c) 
  670.     : _M_stream(&__s), _M_string(__c)  {}
  671.   ostream_iterator<_Tp>& operator=(const _Tp& __value) { 
  672.     *_M_stream << __value;
  673.     if (_M_string) *_M_stream << _M_string;
  674.     return *this;
  675.   }
  676.   ostream_iterator<_Tp>& operator*() { return *this; }
  677.   ostream_iterator<_Tp>& operator++() { return *this; } 
  678.   ostream_iterator<_Tp>& operator++(int) { return *this; } 
  679. private:
  680.   ostream_type* _M_stream;
  681.   const _CharT* _M_string;
  682. };
  683.  
  684. // The default template argument is declared in iosfwd
  685.  
  686. // We do not read any characters until operator* is called.  The first
  687. // time operator* is called, it calls getc.  Subsequent calls to getc 
  688. // return a cached character, and calls to operator++ use snextc.  Before
  689. // operator* or operator++ has been called, _M_is_initialized is false.
  690. template<class _CharT, class _Traits>
  691. class istreambuf_iterator
  692.   : public iterator<input_iterator_tag, _CharT,
  693.                     typename _Traits::off_type, _CharT*, _CharT&>
  694. {
  695. public:
  696.   typedef _CharT                           char_type;
  697.   typedef _Traits                          traits_type;
  698.   typedef typename _Traits::int_type       int_type;
  699.   typedef basic_streambuf<_CharT, _Traits> streambuf_type;
  700.   typedef basic_istream<_CharT, _Traits>   istream_type;
  701.  
  702. public:
  703.   istreambuf_iterator(streambuf_type* __p = 0) { this->_M_init(__p); }
  704.   istreambuf_iterator(istream_type& __is) { this->_M_init(__is.rdbuf()); }
  705.  
  706.   char_type operator*() const 
  707.     { return _M_is_initialized ? _M_c : _M_dereference_aux(); }
  708.  
  709.   istreambuf_iterator& operator++() { this->_M_nextc(); return *this; }
  710.   istreambuf_iterator  operator++(int) {
  711.     if (!_M_is_initialized)
  712.       _M_postincr_aux();
  713.     istreambuf_iterator __tmp = *this;
  714.     this->_M_nextc();
  715.     return __tmp;
  716.   }
  717.  
  718.   bool equal(const istreambuf_iterator& __i) const {
  719.     return this->_M_is_initialized && __i._M_is_initialized
  720.       ? this->_M_eof == __i._M_eof
  721.       : this->_M_equal_aux(__i);
  722.   }
  723.  
  724. private:
  725.   void _M_init(streambuf_type* __p) {
  726.     _M_buf = __p;
  727.     _M_eof = !__p;
  728.     _M_is_initialized = _M_eof;
  729.   }
  730.  
  731.   char_type _M_dereference_aux() const;
  732.   bool _M_equal_aux(const istreambuf_iterator&) const;
  733.   void _M_postincr_aux();
  734.  
  735.   void _M_nextc() {
  736.     int_type __c = _M_buf->snextc();
  737.     _M_c = traits_type::to_char_type(__c);    
  738.     _M_eof = traits_type::eq_int_type(__c, traits_type::eof());
  739.     _M_is_initialized = true;
  740.   }
  741.  
  742.   void _M_getc() const {
  743.     int_type __c = _M_buf->sgetc();
  744.     _M_c = traits_type::to_char_type(__c);
  745.     _M_eof = traits_type::eq_int_type(__c, traits_type::eof());
  746.     _M_is_initialized = true;
  747.   }
  748.  
  749. private:
  750.   streambuf_type* _M_buf;
  751.   mutable _CharT _M_c;
  752.   mutable bool _M_eof : 1;
  753.   mutable bool _M_is_initialized : 1;
  754. };
  755.  
  756. template<class _CharT, class _Traits>
  757. _CharT istreambuf_iterator<_CharT, _Traits>::_M_dereference_aux() const
  758. {
  759.   this->_M_getc();
  760.   return _M_c;
  761. }
  762.  
  763. template<class _CharT, class _Traits>
  764. bool istreambuf_iterator<_CharT, _Traits>
  765.   ::_M_equal_aux(const istreambuf_iterator& __i) const
  766. {
  767.   if (!this->_M_is_initialized)
  768.     this->_M_getc();
  769.   if (!__i._M_is_initialized)
  770.     __i._M_getc();
  771.  
  772.   return this->_M_eof == __i._M_eof;
  773. }
  774.  
  775. template<class _CharT, class _Traits>
  776. void istreambuf_iterator<_CharT, _Traits>::_M_postincr_aux()
  777. {
  778.   this->_M_getc();
  779. }
  780.  
  781. template<class _CharT, class _Traits>
  782. inline bool operator==(const istreambuf_iterator<_CharT, _Traits>& __x,
  783.                        const istreambuf_iterator<_CharT, _Traits>& __y) {
  784.   return __x.equal(__y);
  785. }
  786.  
  787. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  788.  
  789. template<class _CharT, class _Traits>
  790. inline bool operator!=(const istreambuf_iterator<_CharT, _Traits>& __x,
  791.                        const istreambuf_iterator<_CharT, _Traits>& __y) {
  792.   return !__x.equal(__y);
  793. }
  794.  
  795. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  796.  
  797. // The default template argument is declared in iosfwd
  798. template<class _CharT, class _Traits>
  799. class ostreambuf_iterator
  800.   : public iterator<output_iterator_tag, void, void, void, void>
  801. {
  802. public:
  803.   typedef _CharT                           char_type;
  804.   typedef _Traits                          traits_type;
  805.   typedef typename _Traits::int_type       int_type;
  806.   typedef basic_streambuf<_CharT, _Traits> streambuf_type;
  807.   typedef basic_ostream<_CharT, _Traits>   ostream_type;
  808.  
  809. public:
  810.   ostreambuf_iterator(streambuf_type* __buf) : _M_buf(__buf), _M_ok(__buf) {}
  811.   ostreambuf_iterator(ostream_type& __o)
  812.     : _M_buf(__o.rdbuf()), _M_ok(__o.rdbuf() != 0) {}
  813.  
  814.   ostreambuf_iterator& operator=(char_type __c) {
  815.     _M_ok = _M_ok && !traits_type::eq_int_type(_M_buf->sputc(__c),
  816.                                                traits_type::eof());
  817.     return *this;
  818.   }    
  819.   
  820.   ostreambuf_iterator& operator*()     { return *this; }
  821.   ostreambuf_iterator& operator++()    { return *this; }
  822.   ostreambuf_iterator& operator++(int) { return *this; }
  823.  
  824.   bool failed() const { return !_M_ok; }
  825.  
  826. private:
  827.   streambuf_type* _M_buf;
  828.   bool _M_ok;
  829. };
  830.  
  831. #else /* __STL_USE_NEW_IOSTREAMS */
  832.  
  833. template <class _Tp, class _Dist = ptrdiff_t> class istream_iterator;
  834.  
  835. template <class _Tp, class _Dist>
  836. inline bool operator==(const istream_iterator<_Tp, _Dist>&,
  837.                        const istream_iterator<_Tp, _Dist>&);
  838.  
  839. template <class _Tp, class _Dist>
  840. class istream_iterator {
  841. #ifdef __STL_TEMPLATE_FRIENDS
  842.   template <class _T1, class _D1>
  843.   friend bool operator==(const istream_iterator<_T1, _D1>&,
  844.                          const istream_iterator<_T1, _D1>&);
  845. #else /* __STL_TEMPLATE_FRIENDS */
  846.   friend bool __STD_QUALIFIER
  847.   operator== __STL_NULL_TMPL_ARGS (const istream_iterator&,
  848.                                    const istream_iterator&);
  849. #endif /* __STL_TEMPLATE_FRIENDS */
  850.  
  851. protected:
  852.   istream* _M_stream;
  853.   _Tp _M_value;
  854.   bool _M_end_marker;
  855.   void _M_read() {
  856.     _M_end_marker = (*_M_stream) ? true : false;
  857.     if (_M_end_marker) *_M_stream >> _M_value;
  858.     _M_end_marker = (*_M_stream) ? true : false;
  859.   }
  860. public:
  861.   typedef input_iterator_tag  iterator_category;
  862.   typedef _Tp                 value_type;
  863.   typedef _Dist               difference_type;
  864.   typedef const _Tp*          pointer;
  865.   typedef const _Tp&          reference;
  866.  
  867.   istream_iterator() : _M_stream(&cin), _M_end_marker(false) {}
  868.   istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); }
  869.   reference operator*() const { return _M_value; }
  870. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  871.   pointer operator->() const { return &(operator*()); }
  872. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  873.   istream_iterator<_Tp, _Dist>& operator++() { 
  874.     _M_read(); 
  875.     return *this;
  876.   }
  877.   istream_iterator<_Tp, _Dist> operator++(int)  {
  878.     istream_iterator<_Tp, _Dist> __tmp = *this;
  879.     _M_read();
  880.     return __tmp;
  881.   }
  882. };
  883.  
  884. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  885.  
  886. template <class _Tp, class _Dist>
  887. inline input_iterator_tag 
  888. iterator_category(const istream_iterator<_Tp, _Dist>&)
  889. {
  890.   return input_iterator_tag();
  891. }
  892.  
  893. template <class _Tp, class _Dist>
  894. inline _Tp* 
  895. value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; }
  896.  
  897. template <class _Tp, class _Dist>
  898. inline _Dist* 
  899. distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; }
  900.  
  901. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  902.  
  903. template <class _Tp, class _Distance>
  904. inline bool operator==(const istream_iterator<_Tp, _Distance>& __x,
  905.                        const istream_iterator<_Tp, _Distance>& __y) {
  906.   return (__x._M_stream == __y._M_stream &&
  907.           __x._M_end_marker == __y._M_end_marker) ||
  908.          __x._M_end_marker == false && __y._M_end_marker == false;
  909. }
  910.  
  911. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  912.  
  913. template <class _Tp, class _Distance>
  914. inline bool operator!=(const istream_iterator<_Tp, _Distance>& __x,
  915.                        const istream_iterator<_Tp, _Distance>& __y) {
  916.   return !(__x == __y);
  917. }
  918.  
  919. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  920.  
  921. template <class _Tp>
  922. class ostream_iterator {
  923. protected:
  924.   ostream* _M_stream;
  925.   const char* _M_string;
  926. public:
  927.   typedef output_iterator_tag iterator_category;
  928.   typedef void                value_type;
  929.   typedef void                difference_type;
  930.   typedef void                pointer;
  931.   typedef void                reference;
  932.  
  933.   ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {}
  934.   ostream_iterator(ostream& __s, const char* __c) 
  935.     : _M_stream(&__s), _M_string(__c)  {}
  936.   ostream_iterator<_Tp>& operator=(const _Tp& __value) { 
  937.     *_M_stream << __value;
  938.     if (_M_string) *_M_stream << _M_string;
  939.     return *this;
  940.   }
  941.   ostream_iterator<_Tp>& operator*() { return *this; }
  942.   ostream_iterator<_Tp>& operator++() { return *this; } 
  943.   ostream_iterator<_Tp>& operator++(int) { return *this; } 
  944. };
  945.  
  946. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  947.  
  948. template <class _Tp>
  949. inline output_iterator_tag 
  950. iterator_category(const ostream_iterator<_Tp>&) {
  951.   return output_iterator_tag();
  952. }
  953.  
  954. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  955.  
  956. #endif /* __STL_USE_NEW_IOSTREAMS */
  957.  
  958. __STL_END_NAMESPACE
  959.  
  960. #endif /* __SGI_STL_INTERNAL_ITERATOR_H */
  961.  
  962. // Local Variables:
  963. // mode:C++
  964. // End:
  965.