/* * * 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. * * * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * 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. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ #ifndef __SGI_STL_ITERATOR_H #define __SGI_STL_ITERATOR_H #include #include #include struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; template struct input_iterator { typedef input_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; struct output_iterator { typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; }; template struct forward_iterator { typedef forward_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; template struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; template struct random_access_iterator { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef T& reference; }; #if 0 template struct iterator { typedef Category iterator_category; typedef T value_type; typedef Distance difference_type; typedef Pointer pointer; typedef Reference reference; }; #endif #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template struct iterator_traits { typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::value_type value_type; typedef typename Iterator::difference_type difference_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; }; template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef const T* pointer; typedef const T& reference; }; template inline iterator_traits::iterator_category iterator_category(const Iterator&) { return iterator_traits::iterator_category(); } template inline iterator_traits::difference_type* distance_type(const Iterator&) { return static_cast::difference_type*>(0); } template inline iterator_traits::value_type* value_type(const Iterator&) { return static_cast::value_type*>(0); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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(); } template inline random_access_iterator_tag iterator_category(const 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); } template inline T* value_type(const 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); } template inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template class back_insert_iterator { protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit back_insert_iterator(Container& x) : container(&x) {} back_insert_iterator& operator=(const typename 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const back_insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline back_insert_iterator back_inserter(Container& x) { return back_insert_iterator(x); } template class front_insert_iterator { protected: Container* container; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit front_insert_iterator(Container& x) : container(&x) {} front_insert_iterator& operator=(const typename 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const front_insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline front_insert_iterator front_inserter(Container& x) { return front_insert_iterator(x); } template class insert_iterator { protected: Container* container; typename Container::iterator iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(Container& x, typename Container::iterator i) : container(&x), iter(i) {} insert_iterator& operator=(const typename 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const insert_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline insert_iterator inserter(Container& x, Iterator i) { typedef typename Container::iterator iter; return insert_iterator(x, iter(i)); } #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_bidirectional_iterator { typedef reverse_bidirectional_iterator self; friend bool operator==(const self& x, const self& y); protected: BidirectionalIterator current; public: typedef bidirectional_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef Reference reference; reverse_bidirectional_iterator() {} explicit reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {} BidirectionalIterator base() { return current; } Reference operator*() const { BidirectionalIterator tmp = current; return *--tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator&) { return bidirectional_iterator_tag(); } template inline T* value_type(const reverse_bidirectional_iterator&) { return (T*) 0; } template inline Distance* distance_type(const reverse_bidirectional_iterator&) { return (Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template inline bool operator==( const reverse_bidirectional_iterator& x, const reverse_bidirectional_iterator& y) { return x.current == y.current; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION // This is the new version of reverse_iterator, as defined in the // draft C++ standard. It relies on the iterator_traits template, // which in turn relies on partial specialization. The class // reverse_bidirectional_iterator is no longer part of the draft // standard, but it is retained for backward compatibility. template class reverse_iterator : public iterator_traits { protected: Iterator current; public: typedef Iterator iterator_type; typedef reverse_iterator self; public: reverse_iterator() {} explicit reverse_iterator(iterator_type x) : current(x) {} reverse_iterator(const self& x) : current(x.current) {} #ifdef __STL_MEMBER_TEMPLATES template reverse_iterator(const reverse_iterator& x) : current(x.current) {} #endif /* __STL_MEMBER_TEMPLATES */ iterator_type base() const { return current; } reference operator*() const { Iterator tmp = current; return *--tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 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+(difference_type n) const { return self(current - n); } self& operator+=(difference_type n) { current -= n; return *this; } self operator-(difference_type n) const { return self(current + n); } self& operator-=(difference_type n) { current += n; return *this; } reference operator[](difference_type n) { return *(*this + n); } }; template inline bool operator==(const reverse_iterator& x, const reverse_iterator& y) { return x.base() == y.base(); } template inline bool operator<(const reverse_iterator& x, const reverse_iterator& y) { return y.base() < x.base(); } template inline reverse_iterator::difference_type operator-(const reverse_iterator& x, const reverse_iterator& y) { return y.base() - x.base(); } template inline reverse_iterator operator+(reverse_iterator::difference_type n, const reverse_iterator& x) { return reverse_iterator(x.base() - n); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // This is the old version of reverse_iterator, as found in the original // HP STL. It does not use partial specialization. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template #else template #endif class reverse_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: typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef T* pointer; typedef Reference reference; reverse_iterator() {} explicit reverse_iterator(RandomAccessIterator x) : current(x) {} RandomAccessIterator base() { return current; } Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ 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 random_access_iterator_tag iterator_category(const reverse_iterator&) { return random_access_iterator_tag(); } template inline T* value_type(const reverse_iterator&) { return (T*) 0; } template inline Distance* distance_type(const reverse_iterator&) { return (Distance*) 0; } 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); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template class raw_storage_iterator { protected: ForwardIterator iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit raw_storage_iterator(ForwardIterator 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const raw_storage_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ template class istream_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: typedef input_iterator_tag iterator_category; typedef T value_type; typedef Distance difference_type; typedef const T* pointer; typedef const T& reference; istream_iterator() : stream(&cin), end_marker(false) {} istream_iterator(istream& s) : stream(&s) { read(); } reference operator*() const { return value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ istream_iterator& operator++() { read(); return *this; } istream_iterator operator++(int) { istream_iterator tmp = *this; read(); return tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline input_iterator_tag iterator_category(const istream_iterator&) { return input_iterator_tag(); } template inline T* value_type(const istream_iterator&) { return (T*) 0; } template inline Distance* distance_type(const istream_iterator&) { return (Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 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 { protected: ostream* stream; const char* string; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream& s) : stream(&s), string(0) {} ostream_iterator(ostream& s, const 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; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION template inline output_iterator_tag iterator_category(const ostream_iterator&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ #endif /* __SGI_STL_ITERATOR_H */