home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / libg++-2.7.1-bin.lha / lib / g++-include / iterator.h < prev    next >
C/C++ Source or Header  |  1996-10-12  |  12KB  |  396 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.  
  16. #ifndef ITERATOR_H
  17. #define ITERATOR_H
  18.  
  19. #include <stddef.h>
  20. #include <iostream.h>
  21. #ifndef __GNUG__
  22. #include <bool.h>
  23. #endif
  24. #include <function.h>
  25.  
  26. struct input_iterator_tag {};
  27. struct output_iterator_tag {};
  28. struct forward_iterator_tag {};
  29. struct bidirectional_iterator_tag {};
  30. struct random_access_iterator_tag {};
  31.  
  32. template <class T, class Distance> struct input_iterator {};
  33. struct output_iterator {};
  34. template <class T, class Distance> struct forward_iterator {};
  35. template <class T, class Distance> struct bidirectional_iterator {};
  36. template <class T, class Distance> struct random_access_iterator {};
  37.  
  38. template <class T, class Distance> 
  39. inline input_iterator_tag 
  40. iterator_category(const input_iterator<T, Distance>&) {
  41.     return input_iterator_tag();
  42. }
  43.  
  44. inline output_iterator_tag iterator_category(const output_iterator&) {
  45.     return output_iterator_tag();
  46. }
  47.  
  48. template <class T, class Distance> 
  49. inline forward_iterator_tag
  50. iterator_category(const forward_iterator<T, Distance>&) {
  51.     return forward_iterator_tag();
  52. }
  53.  
  54. template <class T, class Distance> 
  55. inline bidirectional_iterator_tag
  56. iterator_category(const bidirectional_iterator<T, Distance>&) {
  57.     return bidirectional_iterator_tag();
  58. }
  59.  
  60. template <class T, class Distance> 
  61. inline random_access_iterator_tag
  62. iterator_category(const random_access_iterator<T, Distance>&) {
  63.     return random_access_iterator_tag();
  64. }
  65.  
  66. template <class T>
  67. inline random_access_iterator_tag iterator_category(const T*) {
  68.     return random_access_iterator_tag();
  69. }
  70.  
  71. template <class T, class Distance> 
  72. inline T* value_type(const input_iterator<T, Distance>&) {
  73.     return (T*)(0); 
  74. }
  75.  
  76. template <class T, class Distance> 
  77. inline T* value_type(const forward_iterator<T, Distance>&) {
  78.     return (T*)(0);
  79. }
  80.  
  81. template <class T, class Distance> 
  82. inline T* value_type(const bidirectional_iterator<T, Distance>&) {
  83.     return (T*)(0);
  84. }
  85.  
  86. template <class T, class Distance> 
  87. inline T* value_type(const random_access_iterator<T, Distance>&) {
  88.     return (T*)(0);
  89. }
  90.  
  91. template <class T>
  92. inline T* value_type(const T*) { return (T*)(0); }
  93.  
  94. template <class T, class Distance> 
  95. inline Distance* distance_type(const input_iterator<T, Distance>&) {
  96.     return (Distance*)(0);
  97. }
  98.  
  99. template <class T, class Distance> 
  100. inline Distance* distance_type(const forward_iterator<T, Distance>&) {
  101.     return (Distance*)(0);
  102. }
  103.  
  104. template <class T, class Distance> 
  105. inline Distance* 
  106. distance_type(const bidirectional_iterator<T, Distance>&) {
  107.     return (Distance*)(0);
  108. }
  109.  
  110. template <class T, class Distance> 
  111. inline Distance* 
  112. distance_type(const random_access_iterator<T, Distance>&) {
  113.     return (Distance*)(0);
  114. }
  115.  
  116. template <class T>
  117. inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
  118.  
  119. template <class Container>
  120. class back_insert_iterator : public output_iterator {
  121. protected:
  122.     Container& container;
  123. public:
  124.     back_insert_iterator(Container& x) : container(x) {}
  125.     back_insert_iterator<Container>&
  126.     operator=(const Container::value_type& value) { 
  127.     container.push_back(value);
  128.     return *this;
  129.     }
  130.     back_insert_iterator<Container>& operator*() { return *this; }
  131.     back_insert_iterator<Container>& operator++() { return *this; }
  132.     back_insert_iterator<Container>& operator++(int) { return *this; }
  133. };
  134.  
  135. template <class Container>
  136. back_insert_iterator<Container> back_inserter(Container& x) {
  137.     return back_insert_iterator<Container>(x);
  138. }
  139.  
  140. template <class Container>
  141. class front_insert_iterator : public output_iterator {
  142. protected:
  143.     Container& container;
  144. public:
  145.     front_insert_iterator(Container& x) : container(x) {}
  146.     front_insert_iterator<Container>&
  147.     operator=(const Container::value_type& value) { 
  148.     container.push_front(value);
  149.     return *this;
  150.     }
  151.     front_insert_iterator<Container>& operator*() { return *this; }
  152.     front_insert_iterator<Container>& operator++() { return *this; }
  153.     front_insert_iterator<Container>& operator++(int) { return *this; }
  154. };
  155.  
  156. template <class Container>
  157. front_insert_iterator<Container> front_inserter(Container& x) {
  158.     return front_insert_iterator<Container>(x);
  159. }
  160.  
  161. template <class Container>
  162. class insert_iterator : public output_iterator {
  163. protected:
  164.     Container& container;
  165.     Container::iterator iter;
  166. public:
  167.     insert_iterator(Container& x, Container::iterator i) 
  168.     : container(x), iter(i) {}
  169.     insert_iterator<Container>&
  170.     operator=(const Container::value_type& value) { 
  171.     iter = container.insert(iter, value);
  172.     ++iter;
  173.     return *this;
  174.     }
  175.     insert_iterator<Container>& operator*() { return *this; }
  176.     insert_iterator<Container>& operator++() { return *this; }
  177.     insert_iterator<Container>& operator++(int) { return *this; }
  178. };
  179.  
  180. template <class Container, class Iterator>
  181. insert_iterator<Container> inserter(Container& x, Iterator i) {
  182.     return insert_iterator<Container>(x, Container::iterator(i));
  183. }
  184.  
  185. template <class BidirectionalIterator, class T, class Reference, 
  186.           class Distance = ptrdiff_t> 
  187. // Reference = T& 
  188. class reverse_bidirectional_iterator 
  189.     : public bidirectional_iterator<T, Distance> {
  190.     typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
  191.                                            Distance> self;
  192.     friend bool operator==(const self& x, const self& y);
  193. protected:
  194.     BidirectionalIterator current;
  195. public:
  196.     reverse_bidirectional_iterator() {}
  197.     reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {}
  198.     BidirectionalIterator base() { return current; }
  199.     Reference operator*() const {
  200.     BidirectionalIterator tmp = current;
  201.     return *--tmp;
  202.     }
  203.     self& operator++() {
  204.     --current;
  205.     return *this;
  206.     }
  207.     self operator++(int) {
  208.     self tmp = *this;
  209.     --current;
  210.     return tmp;
  211.     }
  212.     self& operator--() {
  213.     ++current;
  214.     return *this;
  215.     }
  216.     self operator--(int) {
  217.     self tmp = *this;
  218.     ++current;
  219.     return tmp;
  220.     }
  221. };
  222.  
  223. template <class BidirectionalIterator, class T, class Reference,
  224.           class Distance>
  225. inline bool operator==(
  226.     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
  227.                                  Distance>& x, 
  228.     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
  229.                                  Distance>& y) {
  230.     return x.current == y.current;
  231. }
  232.  
  233. template <class RandomAccessIterator, class T, class Reference,
  234.           class Distance = ptrdiff_t>
  235. // Reference = T&
  236. class reverse_iterator : public random_access_iterator<T, Distance> {
  237.     typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
  238.     self;
  239.     friend bool operator==(const self& x, const self& y);
  240.     friend bool operator<(const self& x, const self& y);
  241.     friend Distance operator-(const self& x, const self& y);
  242.     friend self operator+(Distance n, const self& x);
  243. protected:
  244.     RandomAccessIterator current;
  245. public:
  246.     reverse_iterator() {}
  247.     reverse_iterator(RandomAccessIterator x) : current(x) {}
  248.     RandomAccessIterator base() { return current; }
  249.     Reference operator*() const { return *(current - 1); }
  250.     self& operator++() {
  251.     --current;
  252.     return *this;
  253.     }
  254.     self operator++(int) {
  255.     self tmp = *this;
  256.     --current;
  257.     return tmp;
  258.     }
  259.     self& operator--() {
  260.     ++current;
  261.     return *this;
  262.     }
  263.     self operator--(int) {
  264.     self tmp = *this;
  265.     ++current;
  266.     return tmp;
  267.     }
  268.     self operator+(Distance n) const {
  269.     return self(current - n);
  270.     }
  271.     self& operator+=(Distance n) {
  272.     current -= n;
  273.     return *this;
  274.     }
  275.     self operator-(Distance n) const {
  276.     return self(current + n);
  277.     }
  278.     self& operator-=(Distance n) {
  279.     current += n;
  280.     return *this;
  281.     }
  282.     Reference operator[](Distance n) { return *(*this + n); }
  283. };
  284.  
  285. template <class RandomAccessIterator, class T, class Reference, class Distance>
  286. inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
  287.                                       Reference, Distance>& x, 
  288.                const reverse_iterator<RandomAccessIterator, T,
  289.                                       Reference, Distance>& y) {
  290.     return x.current == y.current;
  291. }
  292.  
  293. template <class RandomAccessIterator, class T, class Reference, class Distance>
  294. inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
  295.                                      Reference, Distance>& x, 
  296.               const reverse_iterator<RandomAccessIterator, T,
  297.                                      Reference, Distance>& y) {
  298.     return y.current < x.current;
  299. }
  300.  
  301. template <class RandomAccessIterator, class T, class Reference, class Distance>
  302. inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
  303.                                      Reference, Distance>& x, 
  304.               const reverse_iterator<RandomAccessIterator, T,
  305.                                      Reference, Distance>& y) {
  306.     return y.current - x.current;
  307. }
  308.  
  309. template <class RandomAccessIterator, class T, class Reference, class Distance>
  310. inline reverse_iterator<RandomAccessIterator, T, Reference, Distance> 
  311. operator+(Distance n,
  312.       const reverse_iterator<RandomAccessIterator, T, Reference,
  313.                              Distance>& x) {
  314.     return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
  315.     (x.current - n);
  316. }
  317.  
  318.  
  319. template <class OutputIterator, class T>
  320. class raw_storage_iterator : public output_iterator {
  321. protected:
  322.     OutputIterator iter;
  323. public:
  324.     raw_storage_iterator(OutputIterator x) : iter(x) {}
  325.     raw_storage_iterator<OutputIterator, T>& operator*() { return *this; }
  326.     raw_storage_iterator<OutputIterator, T>& operator=(const T& element) {
  327.     construct(iter, element);
  328.     return *this;
  329.     }        
  330.     raw_storage_iterator<OutputIterator, T>& operator++() {
  331.     ++iter;
  332.     return *this;
  333.     }
  334.     raw_storage_iterator<OutputIterator, T> operator++(int) {
  335.     raw_storage_iterator<OutputIterator, T> tmp = *this;
  336.     ++iter;
  337.     return tmp;
  338.     }
  339. };
  340.  
  341.  
  342. template <class T, class Distance = ptrdiff_t>
  343. class istream_iterator : public input_iterator<T, Distance> {
  344. friend bool operator==(const istream_iterator<T, Distance>& x,
  345.                const istream_iterator<T, Distance>& y);
  346. protected:
  347.     istream* stream;
  348.     T value;
  349.     bool end_marker;
  350.     void read() {
  351.     end_marker = (*stream) ? true : false;
  352.     if (end_marker) *stream >> value;
  353.     end_marker = (*stream) ? true : false;
  354.     }
  355. public:
  356.     istream_iterator() : stream(&cin), end_marker(false) {}
  357.     istream_iterator(istream& s) : stream(&s) { read(); }
  358.     const T& operator*() const { return value; }
  359.     istream_iterator<T, Distance>& operator++() { 
  360.     read(); 
  361.     return *this;
  362.     }
  363.     istream_iterator<T, Distance> operator++(int)  {
  364.     istream_iterator<T, Distance> tmp = *this;
  365.     read();
  366.     return tmp;
  367.     }
  368. };
  369.  
  370. template <class T, class Distance>
  371. bool operator==(const istream_iterator<T, Distance>& x,
  372.         const istream_iterator<T, Distance>& y) {
  373.     return x.stream == y.stream && x.end_marker == y.end_marker ||
  374.     x.end_marker == false && y.end_marker == false;
  375. }
  376.  
  377. template <class T>
  378. class ostream_iterator : public output_iterator {
  379. protected:
  380.     ostream* stream;
  381.     char* string;
  382. public:
  383.     ostream_iterator(ostream& s) : stream(&s), string(0) {}
  384.     ostream_iterator(ostream& s, char* c) : stream(&s), string(c)  {}
  385.     ostream_iterator<T>& operator=(const T& value) { 
  386.     *stream << value;
  387.     if (string) *stream << string;
  388.     return *this;
  389.     }
  390.     ostream_iterator<T>& operator*() { return *this; }
  391.     ostream_iterator<T>& operator++() { return *this; } 
  392.     ostream_iterator<T>& operator++(int) { return *this; } 
  393. };
  394.  
  395. #endif
  396.