stl_iterator.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:28k
源码类别:

3D图形编程

开发平台:

Visual C++

  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. /* NOTE: This is an internal header file, included by other STL headers.
  27.  *   You should not attempt to use it directly.
  28.  */
  29. #ifndef __SGI_STL_INTERNAL_ITERATOR_H
  30. #define __SGI_STL_INTERNAL_ITERATOR_H
  31. __STL_BEGIN_NAMESPACE
  32. struct input_iterator_tag {};
  33. struct output_iterator_tag {};
  34. struct forward_iterator_tag : public input_iterator_tag {};
  35. struct bidirectional_iterator_tag : public forward_iterator_tag {};
  36. struct random_access_iterator_tag : public bidirectional_iterator_tag {};
  37. // The base classes input_iterator, output_iterator, forward_iterator,
  38. // bidirectional_iterator, and random_access_iterator are not part of
  39. // the C++ standard.  (they have been replaced by struct iterator.)
  40. // They are included for backward compatibility with the HP STL.
  41. template <class _T, class _Distance> struct input_iterator {
  42.   typedef input_iterator_tag  iterator_category;
  43.   typedef _T                  value_type;
  44.   typedef _Distance           difference_type;
  45.   typedef _T*                 pointer;
  46.   typedef _T&                 reference;
  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. template <class _T, class _Distance> struct forward_iterator {
  56.   typedef forward_iterator_tag  iterator_category;
  57.   typedef _T                    value_type;
  58.   typedef _Distance             difference_type;
  59.   typedef _T*                   pointer;
  60.   typedef _T&                   reference;
  61. };
  62. template <class _T, class _Distance> struct bidirectional_iterator {
  63.   typedef bidirectional_iterator_tag  iterator_category;
  64.   typedef _T                          value_type;
  65.   typedef _Distance                   difference_type;
  66.   typedef _T*                         pointer;
  67.   typedef _T&                         reference;
  68. };
  69. template <class _T, class _Distance> struct random_access_iterator {
  70.   typedef random_access_iterator_tag  iterator_category;
  71.   typedef _T                          value_type;
  72.   typedef _Distance                   difference_type;
  73.   typedef _T*                         pointer;
  74.   typedef _T&                         reference;
  75. };
  76. #ifdef __STL_USE_NAMESPACES
  77. template <class _Category, class _T, class _Distance = ptrdiff_t,
  78.           class _Pointer = _T*, class _Reference = _T&>
  79. struct iterator {
  80.   typedef _Category  iterator_category;
  81.   typedef _T         value_type;
  82.   typedef _Distance  difference_type;
  83.   typedef _Pointer   pointer;
  84.   typedef _Reference reference;
  85. };
  86. #endif /* __STL_USE_NAMESPACES */
  87. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  88. template <class _Iterator>
  89. struct iterator_traits {
  90.   typedef typename _Iterator::iterator_category iterator_category;
  91.   typedef typename _Iterator::value_type        value_type;
  92.   typedef typename _Iterator::difference_type   difference_type;
  93.   typedef typename _Iterator::pointer           pointer;
  94.   typedef typename _Iterator::reference         reference;
  95. };
  96. template <class _T>
  97. struct iterator_traits<_T*> {
  98.   typedef random_access_iterator_tag iterator_category;
  99.   typedef _T                          value_type;
  100.   typedef ptrdiff_t                   difference_type;
  101.   typedef _T*                         pointer;
  102.   typedef _T&                         reference;
  103. };
  104. template <class _T>
  105. struct iterator_traits<const _T*> {
  106.   typedef random_access_iterator_tag iterator_category;
  107.   typedef _T                          value_type;
  108.   typedef ptrdiff_t                   difference_type;
  109.   typedef const _T*                   pointer;
  110.   typedef const _T&                   reference;
  111. };
  112. // The overloaded functions iterator_category, distance_type, and
  113. // value_type are not part of the C++ standard.  (They have been
  114. // replaced by struct iterator_traits.)  They are included for
  115. // backward compatibility with the HP STL.
  116. // We introduce internal names for these functions.
  117. template <class _Iter>
  118. inline typename iterator_traits<_Iter>::iterator_category
  119. __iterator_category(const _Iter&)
  120. {
  121.   typedef typename iterator_traits<_Iter>::iterator_category _Category;
  122.   return _Category();
  123. }
  124. template <class _Iter>
  125. inline typename iterator_traits<_Iter>::difference_type*
  126. __distance_type(const _Iter&)
  127. {
  128.   return static_cast<typename iterator_traits<_Iter>::difference_type*>(0);
  129. }
  130. template <class _Iter>
  131. inline typename iterator_traits<_Iter>::value_type*
  132. __value_type(const _Iter&)
  133. {
  134.   return static_cast<typename iterator_traits<_Iter>::value_type*>(0);
  135. }
  136. template <class _Iter>
  137. inline typename iterator_traits<_Iter>::iterator_category
  138. iterator_category(const _Iter& __i) { return __iterator_category(__i); }
  139. template <class _Iter>
  140. inline typename iterator_traits<_Iter>::difference_type*
  141. distance_type(const _Iter& __i) { return __distance_type(__i); }
  142. template <class _Iter>
  143. inline typename iterator_traits<_Iter>::value_type*
  144. value_type(const _Iter& __i) { return __value_type(__i); }
  145. #define __ITERATOR_CATEGORY(__i) __iterator_category(__i)
  146. #define __DISTANCE_TYPE(__i)     __distance_type(__i)
  147. #define __VALUE_TYPE(__i)        __value_type(__i)
  148. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  149. template <class _T, class _Distance> 
  150. inline input_iterator_tag 
  151. iterator_category(const input_iterator<_T, _Distance>&)
  152.   { return input_iterator_tag(); }
  153. inline output_iterator_tag iterator_category(const output_iterator&)
  154.   { return output_iterator_tag(); }
  155. template <class _T, class _Distance> 
  156. inline forward_iterator_tag
  157. iterator_category(const forward_iterator<_T, _Distance>&)
  158.   { return forward_iterator_tag(); }
  159. template <class _T, class _Distance> 
  160. inline bidirectional_iterator_tag
  161. iterator_category(const bidirectional_iterator<_T, _Distance>&)
  162.   { return bidirectional_iterator_tag(); }
  163. template <class _T, class _Distance> 
  164. inline random_access_iterator_tag
  165. iterator_category(const random_access_iterator<_T, _Distance>&)
  166.   { return random_access_iterator_tag(); }
  167. template <class _T>
  168. inline random_access_iterator_tag iterator_category(const _T*)
  169.   { return random_access_iterator_tag(); }
  170. template <class _T, class _Distance> 
  171. inline _T* value_type(const input_iterator<_T, _Distance>&)
  172.   { return (_T*)(0); }
  173. template <class _T, class _Distance> 
  174. inline _T* value_type(const forward_iterator<_T, _Distance>&)
  175.   { return (_T*)(0); }
  176. template <class _T, class _Distance> 
  177. inline _T* value_type(const bidirectional_iterator<_T, _Distance>&)
  178.   { return (_T*)(0); }
  179. template <class _T, class _Distance> 
  180. inline _T* value_type(const random_access_iterator<_T, _Distance>&)
  181.   { return (_T*)(0); }
  182. template <class _T>
  183. inline _T* value_type(const _T*) { return (_T*)(0); }
  184. template <class _T, class _Distance> 
  185. inline _Distance* distance_type(const input_iterator<_T, _Distance>&)
  186. {
  187.   return (_Distance*)(0);
  188. }
  189. template <class _T, class _Distance> 
  190. inline _Distance* distance_type(const forward_iterator<_T, _Distance>&)
  191. {
  192.   return (_Distance*)(0);
  193. }
  194. template <class _T, class _Distance> 
  195. inline _Distance* 
  196. distance_type(const bidirectional_iterator<_T, _Distance>&)
  197. {
  198.   return (_Distance*)(0);
  199. }
  200. template <class _T, class _Distance> 
  201. inline _Distance* 
  202. distance_type(const random_access_iterator<_T, _Distance>&)
  203. {
  204.   return (_Distance*)(0);
  205. }
  206. template <class _T>
  207. inline ptrdiff_t* distance_type(const _T*) { return (ptrdiff_t*)(0); }
  208. // Without partial specialization we can't use iterator_traits, so
  209. // we must keep the old iterator query functions around.  
  210. #define __ITERATOR_CATEGORY(__i) iterator_category(__i)
  211. #define __DISTANCE_TYPE(__i)     distance_type(__i)
  212. #define __VALUE_TYPE(__i)        value_type(__i)
  213. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  214. template <class _InputIterator, class _Distance>
  215. inline void __distance(_InputIterator __first, _InputIterator __last,
  216.                        _Distance& __n, input_iterator_tag)
  217. {
  218.   while (__first != __last) { ++__first; ++__n; }
  219. }
  220. template <class _RandomAccessIterator, class _Distance>
  221. inline void __distance(_RandomAccessIterator __first, 
  222.                        _RandomAccessIterator __last, 
  223.                        _Distance& __n, random_access_iterator_tag)
  224. {
  225.   __n += __last - __first;
  226. }
  227. template <class _InputIterator, class _Distance>
  228. inline void distance(_InputIterator __first, 
  229.                      _InputIterator __last, _Distance& __n)
  230. {
  231.   __distance(__first, __last, __n, iterator_category(__first));
  232. }
  233. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  234. template <class _InputIterator>
  235. inline iterator_traits<_InputIterator>::difference_type
  236. __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag)
  237. {
  238.   iterator_traits<_InputIterator>::difference_type __n = 0;
  239.   while (__first != __last) {
  240.     ++__first; ++__n;
  241.   }
  242.   return __n;
  243. }
  244. template <class _RandomAccessIterator>
  245. inline iterator_traits<_RandomAccessIterator>::difference_type
  246. __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
  247.            random_access_iterator_tag) {
  248.   return __last - __first;
  249. }
  250. template <class _InputIterator>
  251. inline iterator_traits<_InputIterator>::difference_type
  252. distance(_InputIterator __first, _InputIterator __last) {
  253.   typedef typename iterator_traits<_InputIterator>::iterator_category 
  254.     _Category;
  255.   return __distance(__first, __last, _Category());
  256. }
  257. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  258. template <class _InputIter, class _Distance>
  259. inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
  260.   while (__n--) ++__i;
  261. }
  262. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  263. #pragma set woff 1183
  264. #endif
  265. template <class _BidirectionalIterator, class _Distance>
  266. inline void __advance(_BidirectionalIterator& __i, _Distance __n, 
  267.                       bidirectional_iterator_tag) {
  268.   if (__n >= 0)
  269.     while (__n--) ++__i;
  270.   else
  271.     while (__n++) --__i;
  272. }
  273. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  274. #pragma reset woff 1183
  275. #endif
  276. template <class _RandomAccessIterator, class _Distance>
  277. inline void __advance(_RandomAccessIterator& __i, _Distance __n, 
  278.                       random_access_iterator_tag) {
  279.   __i += __n;
  280. }
  281. template <class _InputIterator, class _Distance>
  282. inline void advance(_InputIterator& __i, _Distance __n) {
  283.   __advance(__i, __n, iterator_category(__i));
  284. }
  285. template <class _Container>
  286. class back_insert_iterator {
  287. protected:
  288.   _Container* container;
  289. public:
  290.   typedef _Container          container_type;
  291.   typedef output_iterator_tag iterator_category;
  292.   typedef void                value_type;
  293.   typedef void                difference_type;
  294.   typedef void                pointer;
  295.   typedef void                reference;
  296.   explicit back_insert_iterator(_Container& __x) : container(&__x) {}
  297.   back_insert_iterator<_Container>&
  298.   operator=(const typename _Container::value_type& __value) { 
  299.     container->push_back(__value);
  300.     return *this;
  301.   }
  302.   back_insert_iterator<_Container>& operator*() { return *this; }
  303.   back_insert_iterator<_Container>& operator++() { return *this; }
  304.   back_insert_iterator<_Container>& operator++(int) { return *this; }
  305. };
  306. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  307. template <class _Container>
  308. inline output_iterator_tag
  309. iterator_category(const back_insert_iterator<_Container>&)
  310. {
  311.   return output_iterator_tag();
  312. }
  313. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  314. template <class _Container>
  315. inline back_insert_iterator<_Container> back_inserter(_Container& __x) {
  316.   return back_insert_iterator<_Container>(__x);
  317. }
  318. template <class _Container>
  319. class front_insert_iterator {
  320. protected:
  321.   _Container* container;
  322. public:
  323.   typedef _Container          container_type;
  324.   typedef output_iterator_tag iterator_category;
  325.   typedef void                value_type;
  326.   typedef void                difference_type;
  327.   typedef void                pointer;
  328.   typedef void                reference;
  329.   explicit front_insert_iterator(_Container& __x) : container(&__x) {}
  330.   front_insert_iterator<_Container>&
  331.   operator=(const typename _Container::value_type& __value) { 
  332.     container->push_front(__value);
  333.     return *this;
  334.   }
  335.   front_insert_iterator<_Container>& operator*() { return *this; }
  336.   front_insert_iterator<_Container>& operator++() { return *this; }
  337.   front_insert_iterator<_Container>& operator++(int) { return *this; }
  338. };
  339. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  340. template <class _Container>
  341. inline output_iterator_tag
  342. iterator_category(const front_insert_iterator<_Container>&)
  343. {
  344.   return output_iterator_tag();
  345. }
  346. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  347. template <class _Container>
  348. inline front_insert_iterator<_Container> front_inserter(_Container& __x) {
  349.   return front_insert_iterator<_Container>(__x);
  350. }
  351. template <class _Container>
  352. class insert_iterator {
  353. protected:
  354.   _Container* container;
  355.   typename _Container::iterator iter;
  356. public:
  357.   typedef _Container          container_type;
  358.   typedef output_iterator_tag iterator_category;
  359.   typedef void                value_type;
  360.   typedef void                difference_type;
  361.   typedef void                pointer;
  362.   typedef void                reference;
  363.   insert_iterator(_Container& __x, typename _Container::iterator __i) 
  364.     : container(&__x), iter(__i) {}
  365.   insert_iterator<_Container>&
  366.   operator=(const typename _Container::value_type& __value) { 
  367.     iter = container->insert(iter, __value);
  368.     ++iter;
  369.     return *this;
  370.   }
  371.   insert_iterator<_Container>& operator*() { return *this; }
  372.   insert_iterator<_Container>& operator++() { return *this; }
  373.   insert_iterator<_Container>& operator++(int) { return *this; }
  374. };
  375. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  376. template <class _Container>
  377. inline output_iterator_tag
  378. iterator_category(const insert_iterator<_Container>&)
  379. {
  380.   return output_iterator_tag();
  381. }
  382. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  383. template <class _Container, class _Iterator>
  384. inline 
  385. insert_iterator<_Container> inserter(_Container& __x, _Iterator __i)
  386. {
  387.   typedef typename _Container::iterator __iter;
  388.   return insert_iterator<_Container>(__x, __iter(__i));
  389. }
  390. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  391. template <class _BidirectionalIterator, class _T, class _Reference = _T&, 
  392.           class _Distance = ptrdiff_t> 
  393. #else
  394. template <class _BidirectionalIterator, class _T, class _Reference, 
  395.           class _Distance> 
  396. #endif
  397. class reverse_bidirectional_iterator {
  398.   typedef reverse_bidirectional_iterator<_BidirectionalIterator, _T, 
  399.                                          _Reference, _Distance>  _Self;
  400. protected:
  401.   _BidirectionalIterator _M_current;
  402. public:
  403.   typedef bidirectional_iterator_tag iterator_category;
  404.   typedef _T                          value_type;
  405.   typedef _Distance                   difference_type;
  406.   typedef _T*                         pointer;
  407.   typedef _Reference                  reference;
  408.   reverse_bidirectional_iterator() {}
  409.   explicit reverse_bidirectional_iterator(_BidirectionalIterator __x)
  410.     : _M_current(__x) {}
  411.   _BidirectionalIterator base() const { return _M_current; }
  412.   _Reference operator*() const {
  413.     _BidirectionalIterator __tmp = _M_current;
  414.     return *--__tmp;
  415.   }
  416. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  417.   pointer operator->() const { return &(operator*()); }
  418. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  419.   _Self& operator++() {
  420.     --_M_current;
  421.     return *this;
  422.   }
  423.   _Self operator++(int) {
  424.     _Self __tmp = *this;
  425.     --_M_current;
  426.     return __tmp;
  427.   }
  428.   _Self& operator--() {
  429.     ++_M_current;
  430.     return *this;
  431.   }
  432.   _Self operator--(int) {
  433.     _Self __tmp = *this;
  434.     ++_M_current;
  435.     return __tmp;
  436.   }
  437. };
  438. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  439. template <class _BidirectionalIterator, class _T, class _Reference, 
  440.           class _Distance>
  441. inline bidirectional_iterator_tag
  442. iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator,
  443.                                                        _T, _Reference, 
  444.                                                        _Distance>&) 
  445. {
  446.   return bidirectional_iterator_tag();
  447. }
  448. template <class _BidirectionalIterator, class _T, class _Reference, 
  449.           class _Distance>
  450. inline _T*
  451. value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _T,
  452.                                                _Reference, _Distance>&)
  453. {
  454.   return (_T*) 0;
  455. }
  456. template <class _BidirectionalIterator, class _T, class _Reference, 
  457.           class _Distance>
  458. inline _Distance*
  459. distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _T,
  460.                                                    _Reference, _Distance>&)
  461. {
  462.   return (_Distance*) 0;
  463. }
  464. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  465. template <class _BiIter, class _T, class _Ref,
  466.           class _Distance>
  467. inline bool operator==(
  468.     const reverse_bidirectional_iterator<_BiIter, _T, _Ref, _Distance>& __x, 
  469.     const reverse_bidirectional_iterator<_BiIter, _T, _Ref, _Distance>& __y)
  470. {
  471.   return __x.base() == __y.base();
  472. }
  473. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  474. // This is the new version of reverse_iterator, as defined in the
  475. //  draft C++ standard.  It relies on the iterator_traits template,
  476. //  which in turn relies on partial specialization.  The class
  477. //  reverse_bidirectional_iterator is no longer part of the draft
  478. //  standard, but it is retained for backward compatibility.
  479. template <class _Iterator>
  480. class reverse_iterator 
  481. {
  482. protected:
  483.   _Iterator _M_current;
  484. public:
  485.   typedef typename iterator_traits<_Iterator>::iterator_category
  486.           iterator_category;
  487.   typedef typename iterator_traits<_Iterator>::value_type
  488.           value_type;
  489.   typedef typename iterator_traits<_Iterator>::difference_type
  490.           difference_type;
  491.   typedef typename iterator_traits<_Iterator>::pointer
  492.           pointer;
  493.   typedef typename iterator_traits<_Iterator>::reference
  494.           reference;
  495.   typedef _Iterator iterator_type;
  496.   typedef reverse_iterator<_Iterator> _Self;
  497. public:
  498.   reverse_iterator() {}
  499.   explicit reverse_iterator(iterator_type __x) : _M_current(__x) {}
  500.   reverse_iterator(const _Self& __x) : _M_current(__x._M_current) {}
  501. #ifdef __STL_MEMBER_TEMPLATES
  502.   template <class _Iter>
  503.   reverse_iterator(const reverse_iterator<_Iter>& __x)
  504.     : _M_current(__x.base()) {}
  505. #endif /* __STL_MEMBER_TEMPLATES */
  506.     
  507.   iterator_type base() const { return _M_current; }
  508.   reference operator*() const {
  509.     _Iterator __tmp = _M_current;
  510.     return *--__tmp;
  511.   }
  512. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  513.   pointer operator->() const { return &(operator*()); }
  514. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  515.   _Self& operator++() {
  516.     --_M_current;
  517.     return *this;
  518.   }
  519.   _Self operator++(int) {
  520.     _Self __tmp = *this;
  521.     --_M_current;
  522.     return __tmp;
  523.   }
  524.   _Self& operator--() {
  525.     ++_M_current;
  526.     return *this;
  527.   }
  528.   _Self operator--(int) {
  529.     _Self __tmp = *this;
  530.     ++_M_current;
  531.     return __tmp;
  532.   }
  533.   _Self operator+(difference_type __n) const {
  534.     return _Self(_M_current - __n);
  535.   }
  536.   _Self& operator+=(difference_type __n) {
  537.     _M_current -= __n;
  538.     return *this;
  539.   }
  540.   _Self operator-(difference_type __n) const {
  541.     return _Self(_M_current + __n);
  542.   }
  543.   _Self& operator-=(difference_type __n) {
  544.     _M_current += __n;
  545.     return *this;
  546.   }
  547.   reference operator[](difference_type __n) const { return *(*this + __n); }  
  548. }; 
  549.  
  550. template <class _Iterator>
  551. inline bool operator==(const reverse_iterator<_Iterator>& __x, 
  552.                        const reverse_iterator<_Iterator>& __y) {
  553.   return __x.base() == __y.base();
  554. }
  555. template <class _Iterator>
  556. inline bool operator<(const reverse_iterator<_Iterator>& __x, 
  557.                       const reverse_iterator<_Iterator>& __y) {
  558.   return __y.base() < __x.base();
  559. }
  560. template <class _Iterator>
  561. inline typename reverse_iterator<_Iterator>::difference_type
  562. operator-(const reverse_iterator<_Iterator>& __x, 
  563.           const reverse_iterator<_Iterator>& __y) {
  564.   return __y.base() - __x.base();
  565. }
  566. template <class _Iterator>
  567. inline reverse_iterator<_Iterator> 
  568. operator+(reverse_iterator<_Iterator>::difference_type __n,
  569.           const reverse_iterator<_Iterator>& __x) {
  570.   return reverse_iterator<_Iterator>(__x.base() - __n);
  571. }
  572. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  573. // This is the old version of reverse_iterator, as found in the original
  574. //  HP STL.  It does not use partial specialization.
  575. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
  576. template <class _RandomAccessIterator, class _T, class _Reference = _T&,
  577.           class _Distance = ptrdiff_t> 
  578. #else
  579. template <class _RandomAccessIterator, class _T, class _Reference,
  580.           class _Distance> 
  581. #endif
  582. class reverse_iterator {
  583.   typedef reverse_iterator<_RandomAccessIterator, _T, _Reference, _Distance>
  584.         _Self;
  585. protected:
  586.   _RandomAccessIterator _M_current;
  587. public:
  588.   typedef random_access_iterator_tag iterator_category;
  589.   typedef _T                          value_type;
  590.   typedef _Distance                   difference_type;
  591.   typedef _T*                         pointer;
  592.   typedef _Reference                  reference;
  593.   reverse_iterator() {}
  594.   explicit reverse_iterator(_RandomAccessIterator __x) : _M_current(__x) {}
  595.   _RandomAccessIterator base() const { return _M_current; }
  596.   _Reference operator*() const { return *(_M_current - 1); }
  597. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  598.   pointer operator->() const { return &(operator*()); }
  599. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  600.   _Self& operator++() {
  601.     --_M_current;
  602.     return *this;
  603.   }
  604.   _Self operator++(int) {
  605.     _Self __tmp = *this;
  606.     --_M_current;
  607.     return __tmp;
  608.   }
  609.   _Self& operator--() {
  610.     ++_M_current;
  611.     return *this;
  612.   }
  613.   _Self operator--(int) {
  614.     _Self __tmp = *this;
  615.     ++_M_current;
  616.     return __tmp;
  617.   }
  618.   _Self operator+(_Distance __n) const {
  619.     return _Self(_M_current - __n);
  620.   }
  621.   _Self& operator+=(_Distance __n) {
  622.     _M_current -= __n;
  623.     return *this;
  624.   }
  625.   _Self operator-(_Distance __n) const {
  626.     return _Self(_M_current + __n);
  627.   }
  628.   _Self& operator-=(_Distance __n) {
  629.     _M_current += __n;
  630.     return *this;
  631.   }
  632.   _Reference operator[](_Distance __n) const { return *(*this + __n); }
  633. };
  634. template <class _RandomAccessIterator, class _T, 
  635.           class _Reference, class _Distance>
  636. inline random_access_iterator_tag
  637. iterator_category(const reverse_iterator<_RandomAccessIterator, _T,
  638.                                          _Reference, _Distance>&)
  639. {
  640.   return random_access_iterator_tag();
  641. }
  642. template <class _RandomAccessIterator, class _T,
  643.           class _Reference, class _Distance>
  644. inline _T* value_type(const reverse_iterator<_RandomAccessIterator, _T,
  645.                                             _Reference, _Distance>&)
  646. {
  647.   return (_T*) 0;
  648. }
  649. template <class _RandomAccessIterator, class _T,
  650.           class _Reference, class _Distance>
  651. inline _Distance* 
  652. distance_type(const reverse_iterator<_RandomAccessIterator, 
  653.                                      _T, _Reference, _Distance>&)
  654. {
  655.   return (_Distance*) 0;
  656. }
  657. template <class _RandomAccessIterator, class _T,
  658.           class _Reference, class _Distance>
  659. inline bool 
  660. operator==(const reverse_iterator<_RandomAccessIterator, _T,
  661.                                   _Reference, _Distance>& __x, 
  662.            const reverse_iterator<_RandomAccessIterator, _T,
  663.                                   _Reference, _Distance>& __y)
  664. {
  665.   return __x.base() == __y.base();
  666. }
  667. template <class _RandomAccessIterator, class _T,
  668.           class _Reference, class _Distance>
  669. inline bool 
  670. operator<(const reverse_iterator<_RandomAccessIterator, _T,
  671.                                  _Reference, _Distance>& __x, 
  672.           const reverse_iterator<_RandomAccessIterator, _T,
  673.                                  _Reference, _Distance>& __y)
  674. {
  675.   return __y.base() < __x.base();
  676. }
  677. template <class _RandomAccessIterator, class _T,
  678.           class _Reference, class _Distance>
  679. inline _Distance 
  680. operator-(const reverse_iterator<_RandomAccessIterator, _T,
  681.                                  _Reference, _Distance>& __x, 
  682.           const reverse_iterator<_RandomAccessIterator, _T,
  683.                                  _Reference, _Distance>& __y)
  684. {
  685.   return __y.base() - __x.base();
  686. }
  687. template <class _RandAccIter, class _T, class _Ref, class _Dist>
  688. inline reverse_iterator<_RandAccIter, _T, _Ref, _Dist> 
  689. operator+(_Dist __n,
  690.           const reverse_iterator<_RandAccIter, _T, _Ref, _Dist>& __x)
  691. {
  692.   return reverse_iterator<_RandAccIter, _T, _Ref, _Dist>(__x.base() - __n);
  693. }
  694. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  695. // When we have templatized iostreams, istream_iterator and ostream_iterator
  696. // must be rewritten.
  697. template <class _T, class _Dist = ptrdiff_t> 
  698. class istream_iterator {
  699.   friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator&,
  700.                                                const istream_iterator&);
  701. protected:
  702.   istream* _M_stream;
  703.   _T _M_value;
  704.   bool _M_end_marker;
  705.   void _M_read() {
  706.     _M_end_marker = (*_M_stream) ? true : false;
  707.     if (_M_end_marker) *_M_stream >> _M_value;
  708.     _M_end_marker = (*_M_stream) ? true : false;
  709.   }
  710. public:
  711.   typedef input_iterator_tag  iterator_category;
  712.   typedef _T                  value_type;
  713.   typedef _Dist               difference_type;
  714.   typedef const _T*           pointer;
  715.   typedef const _T&           reference;
  716.   istream_iterator() : _M_stream(&cin), _M_end_marker(false) {}
  717.   istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); }
  718.   reference operator*() const { return _M_value; }
  719. #ifndef __SGI_STL_NO_ARROW_OPERATOR
  720.   pointer operator->() const { return &(operator*()); }
  721. #endif /* __SGI_STL_NO_ARROW_OPERATOR */
  722.   istream_iterator<_T, _Dist>& operator++() { 
  723.     _M_read(); 
  724.     return *this;
  725.   }
  726.   istream_iterator<_T, _Dist> operator++(int)  {
  727.     istream_iterator<_T, _Dist> __tmp = *this;
  728.     _M_read();
  729.     return __tmp;
  730.   }
  731. };
  732. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  733. template <class _T, class _Dist>
  734. inline input_iterator_tag 
  735. iterator_category(const istream_iterator<_T, _Dist>&)
  736. {
  737.   return input_iterator_tag();
  738. }
  739. template <class _T, class _Dist>
  740. inline _T* 
  741. value_type(const istream_iterator<_T, _Dist>&) { return (_T*) 0; }
  742. template <class _T, class _Dist>
  743. inline _Dist* 
  744. distance_type(const istream_iterator<_T, _Dist>&) { return (_Dist*)0; }
  745. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  746. template <class _T, class _Distance>
  747. inline bool operator==(const istream_iterator<_T, _Distance>& __x,
  748.                        const istream_iterator<_T, _Distance>& __y) {
  749.   return (__x._M_stream == __y._M_stream &&
  750.           __x._M_end_marker == __y._M_end_marker) ||
  751.          __x._M_end_marker == false && __y._M_end_marker == false;
  752. }
  753. template <class _T>
  754. class ostream_iterator {
  755. protected:
  756.   ostream* _M_stream;
  757.   const char* _M_string;
  758. public:
  759.   typedef output_iterator_tag iterator_category;
  760.   typedef void                value_type;
  761.   typedef void                difference_type;
  762.   typedef void                pointer;
  763.   typedef void                reference;
  764.   ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {}
  765.   ostream_iterator(ostream& __s, const char* __c) 
  766.     : _M_stream(&__s), _M_string(__c)  {}
  767.   ostream_iterator<_T>& operator=(const _T& __value) { 
  768.     *_M_stream << __value;
  769.     if (_M_string) *_M_stream << _M_string;
  770.     return *this;
  771.   }
  772.   ostream_iterator<_T>& operator*() { return *this; }
  773.   ostream_iterator<_T>& operator++() { return *this; } 
  774.   ostream_iterator<_T>& operator++(int) { return *this; } 
  775. };
  776. #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
  777. template <class _T>
  778. inline output_iterator_tag 
  779. iterator_category(const ostream_iterator<_T>&) {
  780.   return output_iterator_tag();
  781. }
  782. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  783. __STL_END_NAMESPACE
  784. #endif /* __SGI_STL_INTERNAL_ITERATOR_H */
  785. // Local Variables:
  786. // mode:C++
  787. // End: