/** -*- C++ -*- ** ** KAI C++ Compiler ** ** Copyright (C) 1996-2001 Intel Corp. All rights reserved. **/ /** ** Lib++ : The Modena C++ Standard Library, ** Version 2.4, October 1997 ** ** Copyright (c) 1995-1997 Modena Software Inc. **/ #ifndef __KAI_ITERATOR #define __KAI_ITERATOR #include #include #include namespace std { // Subclause 24.3.1 -- Standard iterator tags // 24.3.3 Standard Iterator tags struct input_iterator_tag {}; struct output_iterator_tag {}; struct forward_iterator_tag : public input_iterator_tag, public output_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; #if KAI_NONSTD_ITERATOR // Function distance_type is not part of current ANSI draft, but widely used in // previous drafts and the original STL. template inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } #endif /* KAI_NONSTD_ITERATOR */ // 24.3.1 Iterator traits template struct iterator_traits { typedef typename Iterator::value_type value_type; typedef typename Iterator::difference_type difference_type; typedef typename Iterator::pointer pointer; typedef typename Iterator::reference reference; typedef typename Iterator::iterator_category iterator_category; #if KAI_NONSTD_ITERATOR typedef typename Iterator::difference_type distance_type; // non-standard #endif /* KAI_NONSTD_ITERATOR */ }; template struct iterator_traits { typedef ptrdiff_t difference_type; typedef T value_type; typedef T * pointer; typedef T & reference; typedef random_access_iterator_tag iterator_category; #if KAI_NONSTD_ITERATOR typedef ptrdiff_t distance_type; // non-standard #endif /* KAI_NONSTD_ITERATOR */ }; template struct iterator_traits { typedef ptrdiff_t difference_type; typedef T value_type; typedef const T * pointer; typedef const T & reference; typedef random_access_iterator_tag iterator_category; #if KAI_NONSTD_ITERATOR typedef ptrdiff_t distance_type; // non-standard #endif /* KAI_NONSTD_ITERATOR */ }; // 24.3.2 -- Basic iterators template struct iterator { typedef T value_type; typedef Distance difference_type; typedef Pointer pointer; typedef Reference reference; typedef Category iterator_category; #if KAI_NONSTD_ITERATOR typedef Distance distance_type; // non-standard #endif /* KAI_NONSTD_ITERATOR */ }; #if KAI_NONSTD_ITERATOR // These will probably disappear in the future. Use iterator directly. struct output_iterator : public iterator {}; template struct input_iterator : public iterator {}; template struct forward_iterator : public iterator {}; template struct bidirectional_iterator : public iterator {}; template struct random_access_iterator : public iterator {}; #endif /* KAI_NONSTD_ITERATOR */ // 24.3.4 Iterator operations // To make advance and distance more efficient, we use an overloaded function // to automatically select the most efficient version. } // namespace std namespace __kai { template void __advance(Iterator& i, Distance n, std::input_iterator_tag *) { while (n--) ++i; } template void __advance(Iterator& i, Distance n, std::bidirectional_iterator_tag *) { if (n > 0) while (n--) ++i; else while (n++) --i; } template inline void __advance(Iterator& i, Distance n, std::random_access_iterator_tag *) { i += n; } template Distance __distance(Iterator first, Iterator last, std::input_iterator_tag *) { Distance n = 0; while (first != last) { ++first; ++n; } return n; } template inline Distance __distance(Iterator first, Iterator last, std::random_access_iterator_tag *) { return last - first; } } // namespace __kai namespace std { template inline void advance(InputIterator& i, Distance n) { typedef typename iterator_traits ::iterator_category Category; __kai::__advance(i, n, (Category*)0); } template inline typename iterator_traits::difference_type distance(InputIterator first, InputIterator last) { typedef typename iterator_traits::iterator_category Category; typedef typename iterator_traits::difference_type Distance; return __kai::__distance(first, last, (Category*)0); } // Subclause 24.4 -- Predefined iterators // Section 24.4.1 -- Reverse iterators // Subclause 24.4.1.1 -- class reverse_iterator template class reverse_iterator : public iterator::iterator_category, typename iterator_traits::value_type, typename iterator_traits::difference_type, typename iterator_traits::pointer, typename iterator_traits::reference> { protected: Iterator current; public: typedef Iterator iterator_type; typedef typename iterator_traits::difference_type difference_type; typedef typename iterator_traits::reference reference; typedef typename iterator_traits::pointer pointer; reverse_iterator() {} explicit reverse_iterator(Iterator x) : current(x) {} template reverse_iterator(const reverse_iterator& u) : current(u.base()) { } Iterator base() const { return current; } reference operator*() const { Iterator tmp = current; return *--tmp; } pointer operator->() const { return &(operator*()); } reverse_iterator& operator++() { --current; return *this; } reverse_iterator operator++(int) { reverse_iterator tmp = *this; --current; return tmp; } reverse_iterator& operator--() { ++current; return *this; } reverse_iterator operator--(int) { reverse_iterator tmp = *this; ++current; return tmp; } reverse_iterator operator+(difference_type n) const { return reverse_iterator(current - n); } reverse_iterator& operator+=(difference_type n) { current -= n; return *this; } reverse_iterator operator-(difference_type n) const { return reverse_iterator(current+n); } reverse_iterator& operator-=(difference_type n) { current += n; return *this; } reference operator[](difference_type n) const { return current[-n-1]; } }; template inline bool operator==(const reverse_iterator& x, const reverse_iterator& y){ return y.base() == x.base(); } template inline bool operator<(const reverse_iterator& x, const reverse_iterator& y){ return y.base() < x.base(); } template inline bool operator!=(const reverse_iterator& x, const reverse_iterator& y){ return y.base() != x.base(); } template inline bool operator>(const reverse_iterator& x, const reverse_iterator& y){ return y.base() > x.base(); } template inline bool operator>=(const reverse_iterator& x, const reverse_iterator& y){ return y.base() >= x.base(); } template inline bool operator<=(const reverse_iterator& x, const reverse_iterator& y){ return y.base() <= x.base(); } template typename reverse_iterator::difference_type operator-(const reverse_iterator& x, const reverse_iterator& y) { return y.base() - x.base(); } template reverse_iterator operator+(typename reverse_iterator::difference_type n, reverse_iterator& x) { return reverse_iterator(x.base() - n); } //---------------------------------------- // Subclause 24.4.2 -- Insert iterators //---------------------------------------- // Section 24.4.2.1 -- class back_insert_iterator template class back_insert_iterator : public iterator { protected: Container * container; public: typedef Container container_type; explicit back_insert_iterator(Container& x) : container(&x) {} back_insert_iterator& operator=(typename Container::const_reference 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 inline back_insert_iterator back_inserter(Container& x) { return back_insert_iterator(x); } // Section 24.4.2.3 -- class front_insert_iterator template class front_insert_iterator : public iterator { protected: Container * container; public: typedef Container container_type; explicit front_insert_iterator(Container& x) : container (&x) {} front_insert_iterator& operator=(typename Container::const_reference 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 inline front_insert_iterator front_inserter(Container& x) { return front_insert_iterator(x); } // Section 24.4.2.5 -- class insert_iterator template class insert_iterator : public iterator { protected: Container * container; typename Container::iterator iter; public: typedef Container container_type; insert_iterator(Container& x, typename Container::iterator i) : container(&x), iter(i) {} insert_iterator&operator=(typename Container::const_reference 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 inline insert_iterator inserter(Container& x, Iterator i) { return insert_iterator(x, Container::iterator(i)); } //-------------------------------------------------------------------------------- // 24.5 Stream iterators //-------------------------------------------------------------------------------- // 24.5 istream_iterator template , class Distance = ptrdiff_t> class istream_iterator : public iterator { friend bool operator==(const istream_iterator& x, const istream_iterator& y); public: typedef charT char_type; typedef traits traits_type; typedef basic_istream istream_type; istream_iterator() : in_stream(NULL) {} istream_iterator(istream_type& s) : in_stream(&s) { read(); } istream_iterator(const istream_iterator& x) : in_stream(x.in_stream), value(x.value) {} const T& operator*() const { return value; } const T* operator->() const { return &(operator*()); } istream_iterator& operator++() { read(); return *this; } istream_iterator operator++(int) { istream_iterator tmp = *this; read(); return tmp; } private: istream_type* in_stream; T value; void read() { if (in_stream) { __KAI_LOCK_STREAM(*in_stream); if (!*in_stream || !(*in_stream >> value)) in_stream = NULL; } } }; template inline bool operator==(const istream_iterator& x, const istream_iterator& y) { return x.in_stream == y.in_stream; } template inline bool operator!=(const istream_iterator& x, const istream_iterator& y) { return !(x == y); } //24.5.2 ostream_iterator template > class ostream_iterator : public iterator { public: typedef charT char_type; typedef traits traits_type; typedef basic_ostream ostream_type; ostream_iterator(ostream_type& s) : out_stream(&s), delim(0) {} ostream_iterator(ostream_type& s, const charT* delimiter) : out_stream(&s), delim(delimiter) {} ostream_iterator(const ostream_iterator& x) : out_stream(x.out_stream), delim (x.delim) {} ostream_iterator& operator=(const T& value) { __KAI_LOCK_STREAM(*out_stream); *out_stream << value; if (delim) *out_stream << delim; return *this; } ostream_iterator& operator*() { return *this; } ostream_iterator& operator++() { return *this; } ostream_iterator& operator++(int) { return *this; } private: ostream_type* out_stream; const charT* delim; }; // 24.5.3 istreambuf_iterator template < class charT, class traits = char_traits > class istreambuf_iterator : public iterator { public: typedef charT char_type; typedef traits traits_type; typedef typename traits::int_type int_type; typedef basic_streambuf streambuf_type; typedef basic_istream istream_type; #if KAI_NONSTD_ITERATOR typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; #endif /* KAI_NONSTD_ITERATOR */ class proxy { charT data; streambuf_type *sbuf; proxy(charT c, streambuf_type *s): data(c), sbuf(s){} public: charT operator*(){return data; } friend class istreambuf_iterator; }; istreambuf_iterator() MSIPL_THROW : sbuf(0), data(traits::eof ()) { } istreambuf_iterator(istream_type& is) MSIPL_THROW : sbuf(is.rdbuf()) { __kai_peek_char(); } istreambuf_iterator(streambuf_type* sb) MSIPL_THROW : sbuf(sb) { __kai_peek_char(); } istreambuf_iterator(const proxy& p) MSIPL_THROW : sbuf(p.sbuf), data(p.data) {} inline char_type operator*() const { return data; } istreambuf_iterator& operator++() { // It is undefined if the user calls this when it is in the end-of-stream condition. traits::int_type c = sbuf->snextc(); data=traits::to_char_type(c); if (traits::eq_int_type(c, traits::eof())) sbuf=NULL; return *this; } proxy operator++(int) { // It is undefined if the user calls this when it is in the end-of-stream condition. proxy prev(data, sbuf); traits::int_type c = sbuf->snextc(); data=traits::to_char_type(c); if (traits::eq_int_type(c, traits::eof())) sbuf=NULL; return prev; } inline bool equal(const istreambuf_iterator& b) const { return ((sbuf == 0) == (b.sbuf == 0)); } private: streambuf_type* sbuf; charT data; void __kai_peek_char() { traits::int_type c; if (sbuf==NULL || traits::eq_int_type((c=sbuf->sgetc()), traits::eof())) { sbuf=NULL; data=traits::eof(); } else { data=traits::to_char_type(c); } } }; template inline bool operator==(const istreambuf_iterator& a, const istreambuf_iterator& b) { return a.equal(b); } template inline bool operator!=(const istreambuf_iterator& a, const istreambuf_iterator& b) { return !a.equal(b); } // 24.5.4 ostreambuf_iterator template > class ostreambuf_iterator : public iterator { public: typedef charT char_type; typedef traits traits_type; typedef basic_ostream ostream_type; typedef basic_streambuf streambuf_type; #if KAI_NONSTD_ITERATOR typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; #endif /* KAI_NONSTD_ITERATOR */ ostreambuf_iterator(ostream_type& s) MSIPL_THROW : sbuf(s.rdbuf()) {} ostreambuf_iterator(streambuf_type* s) MSIPL_THROW : sbuf(s) {} ostreambuf_iterator& operator*() { return *this; } ostreambuf_iterator& operator++() { return *this; } ostreambuf_iterator& operator++(int) { return *this; } ostreambuf_iterator& operator=(char_type c) { if (sbuf && traits::eq_int_type(sbuf->sputc(c), traits::eof())) sbuf = 0; return *this; } bool failed() const MSIPL_THROW { return !sbuf; } private: streambuf_type* sbuf; }; #if KAI_NONSTD_ITERATOR // reverse_bidirectional_iterator // This will go away in future versions of the library. // Use reverse_iterator instead. template ::value_type&, class Reference = T&, class Pointer = T*, class Distance = ptrdiff_t> class reverse_bidirectional_iterator : public iterator { typedef reverse_bidirectional_iterator self; friend bool operator==(const self& x, const self& y); protected: BidirectionalIterator current; public: reverse_bidirectional_iterator() {} explicit reverse_bidirectional_iterator (BidirectionalIterator x) : current (x) {} BidirectionalIterator base() const { return current; } Reference operator*() const { BidirectionalIterator tmp = current; return *--tmp; } // // Waiting for clarifications on this // // Pointer operator-> () const { return & (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; } }; template inline bool operator==( const reverse_bidirectional_iterator& x, const reverse_bidirectional_iterator& y) { return x.current == y.current; } #endif /* KAI_NONSTD_ITERATOR */ } // namespace std #endif /* __KAI_ITERATOR */