/* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ #ifndef ITERATOR_H #define ITERATOR_H #include #include #include #include struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag {}; struct bidirectional_iterator_tag {}; struct random_access_iterator_tag {}; /* NON-HP HACK */ template struct input_iterator : public input_iterator_tag {}; struct output_iterator : public output_iterator_tag {}; template struct forward_iterator : public forward_iterator_tag {}; template struct bidirectional_iterator : public bidirectional_iterator_tag {}; template struct random_access_iterator : public random_access_iterator_tag {}; /* NON-HP HACK */ inline input_iterator_tag iterator_category( input_iterator_tag tag ) { return tag ; } inline output_iterator_tag iterator_category( output_iterator_tag tag ) { return tag ; } inline forward_iterator_tag iterator_category( forward_iterator_tag tag ) { return tag ; } inline bidirectional_iterator_tag iterator_category( bidirectional_iterator_tag tag ) { return tag ; } inline random_access_iterator_tag iterator_category( random_access_iterator_tag tag ) { return tag ; } template inline input_iterator_tag iterator_category(const input_iterator&) { return input_iterator_tag(); } inline output_iterator_tag iterator_category(const output_iterator&) { return output_iterator_tag(); } template inline forward_iterator_tag iterator_category(const forward_iterator&) { return forward_iterator_tag(); } template inline bidirectional_iterator_tag iterator_category(const bidirectional_iterator&) { return bidirectional_iterator_tag(); } template inline random_access_iterator_tag iterator_category(const random_access_iterator&) { return random_access_iterator_tag(); } /* NON-HP HACK Altered for Watcom's template-matching rules */ template inline random_access_iterator_tag iterator_category(T*) { return random_access_iterator_tag(); } template inline T* value_type(const input_iterator&) { return (T*)(0); } template inline T* value_type(const forward_iterator&) { return (T*)(0); } template inline T* value_type(const bidirectional_iterator&) { return (T*)(0); } template inline T* value_type(const random_access_iterator&) { return (T*)(0); } /* NON-HP HACK Altered for Watcom's template-matching rules */ template inline T* value_type(T*) { return (T*)(0); } template inline Distance* distance_type(const input_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const forward_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const bidirectional_iterator&) { return (Distance*)(0); } template inline Distance* distance_type(const random_access_iterator&) { return (Distance*)(0); } /* NON-HP HACK Altered for Watcom's template-matching rules */ template inline ptrdiff_t* distance_type(T*) { return (ptrdiff_t*)(0); } template class back_insert_iterator : public output_iterator { protected: Container& container; public: back_insert_iterator(Container& x) : container(x) {} back_insert_iterator& operator=(const Container::value_type& value) { container.push_back(value); return *this; } back_insert_iterator& operator*() { return *this; } back_insert_iterator& operator++() { return *this; } back_insert_iterator& operator++(int) { return *this; } }; template back_insert_iterator back_inserter(Container& x) { return back_insert_iterator(x); } template class front_insert_iterator : public output_iterator { protected: Container& container; public: front_insert_iterator(Container& x) : container(x) {} front_insert_iterator& operator=(const Container::value_type& value) { container.push_front(value); return *this; } front_insert_iterator& operator*() { return *this; } front_insert_iterator& operator++() { return *this; } front_insert_iterator& operator++(int) { return *this; } }; template front_insert_iterator front_inserter(Container& x) { return front_insert_iterator(x); } template class insert_iterator : public output_iterator { protected: Container& container; Container::iterator iter; public: insert_iterator(Container& x, Container::iterator i) : container(x), iter(i) {} insert_iterator& operator=(const Container::value_type& value) { iter = container.insert(iter, value); ++iter; return *this; } insert_iterator& operator*() { return *this; } insert_iterator& operator++() { return *this; } insert_iterator& operator++(int) { return *this; } }; template insert_iterator inserter(Container& x, Iterator i) { return insert_iterator(x, Container::iterator(i)); } template // Reference = T& // Distance = ptrdiff_t class reverse_bidirectional_iterator : public bidirectional_iterator { typedef reverse_bidirectional_iterator self; friend bool operator==(const self& x, const self& y); protected: BidirectionalIterator current; public: reverse_bidirectional_iterator() {} reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {} BidirectionalIterator base() { return current; } Reference operator*() const { BidirectionalIterator tmp = current; return *--tmp; } self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } }; template inline bool operator==( const reverse_bidirectional_iterator& x, const reverse_bidirectional_iterator& y) { return x.current == y.current; } template // Reference = T& // Distance = ptrdiff_t class reverse_iterator : public random_access_iterator { typedef reverse_iterator self; friend bool operator==(const self& x, const self& y); friend bool operator<(const self& x, const self& y); friend Distance operator-(const self& x, const self& y); friend self operator+(Distance n, const self& x); protected: RandomAccessIterator current; public: reverse_iterator() {} reverse_iterator(RandomAccessIterator x) : current(x) {} RandomAccessIterator base() { return current; } Reference operator*() const { return *(current - 1); } self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } self operator+(Distance n) const { return self(current - n); } self& operator+=(Distance n) { current -= n; return *this; } self operator-(Distance n) const { return self(current + n); } self& operator-=(Distance n) { current += n; return *this; } Reference operator[](Distance n) { return *(*this + n); } }; template inline bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return x.current == y.current; } template inline bool operator<(const reverse_iterator& x, const reverse_iterator& y) { return y.current < x.current; } template inline Distance operator-(const reverse_iterator& x, const reverse_iterator& y) { return y.current - x.current; } template inline reverse_iterator operator+(Distance n, const reverse_iterator& x) { return reverse_iterator (x.current - n); } template class raw_storage_iterator : public output_iterator { protected: OutputIterator iter; public: raw_storage_iterator(OutputIterator x) : iter(x) {} raw_storage_iterator& operator*() { return *this; } raw_storage_iterator& operator=(const T& element) { construct(iter, element); return *this; } raw_storage_iterator& operator++() { ++iter; return *this; } raw_storage_iterator operator++(int) { raw_storage_iterator tmp = *this; ++iter; return tmp; } }; template // Distance == ptrdiff_t class istream_iterator : public input_iterator { friend bool operator==(const istream_iterator& x, const istream_iterator& y); protected: istream* stream; T value; bool end_marker; void read() { end_marker = (*stream) ? true : false; if (end_marker) *stream >> value; end_marker = (*stream) ? true : false; } public: istream_iterator() : stream(&cin), end_marker(false) {} istream_iterator(istream& s) : stream(&s) { read(); } const T& operator*() const { return value; } istream_iterator& operator++() { read(); return *this; } istream_iterator operator++(int) { istream_iterator tmp = *this; read(); return tmp; } }; template bool operator==(const istream_iterator& x, const istream_iterator& y) { return x.stream == y.stream && x.end_marker == y.end_marker || x.end_marker == false && y.end_marker == false; } template class ostream_iterator : public output_iterator { protected: ostream* stream; char* string; public: ostream_iterator(ostream& s) : stream(&s), string(0) {} ostream_iterator(ostream& s, char* c) : stream(&s), string(c) {} ostream_iterator& operator=(const T& value) { *stream << value; if (string) *stream << string; return *this; } ostream_iterator& operator*() { return *this; } ostream_iterator& operator++() { return *this; } ostream_iterator& operator++(int) { return *this; } }; #endif