stl_iterator.h

Go to the documentation of this file.
00001 // Iterators -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /*
00031  *
00032  * Copyright (c) 1994
00033  * Hewlett-Packard Company
00034  *
00035  * Permission to use, copy, modify, distribute and sell this software
00036  * and its documentation for any purpose is hereby granted without fee,
00037  * provided that the above copyright notice appear in all copies and
00038  * that both that copyright notice and this permission notice appear
00039  * in supporting documentation.  Hewlett-Packard Company makes no
00040  * representations about the suitability of this software for any
00041  * purpose.  It is provided "as is" without express or implied warranty.
00042  *
00043  *
00044  * Copyright (c) 1996-1998
00045  * Silicon Graphics Computer Systems, Inc.
00046  *
00047  * Permission to use, copy, modify, distribute and sell this software
00048  * and its documentation for any purpose is hereby granted without fee,
00049  * provided that the above copyright notice appear in all copies and
00050  * that both that copyright notice and this permission notice appear
00051  * in supporting documentation.  Silicon Graphics makes no
00052  * representations about the suitability of this software for any
00053  * purpose.  It is provided "as is" without express or implied warranty.
00054  */
00055 
00065 #ifndef _ITERATOR_H
00066 #define _ITERATOR_H 1
00067 
00068 namespace std
00069 {
00070   // 24.4.1 Reverse iterators
00089   template<typename _Iterator>
00090     class reverse_iterator
00091     : public iterator<typename iterator_traits<_Iterator>::iterator_category,
00092               typename iterator_traits<_Iterator>::value_type,
00093               typename iterator_traits<_Iterator>::difference_type,
00094               typename iterator_traits<_Iterator>::pointer,
00095                       typename iterator_traits<_Iterator>::reference>
00096     {
00097     protected:
00098       _Iterator current;
00099 
00100     public:
00101       typedef _Iterator                        iterator_type;
00102       typedef typename iterator_traits<_Iterator>::difference_type
00103                                    difference_type;
00104       typedef typename iterator_traits<_Iterator>::reference   reference;
00105       typedef typename iterator_traits<_Iterator>::pointer     pointer;
00106 
00107     public:
00112       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00113       // 235 No specification of default ctor for reverse_iterator
00114       reverse_iterator() : current() { }
00115 
00119       explicit
00120       reverse_iterator(iterator_type __x) : current(__x) { }
00121 
00125       reverse_iterator(const reverse_iterator& __x)
00126       : current(__x.current) { }
00127 
00132       template<typename _Iter>
00133         reverse_iterator(const reverse_iterator<_Iter>& __x)
00134     : current(__x.base()) { }
00135 
00139       iterator_type
00140       base() const
00141       { return current; }
00142 
00148       reference
00149       operator*() const
00150       {
00151     _Iterator __tmp = current;
00152     return *--__tmp;
00153       }
00154 
00160       pointer
00161       operator->() const
00162       { return &(operator*()); }
00163 
00169       reverse_iterator&
00170       operator++()
00171       {
00172     --current;
00173     return *this;
00174       }
00175 
00181       reverse_iterator
00182       operator++(int)
00183       {
00184     reverse_iterator __tmp = *this;
00185     --current;
00186     return __tmp;
00187       }
00188 
00194       reverse_iterator&
00195       operator--()
00196       {
00197     ++current;
00198     return *this;
00199       }
00200 
00206       reverse_iterator operator--(int)
00207       {
00208     reverse_iterator __tmp = *this;
00209     ++current;
00210     return __tmp;
00211       }
00212 
00218       reverse_iterator
00219       operator+(difference_type __n) const
00220       { return reverse_iterator(current - __n); }
00221 
00227       reverse_iterator&
00228       operator+=(difference_type __n)
00229       {
00230     current -= __n;
00231     return *this;
00232       }
00233 
00239       reverse_iterator
00240       operator-(difference_type __n) const
00241       { return reverse_iterator(current + __n); }
00242 
00248       reverse_iterator&
00249       operator-=(difference_type __n)
00250       {
00251     current += __n;
00252     return *this;
00253       }
00254 
00260       reference
00261       operator[](difference_type __n) const
00262       { return *(*this + __n); }
00263     };
00264 
00266 
00275   template<typename _Iterator>
00276     inline bool
00277     operator==(const reverse_iterator<_Iterator>& __x,
00278            const reverse_iterator<_Iterator>& __y)
00279     { return __x.base() == __y.base(); }
00280 
00281   template<typename _Iterator>
00282     inline bool
00283     operator<(const reverse_iterator<_Iterator>& __x,
00284           const reverse_iterator<_Iterator>& __y)
00285     { return __y.base() < __x.base(); }
00286 
00287   template<typename _Iterator>
00288     inline bool
00289     operator!=(const reverse_iterator<_Iterator>& __x,
00290            const reverse_iterator<_Iterator>& __y)
00291     { return !(__x == __y); }
00292 
00293   template<typename _Iterator>
00294     inline bool
00295     operator>(const reverse_iterator<_Iterator>& __x,
00296           const reverse_iterator<_Iterator>& __y)
00297     { return __y < __x; }
00298 
00299   template<typename _Iterator>
00300     inline bool
00301     operator<=(const reverse_iterator<_Iterator>& __x,
00302         const reverse_iterator<_Iterator>& __y)
00303     { return !(__y < __x); }
00304 
00305   template<typename _Iterator>
00306     inline bool
00307     operator>=(const reverse_iterator<_Iterator>& __x,
00308            const reverse_iterator<_Iterator>& __y)
00309     { return !(__x < __y); }
00310 
00311   template<typename _Iterator>
00312     inline typename reverse_iterator<_Iterator>::difference_type
00313     operator-(const reverse_iterator<_Iterator>& __x,
00314           const reverse_iterator<_Iterator>& __y)
00315     { return __y.base() - __x.base(); }
00316 
00317   template<typename _Iterator>
00318     inline reverse_iterator<_Iterator>
00319     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
00320           const reverse_iterator<_Iterator>& __x)
00321     { return reverse_iterator<_Iterator>(__x.base() - __n); }
00323 
00324   // 24.4.2.2.1 back_insert_iterator
00335   template<typename _Container>
00336     class back_insert_iterator
00337     : public iterator<output_iterator_tag, void, void, void, void>
00338     {
00339     protected:
00340       _Container* container;
00341 
00342     public:
00344       typedef _Container          container_type;
00345 
00347       explicit
00348       back_insert_iterator(_Container& __x) : container(&__x) { }
00349 
00361       back_insert_iterator&
00362       operator=(typename _Container::const_reference __value)
00363       {
00364     container->push_back(__value);
00365     return *this;
00366       }
00367 
00369       back_insert_iterator&
00370       operator*()
00371       { return *this; }
00372 
00374       back_insert_iterator&
00375       operator++()
00376       { return *this; }
00377 
00379       back_insert_iterator
00380       operator++(int)
00381       { return *this; }
00382     };
00383 
00395   template<typename _Container>
00396     inline back_insert_iterator<_Container>
00397     back_inserter(_Container& __x)
00398     { return back_insert_iterator<_Container>(__x); }
00399 
00410   template<typename _Container>
00411     class front_insert_iterator
00412     : public iterator<output_iterator_tag, void, void, void, void>
00413     {
00414     protected:
00415       _Container* container;
00416 
00417     public:
00419       typedef _Container          container_type;
00420 
00422       explicit front_insert_iterator(_Container& __x) : container(&__x) { }
00423 
00435       front_insert_iterator&
00436       operator=(typename _Container::const_reference __value)
00437       {
00438     container->push_front(__value);
00439     return *this;
00440       }
00441 
00443       front_insert_iterator&
00444       operator*()
00445       { return *this; }
00446 
00448       front_insert_iterator&
00449       operator++()
00450       { return *this; }
00451 
00453       front_insert_iterator
00454       operator++(int)
00455       { return *this; }
00456     };
00457 
00469   template<typename _Container>
00470     inline front_insert_iterator<_Container>
00471     front_inserter(_Container& __x)
00472     { return front_insert_iterator<_Container>(__x); }
00473 
00488   template<typename _Container>
00489     class insert_iterator
00490     : public iterator<output_iterator_tag, void, void, void, void>
00491     {
00492     protected:
00493       _Container* container;
00494       typename _Container::iterator iter;
00495 
00496     public:
00498       typedef _Container          container_type;
00499 
00504       insert_iterator(_Container& __x, typename _Container::iterator __i)
00505       : container(&__x), iter(__i) {}
00506 
00530       insert_iterator&
00531       operator=(const typename _Container::const_reference __value)
00532       {
00533     iter = container->insert(iter, __value);
00534     ++iter;
00535     return *this;
00536       }
00537 
00539       insert_iterator&
00540       operator*()
00541       { return *this; }
00542 
00544       insert_iterator&
00545       operator++()
00546       { return *this; }
00547 
00549       insert_iterator&
00550       operator++(int)
00551       { return *this; }
00552     };
00553 
00565   template<typename _Container, typename _Iterator>
00566     inline insert_iterator<_Container>
00567     inserter(_Container& __x, _Iterator __i)
00568     {
00569       return insert_iterator<_Container>(__x,
00570                      typename _Container::iterator(__i));
00571     }
00572 } // namespace std
00573 
00574 namespace __gnu_cxx
00575 {
00576   // This iterator adapter is 'normal' in the sense that it does not
00577   // change the semantics of any of the operators of its iterator
00578   // parameter.  Its primary purpose is to convert an iterator that is
00579   // not a class, e.g. a pointer, into an iterator that is a class.
00580   // The _Container parameter exists solely so that different containers
00581   // using this template can instantiate different types, even if the
00582   // _Iterator parameter is the same.
00583   using std::iterator_traits;
00584   using std::iterator;
00585   template<typename _Iterator, typename _Container>
00586     class __normal_iterator
00587     {
00588     protected:
00589       _Iterator _M_current;
00590 
00591     public:
00592       typedef typename iterator_traits<_Iterator>::iterator_category
00593                                                              iterator_category;
00594       typedef typename iterator_traits<_Iterator>::value_type  value_type;
00595       typedef typename iterator_traits<_Iterator>::difference_type
00596                                                              difference_type;
00597       typedef typename iterator_traits<_Iterator>::reference reference;
00598       typedef typename iterator_traits<_Iterator>::pointer   pointer;
00599 
00600       __normal_iterator() : _M_current(_Iterator()) { }
00601 
00602       explicit
00603       __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
00604 
00605       // Allow iterator to const_iterator conversion
00606       template<typename _Iter>
00607         inline __normal_iterator(const __normal_iterator<_Iter,
00608                  _Container>& __i)
00609     : _M_current(__i.base()) { }
00610 
00611       // Forward iterator requirements
00612       reference
00613       operator*() const
00614       { return *_M_current; }
00615 
00616       pointer
00617       operator->() const
00618       { return _M_current; }
00619 
00620       __normal_iterator&
00621       operator++()
00622       {
00623     ++_M_current;
00624     return *this;
00625       }
00626 
00627       __normal_iterator
00628       operator++(int)
00629       { return __normal_iterator(_M_current++); }
00630 
00631       // Bidirectional iterator requirements
00632       __normal_iterator&
00633       operator--()
00634       {
00635     --_M_current;
00636     return *this;
00637       }
00638 
00639       __normal_iterator
00640       operator--(int)
00641       { return __normal_iterator(_M_current--); }
00642 
00643       // Random access iterator requirements
00644       reference
00645       operator[](const difference_type& __n) const
00646       { return _M_current[__n]; }
00647 
00648       __normal_iterator&
00649       operator+=(const difference_type& __n)
00650       { _M_current += __n; return *this; }
00651 
00652       __normal_iterator
00653       operator+(const difference_type& __n) const
00654       { return __normal_iterator(_M_current + __n); }
00655 
00656       __normal_iterator&
00657       operator-=(const difference_type& __n)
00658       { _M_current -= __n; return *this; }
00659 
00660       __normal_iterator
00661       operator-(const difference_type& __n) const
00662       { return __normal_iterator(_M_current - __n); }
00663 
00664       const _Iterator&
00665       base() const
00666       { return _M_current; }
00667     };
00668 
00669   // Note: In what follows, the left- and right-hand-side iterators are
00670   // allowed to vary in types (conceptually in cv-qualification) so that
00671   // comparaison between cv-qualified and non-cv-qualified iterators be
00672   // valid.  However, the greedy and unfriendly operators in std::rel_ops
00673   // will make overload resolution ambiguous (when in scope) if we don't
00674   // provide overloads whose operands are of the same type.  Can someone
00675   // remind me what generic programming is about? -- Gaby
00676 
00677   // Forward iterator requirements
00678   template<typename _IteratorL, typename _IteratorR, typename _Container>
00679     inline bool
00680     operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
00681            const __normal_iterator<_IteratorR, _Container>& __rhs)
00682     { return __lhs.base() == __rhs.base(); }
00683 
00684   template<typename _Iterator, typename _Container>
00685     inline bool
00686     operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
00687            const __normal_iterator<_Iterator, _Container>& __rhs)
00688     { return __lhs.base() == __rhs.base(); }
00689 
00690   template<typename _IteratorL, typename _IteratorR, typename _Container>
00691     inline bool
00692     operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00693            const __normal_iterator<_IteratorR, _Container>& __rhs)
00694     { return __lhs.base() != __rhs.base(); }
00695 
00696   template<typename _Iterator, typename _Container>
00697     inline bool
00698     operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
00699            const __normal_iterator<_Iterator, _Container>& __rhs)
00700     { return __lhs.base() != __rhs.base(); }
00701 
00702   // Random access iterator requirements
00703   template<typename _IteratorL, typename _IteratorR, typename _Container>
00704     inline bool
00705     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
00706           const __normal_iterator<_IteratorR, _Container>& __rhs)
00707     { return __lhs.base() < __rhs.base(); }
00708 
00709   template<typename _Iterator, typename _Container>
00710     inline bool
00711     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
00712           const __normal_iterator<_Iterator, _Container>& __rhs)
00713     { return __lhs.base() < __rhs.base(); }
00714 
00715   template<typename _IteratorL, typename _IteratorR, typename _Container>
00716     inline bool
00717     operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
00718           const __normal_iterator<_IteratorR, _Container>& __rhs)
00719     { return __lhs.base() > __rhs.base(); }
00720 
00721   template<typename _Iterator, typename _Container>
00722     inline bool
00723     operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
00724           const __normal_iterator<_Iterator, _Container>& __rhs)
00725     { return __lhs.base() > __rhs.base(); }
00726 
00727   template<typename _IteratorL, typename _IteratorR, typename _Container>
00728     inline bool
00729     operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00730            const __normal_iterator<_IteratorR, _Container>& __rhs)
00731     { return __lhs.base() <= __rhs.base(); }
00732 
00733   template<typename _Iterator, typename _Container>
00734     inline bool
00735     operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
00736            const __normal_iterator<_Iterator, _Container>& __rhs)
00737     { return __lhs.base() <= __rhs.base(); }
00738 
00739   template<typename _IteratorL, typename _IteratorR, typename _Container>
00740     inline bool
00741     operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00742            const __normal_iterator<_IteratorR, _Container>& __rhs)
00743     { return __lhs.base() >= __rhs.base(); }
00744 
00745   template<typename _Iterator, typename _Container>
00746     inline bool
00747     operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
00748            const __normal_iterator<_Iterator, _Container>& __rhs)
00749     { return __lhs.base() >= __rhs.base(); }
00750 
00751   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00752   // According to the resolution of DR179 not only the various comparison
00753   // operators but also operator- must accept mixed iterator/const_iterator
00754   // parameters.
00755   template<typename _IteratorL, typename _IteratorR, typename _Container>
00756     inline typename __normal_iterator<_IteratorL, _Container>::difference_type
00757     operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
00758           const __normal_iterator<_IteratorR, _Container>& __rhs)
00759     { return __lhs.base() - __rhs.base(); }
00760 
00761   template<typename _Iterator, typename _Container>
00762     inline __normal_iterator<_Iterator, _Container>
00763     operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
00764           __n, const __normal_iterator<_Iterator, _Container>& __i)
00765     { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
00766 } // namespace __gnu_cxx
00767 
00768 #endif
00769 
00770 // Local Variables:
00771 // mode:C++
00772 // End:

Generated on Tue Jan 30 17:31:54 2007 for GNU C++ STL by doxygen 1.3.6