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