# stl_iterator.h

Go to the documentation of this file.

    00001 // Iterators -*- C++ -*-
    00002
    00003 // Copyright (C) 2001, 2002 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 __GLIBCPP_INTERNAL_ITERATOR_H
    00066 #define __GLIBCPP_INTERNAL_ITERATOR_H
    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:
    00111       reverse_iterator() { }
    00112
    00116       explicit
    00117       reverse_iterator(iterator_type __x) : current(__x) { }
    00118
    00122       reverse_iterator(const reverse_iterator& __x)
    00123       : current(__x.current) { }
    00124
    00129       template<typename _Iter>
    00130         reverse_iterator(const reverse_iterator<_Iter>& __x)
    00131     : current(__x.base()) { }
    00132
    00136       iterator_type
    00137       base() const { return current; }
    00138
    00144       reference
    00145       operator*() const
    00146       {
    00147     _Iterator __tmp = current;
    00148     return *--__tmp;
    00149       }
    00150
    00156       pointer
    00157       operator->() const { return &(operator*()); }
    00158
    00164       reverse_iterator&
    00165       operator++()
    00166       {
    00167     --current;
    00168     return *this;
    00169       }
    00170
    00176       reverse_iterator
    00177       operator++(int)
    00178       {
    00179     reverse_iterator __tmp = *this;
    00180     --current;
    00181     return __tmp;
    00182       }
    00183
    00189       reverse_iterator&
    00190       operator--()
    00191       {
    00192     ++current;
    00193     return *this;
    00194       }
    00195
    00201       reverse_iterator operator--(int)
    00202       {
    00203     reverse_iterator __tmp = *this;
    00204     ++current;
    00205     return __tmp;
    00206       }
    00207
    00213       reverse_iterator
    00214       operator+(difference_type __n) const
    00215       { return reverse_iterator(current - __n); }
    00216
    00222       reverse_iterator&
    00223       operator+=(difference_type __n)
    00224       {
    00225     current -= __n;
    00226     return *this;
    00227       }
    00228
    00234       reverse_iterator
    00235       operator-(difference_type __n) const
    00236       { return reverse_iterator(current + __n); }
    00237
    00243       reverse_iterator&
    00244       operator-=(difference_type __n)
    00245       {
    00246     current += __n;
    00247     return *this;
    00248       }
    00249
    00255       reference
    00256       operator[](difference_type __n) const { return *(*this + __n); }
    00257     };
    00258
    00260
    00269   template<typename _Iterator>
    00270     inline bool
    00271     operator==(const reverse_iterator<_Iterator>& __x,
    00272            const reverse_iterator<_Iterator>& __y)
    00273     { return __x.base() == __y.base(); }
    00274
    00275   template<typename _Iterator>
    00276     inline bool
    00277     operator<(const reverse_iterator<_Iterator>& __x,
    00278           const reverse_iterator<_Iterator>& __y)
    00279     { return __y.base() < __x.base(); }
    00280
    00281   template<typename _Iterator>
    00282     inline bool
    00283     operator!=(const reverse_iterator<_Iterator>& __x,
    00284            const reverse_iterator<_Iterator>& __y)
    00285     { return !(__x == __y); }
    00286
    00287   template<typename _Iterator>
    00288     inline bool
    00289     operator>(const reverse_iterator<_Iterator>& __x,
    00290           const reverse_iterator<_Iterator>& __y)
    00291     { return __y < __x; }
    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 !(__x < __y); }
    00304
    00305   template<typename _Iterator>
    00306     inline typename reverse_iterator<_Iterator>::difference_type
    00307     operator-(const reverse_iterator<_Iterator>& __x,
    00308           const reverse_iterator<_Iterator>& __y)
    00309     { return __y.base() - __x.base(); }
    00310
    00311   template<typename _Iterator>
    00312     inline reverse_iterator<_Iterator>
    00313     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
    00314           const reverse_iterator<_Iterator>& __x)
    00315     { return reverse_iterator<_Iterator>(__x.base() - __n); }
    00317
    00318   // 24.4.2.2.1 back_insert_iterator
    00329   template<typename _Container>
    00330     class back_insert_iterator
    00331     : public iterator<output_iterator_tag, void, void, void, void>
    00332     {
    00333     protected:
    00334       _Container* container;
    00335
    00336     public:
    00338       typedef _Container          container_type;
    00339
    00341       explicit
    00342       back_insert_iterator(_Container& __x) : container(&__x) { }
    00343
    00355       back_insert_iterator&
    00356       operator=(typename _Container::const_reference __value)
    00357       {
    00358     container->push_back(__value);
    00359     return *this;
    00360       }
    00361
    00363       back_insert_iterator&
    00364       operator*() { return *this; }
    00365
    00367       back_insert_iterator&
    00368       operator++() { return *this; }
    00369
    00371       back_insert_iterator
    00372       operator++(int) { return *this; }
    00373     };
    00374
    00386   template<typename _Container>
    00387     inline back_insert_iterator<_Container>
    00388     back_inserter(_Container& __x)
    00389     { return back_insert_iterator<_Container>(__x); }
    00390
    00401   template<typename _Container>
    00402     class front_insert_iterator
    00403     : public iterator<output_iterator_tag, void, void, void, void>
    00404     {
    00405     protected:
    00406       _Container* container;
    00407
    00408     public:
    00410       typedef _Container          container_type;
    00411
    00413       explicit front_insert_iterator(_Container& __x) : container(&__x) { }
    00414
    00426       front_insert_iterator&
    00427       operator=(typename _Container::const_reference __value)
    00428       {
    00429     container->push_front(__value);
    00430     return *this;
    00431       }
    00432
    00434       front_insert_iterator&
    00435       operator*() { return *this; }
    00436
    00438       front_insert_iterator&
    00439       operator++() { return *this; }
    00440
    00442       front_insert_iterator
    00443       operator++(int) { return *this; }
    00444     };
    00445
    00457   template<typename _Container>
    00458     inline front_insert_iterator<_Container>
    00459     front_inserter(_Container& __x)
    00460     { return front_insert_iterator<_Container>(__x); }
    00461
    00476   template<typename _Container>
    00477     class insert_iterator
    00478     : public iterator<output_iterator_tag, void, void, void, void>
    00479     {
    00480     protected:
    00481       _Container* container;
    00482       typename _Container::iterator iter;
    00483
    00484     public:
    00486       typedef _Container          container_type;
    00487
    00492       insert_iterator(_Container& __x, typename _Container::iterator __i)
    00493       : container(&__x), iter(__i) {}
    00494
    00518       insert_iterator&
    00519       operator=(const typename _Container::const_reference __value)
    00520       {
    00521     iter = container->insert(iter, __value);
    00522     ++iter;
    00523     return *this;
    00524       }
    00525
    00527       insert_iterator&
    00528       operator*() { return *this; }
    00529
    00531       insert_iterator&
    00532       operator++() { return *this; }
    00533
    00535       insert_iterator&
    00536       operator++(int) { return *this; }
    00537     };
    00538
    00550   template<typename _Container, typename _Iterator>
    00551     inline insert_iterator<_Container>
    00552     inserter(_Container& __x, _Iterator __i)
    00553     {
    00554       return insert_iterator<_Container>(__x,
    00555                      typename _Container::iterator(__i));
    00556     }
    00557 } // namespace std
    00558
    00559 namespace __gnu_cxx
    00560 {
    00561   // This iterator adapter is 'normal' in the sense that it does not
    00562   // change the semantics of any of the operators of its iterator
    00563   // parameter.  Its primary purpose is to convert an iterator that is
    00564   // not a class, e.g. a pointer, into an iterator that is a class.
    00565   // The _Container parameter exists solely so that different containers
    00566   // using this template can instantiate different types, even if the
    00567   // _Iterator parameter is the same.
    00568   using std::iterator_traits;
    00569   using std::iterator;
    00570   template<typename _Iterator, typename _Container>
    00571     class __normal_iterator
    00572       : public iterator<typename iterator_traits<_Iterator>::iterator_category,
    00573                         typename iterator_traits<_Iterator>::value_type,
    00574                         typename iterator_traits<_Iterator>::difference_type,
    00575                         typename iterator_traits<_Iterator>::pointer,
    00576                         typename iterator_traits<_Iterator>::reference>
    00577     {
    00578     protected:
    00579       _Iterator _M_current;
    00580
    00581     public:
    00582       typedef typename iterator_traits<_Iterator>::difference_type
    00583                                        difference_type;
    00584       typedef typename iterator_traits<_Iterator>::reference   reference;
    00585       typedef typename iterator_traits<_Iterator>::pointer     pointer;
    00586
    00587       __normal_iterator() : _M_current(_Iterator()) { }
    00588
    00589       explicit
    00590       __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
    00591
    00592       // Allow iterator to const_iterator conversion
    00593       template<typename _Iter>
    00594       inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
    00595     : _M_current(__i.base()) { }
    00596
    00597       // Forward iterator requirements
    00598       reference
    00599       operator*() const { return *_M_current; }
    00600
    00601       pointer
    00602       operator->() const { return _M_current; }
    00603
    00604       __normal_iterator&
    00605       operator++() { ++_M_current; return *this; }
    00606
    00607       __normal_iterator
    00608       operator++(int) { return __normal_iterator(_M_current++); }
    00609
    00610       // Bidirectional iterator requirements
    00611       __normal_iterator&
    00612       operator--() { --_M_current; return *this; }
    00613
    00614       __normal_iterator
    00615       operator--(int) { return __normal_iterator(_M_current--); }
    00616
    00617       // Random access iterator requirements
    00618       reference
    00619       operator[](const difference_type& __n) const
    00620       { return _M_current[__n]; }
    00621
    00622       __normal_iterator&
    00623       operator+=(const difference_type& __n)
    00624       { _M_current += __n; return *this; }
    00625
    00626       __normal_iterator
    00627       operator+(const difference_type& __n) const
    00628       { return __normal_iterator(_M_current + __n); }
    00629
    00630       __normal_iterator&
    00631       operator-=(const difference_type& __n)
    00632       { _M_current -= __n; return *this; }
    00633
    00634       __normal_iterator
    00635       operator-(const difference_type& __n) const
    00636       { return __normal_iterator(_M_current - __n); }
    00637
    00638       const _Iterator&
    00639       base() const { return _M_current; }
    00640     };
    00641
    00642   // Note: In what follows, the left- and right-hand-side iterators are
    00643   // allowed to vary in types (conceptually in cv-qualification) so that
    00644   // comparaison between cv-qualified and non-cv-qualified iterators be
    00645   // valid.  However, the greedy and unfriendly operators in std::rel_ops
    00646   // will make overload resolution ambiguous (when in scope) if we don't
    00647   // provide overloads whose operands are of the same type.  Can someone
    00648   // remind me what generic programming is about? -- Gaby
    00649
    00650   // Forward iterator requirements
    00651   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00652   inline bool
    00653   operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00654          const __normal_iterator<_IteratorR, _Container>& __rhs)
    00655   { return __lhs.base() == __rhs.base(); }
    00656
    00657   template<typename _Iterator, typename _Container>
    00658   inline bool
    00659   operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
    00660              const __normal_iterator<_Iterator, _Container>& __rhs)
    00661   { return __lhs.base() == __rhs.base(); }
    00662
    00663   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00664   inline bool
    00665   operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00666          const __normal_iterator<_IteratorR, _Container>& __rhs)
    00667   { return __lhs.base() != __rhs.base(); }
    00668
    00669   template<typename _Iterator, typename _Container>
    00670   inline bool
    00671   operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
    00672              const __normal_iterator<_Iterator, _Container>& __rhs)
    00673   { return __lhs.base() != __rhs.base(); }
    00674
    00675   // Random access iterator requirements
    00676   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00677   inline bool
    00678   operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00679         const __normal_iterator<_IteratorR, _Container>& __rhs)
    00680   { return __lhs.base() < __rhs.base(); }
    00681
    00682   template<typename _Iterator, typename _Container>
    00683   inline bool
    00684   operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
    00685              const __normal_iterator<_Iterator, _Container>& __rhs)
    00686   { return __lhs.base() < __rhs.base(); }
    00687
    00688   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00689   inline bool
    00690   operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00691         const __normal_iterator<_IteratorR, _Container>& __rhs)
    00692   { return __lhs.base() > __rhs.base(); }
    00693
    00694   template<typename _Iterator, typename _Container>
    00695   inline bool
    00696   operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
    00697         const __normal_iterator<_Iterator, _Container>& __rhs)
    00698   { return __lhs.base() > __rhs.base(); }
    00699
    00700   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00701   inline bool
    00702   operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00703          const __normal_iterator<_IteratorR, _Container>& __rhs)
    00704   { return __lhs.base() <= __rhs.base(); }
    00705
    00706   template<typename _Iterator, typename _Container>
    00707   inline bool
    00708   operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
    00709          const __normal_iterator<_Iterator, _Container>& __rhs)
    00710   { return __lhs.base() <= __rhs.base(); }
    00711
    00712   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00713   inline bool
    00714   operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00715          const __normal_iterator<_IteratorR, _Container>& __rhs)
    00716   { return __lhs.base() >= __rhs.base(); }
    00717
    00718   template<typename _Iterator, typename _Container>
    00719   inline bool
    00720   operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
    00721          const __normal_iterator<_Iterator, _Container>& __rhs)
    00722   { return __lhs.base() >= __rhs.base(); }
    00723
    00724   // _GLIBCPP_RESOLVE_LIB_DEFECTS
    00725   // According to the resolution of DR179 not only the various comparison
    00726   // operators but also operator- must accept mixed iterator/const_iterator
    00727   // parameters.
    00728   template<typename _IteratorL, typename _IteratorR, typename _Container>
    00729   inline typename __normal_iterator<_IteratorL, _Container>::difference_type
    00730   operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
    00731          const __normal_iterator<_IteratorR, _Container>& __rhs)
    00732   { return __lhs.base() - __rhs.base(); }
    00733
    00734   template<typename _Iterator, typename _Container>
    00735   inline __normal_iterator<_Iterator, _Container>
    00736   operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n,
    00737         const __normal_iterator<_Iterator, _Container>& __i)
    00738   { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
    00739 } // namespace __gnu_cxx
    00740
    00741 #endif
    00742
    00743 // Local Variables:
    00744 // mode:C++
    00745 // End: