stl_iterator.h

Go to the documentation of this file.
00001 // Iterators -*- C++ -*-
00002 
00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 
00056 /** @file stl_iterator.h
00057  *  This is an internal header file, included by other library headers.
00058  *  You should not attempt to use it directly.
00059  *
00060  *  This file implements reverse_iterator, back_insert_iterator,
00061  *  front_insert_iterator, insert_iterator, __normal_iterator, and their
00062  *  supporting functions and overloaded operators.
00063  */
00064 
00065 #ifndef _ITERATOR_H
00066 #define _ITERATOR_H 1
00067 
00068 #include <bits/cpp_type_traits.h>
00069 
00070 namespace std
00071 {
00072   // 24.4.1 Reverse iterators
00073   /**
00074    *  "Bidirectional and random access iterators have corresponding reverse
00075    *  %iterator adaptors that iterate through the data structure in the
00076    *  opposite direction.  They have the same signatures as the corresponding
00077    *  iterators.  The fundamental relation between a reverse %iterator and its
00078    *  corresponding %iterator @c i is established by the identity:
00079    *  @code
00080    *      &*(reverse_iterator(i)) == &*(i - 1)
00081    *  @endcode
00082    *
00083    *  This mapping is dictated by the fact that while there is always a
00084    *  pointer past the end of an array, there might not be a valid pointer
00085    *  before the beginning of an array." [24.4.1]/1,2
00086    *
00087    *  Reverse iterators can be tricky and surprising at first.  Their
00088    *  semantics make sense, however, and the trickiness is a side effect of
00089    *  the requirement that the iterators must be safe.
00090   */
00091   template<typename _Iterator>
00092     class reverse_iterator
00093     : public iterator<typename iterator_traits<_Iterator>::iterator_category,
00094               typename iterator_traits<_Iterator>::value_type,
00095               typename iterator_traits<_Iterator>::difference_type,
00096               typename iterator_traits<_Iterator>::pointer,
00097                       typename iterator_traits<_Iterator>::reference>
00098     {
00099     protected:
00100       _Iterator current;
00101 
00102     public:
00103       typedef _Iterator                        iterator_type;
00104       typedef typename iterator_traits<_Iterator>::difference_type
00105                                    difference_type;
00106       typedef typename iterator_traits<_Iterator>::reference   reference;
00107       typedef typename iterator_traits<_Iterator>::pointer     pointer;
00108 
00109     public:
00110       /**
00111        *  The default constructor default-initializes member @p current.
00112        *  If it is a pointer, that means it is zero-initialized.
00113       */
00114       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00115       // 235 No specification of default ctor for reverse_iterator
00116       reverse_iterator() : current() { }
00117 
00118       /**
00119        *  This %iterator will move in the opposite direction that @p x does.
00120       */
00121       explicit
00122       reverse_iterator(iterator_type __x) : current(__x) { }
00123 
00124       /**
00125        *  The copy constructor is normal.
00126       */
00127       reverse_iterator(const reverse_iterator& __x)
00128       : current(__x.current) { }
00129 
00130       /**
00131        *  A reverse_iterator across other types can be copied in the normal
00132        *  fashion.
00133       */
00134       template<typename _Iter>
00135         reverse_iterator(const reverse_iterator<_Iter>& __x)
00136     : current(__x.base()) { }
00137 
00138       /**
00139        *  @return  @c current, the %iterator used for underlying work.
00140       */
00141       iterator_type
00142       base() const
00143       { return current; }
00144 
00145       /**
00146        *  @return  TODO
00147        *
00148        *  @doctodo
00149       */
00150       reference
00151       operator*() const
00152       {
00153     _Iterator __tmp = current;
00154     return *--__tmp;
00155       }
00156 
00157       /**
00158        *  @return  TODO
00159        *
00160        *  @doctodo
00161       */
00162       pointer
00163       operator->() const
00164       { return &(operator*()); }
00165 
00166       /**
00167        *  @return  TODO
00168        *
00169        *  @doctodo
00170       */
00171       reverse_iterator&
00172       operator++()
00173       {
00174     --current;
00175     return *this;
00176       }
00177 
00178       /**
00179        *  @return  TODO
00180        *
00181        *  @doctodo
00182       */
00183       reverse_iterator
00184       operator++(int)
00185       {
00186     reverse_iterator __tmp = *this;
00187     --current;
00188     return __tmp;
00189       }
00190 
00191       /**
00192        *  @return  TODO
00193        *
00194        *  @doctodo
00195       */
00196       reverse_iterator&
00197       operator--()
00198       {
00199     ++current;
00200     return *this;
00201       }
00202 
00203       /**
00204        *  @return  TODO
00205        *
00206        *  @doctodo
00207       */
00208       reverse_iterator
00209       operator--(int)
00210       {
00211     reverse_iterator __tmp = *this;
00212     ++current;
00213     return __tmp;
00214       }
00215 
00216       /**
00217        *  @return  TODO
00218        *
00219        *  @doctodo
00220       */
00221       reverse_iterator
00222       operator+(difference_type __n) const
00223       { return reverse_iterator(current - __n); }
00224 
00225       /**
00226        *  @return  TODO
00227        *
00228        *  @doctodo
00229       */
00230       reverse_iterator&
00231       operator+=(difference_type __n)
00232       {
00233     current -= __n;
00234     return *this;
00235       }
00236 
00237       /**
00238        *  @return  TODO
00239        *
00240        *  @doctodo
00241       */
00242       reverse_iterator
00243       operator-(difference_type __n) const
00244       { return reverse_iterator(current + __n); }
00245 
00246       /**
00247        *  @return  TODO
00248        *
00249        *  @doctodo
00250       */
00251       reverse_iterator&
00252       operator-=(difference_type __n)
00253       {
00254     current += __n;
00255     return *this;
00256       }
00257 
00258       /**
00259        *  @return  TODO
00260        *
00261        *  @doctodo
00262       */
00263       reference
00264       operator[](difference_type __n) const
00265       { return *(*this + __n); }
00266     };
00267 
00268   //@{
00269   /**
00270    *  @param  x  A %reverse_iterator.
00271    *  @param  y  A %reverse_iterator.
00272    *  @return  A simple bool.
00273    *
00274    *  Reverse iterators forward many operations to their underlying base()
00275    *  iterators.  Others are implemented in terms of one another.
00276    *
00277   */
00278   template<typename _Iterator>
00279     inline bool
00280     operator==(const reverse_iterator<_Iterator>& __x,
00281            const reverse_iterator<_Iterator>& __y)
00282     { return __x.base() == __y.base(); }
00283 
00284   template<typename _Iterator>
00285     inline bool
00286     operator<(const reverse_iterator<_Iterator>& __x,
00287           const reverse_iterator<_Iterator>& __y)
00288     { return __y.base() < __x.base(); }
00289 
00290   template<typename _Iterator>
00291     inline bool
00292     operator!=(const reverse_iterator<_Iterator>& __x,
00293            const reverse_iterator<_Iterator>& __y)
00294     { return !(__x == __y); }
00295 
00296   template<typename _Iterator>
00297     inline bool
00298     operator>(const reverse_iterator<_Iterator>& __x,
00299           const reverse_iterator<_Iterator>& __y)
00300     { return __y < __x; }
00301 
00302   template<typename _Iterator>
00303     inline bool
00304     operator<=(const reverse_iterator<_Iterator>& __x,
00305            const reverse_iterator<_Iterator>& __y)
00306     { return !(__y < __x); }
00307 
00308   template<typename _Iterator>
00309     inline bool
00310     operator>=(const reverse_iterator<_Iterator>& __x,
00311            const reverse_iterator<_Iterator>& __y)
00312     { return !(__x < __y); }
00313 
00314   template<typename _Iterator>
00315     inline typename reverse_iterator<_Iterator>::difference_type
00316     operator-(const reverse_iterator<_Iterator>& __x,
00317           const reverse_iterator<_Iterator>& __y)
00318     { return __y.base() - __x.base(); }
00319 
00320   template<typename _Iterator>
00321     inline reverse_iterator<_Iterator>
00322     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
00323           const reverse_iterator<_Iterator>& __x)
00324     { return reverse_iterator<_Iterator>(__x.base() - __n); }
00325 
00326   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00327   // DR 280. Comparison of reverse_iterator to const reverse_iterator.
00328   template<typename _IteratorL, typename _IteratorR>
00329     inline bool
00330     operator==(const reverse_iterator<_IteratorL>& __x,
00331            const reverse_iterator<_IteratorR>& __y)
00332     { return __x.base() == __y.base(); }
00333 
00334   template<typename _IteratorL, typename _IteratorR>
00335     inline bool
00336     operator<(const reverse_iterator<_IteratorL>& __x,
00337           const reverse_iterator<_IteratorR>& __y)
00338     { return __y.base() < __x.base(); }
00339 
00340   template<typename _IteratorL, typename _IteratorR>
00341     inline bool
00342     operator!=(const reverse_iterator<_IteratorL>& __x,
00343            const reverse_iterator<_IteratorR>& __y)
00344     { return !(__x == __y); }
00345 
00346   template<typename _IteratorL, typename _IteratorR>
00347     inline bool
00348     operator>(const reverse_iterator<_IteratorL>& __x,
00349           const reverse_iterator<_IteratorR>& __y)
00350     { return __y < __x; }
00351 
00352   template<typename _IteratorL, typename _IteratorR>
00353     inline bool
00354     operator<=(const reverse_iterator<_IteratorL>& __x,
00355            const reverse_iterator<_IteratorR>& __y)
00356     { return !(__y < __x); }
00357 
00358   template<typename _IteratorL, typename _IteratorR>
00359     inline bool
00360     operator>=(const reverse_iterator<_IteratorL>& __x,
00361            const reverse_iterator<_IteratorR>& __y)
00362     { return !(__x < __y); }
00363 
00364   template<typename _IteratorL, typename _IteratorR>
00365     inline typename reverse_iterator<_IteratorL>::difference_type
00366     operator-(const reverse_iterator<_IteratorL>& __x,
00367           const reverse_iterator<_IteratorR>& __y)
00368     { return __y.base() - __x.base(); }
00369   //@}
00370 
00371   // 24.4.2.2.1 back_insert_iterator
00372   /**
00373    *  @brief  Turns assignment into insertion.
00374    *
00375    *  These are output iterators, constructed from a container-of-T.
00376    *  Assigning a T to the iterator appends it to the container using
00377    *  push_back.
00378    *
00379    *  Tip:  Using the back_inserter function to create these iterators can
00380    *  save typing.
00381   */
00382   template<typename _Container>
00383     class back_insert_iterator
00384     : public iterator<output_iterator_tag, void, void, void, void>
00385     {
00386     protected:
00387       _Container* container;
00388 
00389     public:
00390       /// A nested typedef for the type of whatever container you used.
00391       typedef _Container          container_type;
00392 
00393       /// The only way to create this %iterator is with a container.
00394       explicit
00395       back_insert_iterator(_Container& __x) : container(&__x) { }
00396 
00397       /**
00398        *  @param  value  An instance of whatever type
00399        *                 container_type::const_reference is; presumably a
00400        *                 reference-to-const T for container<T>.
00401        *  @return  This %iterator, for chained operations.
00402        *
00403        *  This kind of %iterator doesn't really have a "position" in the
00404        *  container (you can think of the position as being permanently at
00405        *  the end, if you like).  Assigning a value to the %iterator will
00406        *  always append the value to the end of the container.
00407       */
00408       back_insert_iterator&
00409       operator=(typename _Container::const_reference __value)
00410       {
00411     container->push_back(__value);
00412     return *this;
00413       }
00414 
00415       /// Simply returns *this.
00416       back_insert_iterator&
00417       operator*()
00418       { return *this; }
00419 
00420       /// Simply returns *this.  (This %iterator does not "move".)
00421       back_insert_iterator&
00422       operator++()
00423       { return *this; }
00424 
00425       /// Simply returns *this.  (This %iterator does not "move".)
00426       back_insert_iterator
00427       operator++(int)
00428       { return *this; }
00429     };
00430 
00431   /**
00432    *  @param  x  A container of arbitrary type.
00433    *  @return  An instance of back_insert_iterator working on @p x.
00434    *
00435    *  This wrapper function helps in creating back_insert_iterator instances.
00436    *  Typing the name of the %iterator requires knowing the precise full
00437    *  type of the container, which can be tedious and impedes generic
00438    *  programming.  Using this function lets you take advantage of automatic
00439    *  template parameter deduction, making the compiler match the correct
00440    *  types for you.
00441   */
00442   template<typename _Container>
00443     inline back_insert_iterator<_Container>
00444     back_inserter(_Container& __x)
00445     { return back_insert_iterator<_Container>(__x); }
00446 
00447   /**
00448    *  @brief  Turns assignment into insertion.
00449    *
00450    *  These are output iterators, constructed from a container-of-T.
00451    *  Assigning a T to the iterator prepends it to the container using
00452    *  push_front.
00453    *
00454    *  Tip:  Using the front_inserter function to create these iterators can
00455    *  save typing.
00456   */
00457   template<typename _Container>
00458     class front_insert_iterator
00459     : public iterator<output_iterator_tag, void, void, void, void>
00460     {
00461     protected:
00462       _Container* container;
00463 
00464     public:
00465       /// A nested typedef for the type of whatever container you used.
00466       typedef _Container          container_type;
00467 
00468       /// The only way to create this %iterator is with a container.
00469       explicit front_insert_iterator(_Container& __x) : container(&__x) { }
00470 
00471       /**
00472        *  @param  value  An instance of whatever type
00473        *                 container_type::const_reference is; presumably a
00474        *                 reference-to-const T for container<T>.
00475        *  @return  This %iterator, for chained operations.
00476        *
00477        *  This kind of %iterator doesn't really have a "position" in the
00478        *  container (you can think of the position as being permanently at
00479        *  the front, if you like).  Assigning a value to the %iterator will
00480        *  always prepend the value to the front of the container.
00481       */
00482       front_insert_iterator&
00483       operator=(typename _Container::const_reference __value)
00484       {
00485     container->push_front(__value);
00486     return *this;
00487       }
00488 
00489       /// Simply returns *this.
00490       front_insert_iterator&
00491       operator*()
00492       { return *this; }
00493 
00494       /// Simply returns *this.  (This %iterator does not "move".)
00495       front_insert_iterator&
00496       operator++()
00497       { return *this; }
00498 
00499       /// Simply returns *this.  (This %iterator does not "move".)
00500       front_insert_iterator
00501       operator++(int)
00502       { return *this; }
00503     };
00504 
00505   /**
00506    *  @param  x  A container of arbitrary type.
00507    *  @return  An instance of front_insert_iterator working on @p x.
00508    *
00509    *  This wrapper function helps in creating front_insert_iterator instances.
00510    *  Typing the name of the %iterator requires knowing the precise full
00511    *  type of the container, which can be tedious and impedes generic
00512    *  programming.  Using this function lets you take advantage of automatic
00513    *  template parameter deduction, making the compiler match the correct
00514    *  types for you.
00515   */
00516   template<typename _Container>
00517     inline front_insert_iterator<_Container>
00518     front_inserter(_Container& __x)
00519     { return front_insert_iterator<_Container>(__x); }
00520 
00521   /**
00522    *  @brief  Turns assignment into insertion.
00523    *
00524    *  These are output iterators, constructed from a container-of-T.
00525    *  Assigning a T to the iterator inserts it in the container at the
00526    *  %iterator's position, rather than overwriting the value at that
00527    *  position.
00528    *
00529    *  (Sequences will actually insert a @e copy of the value before the
00530    *  %iterator's position.)
00531    *
00532    *  Tip:  Using the inserter function to create these iterators can
00533    *  save typing.
00534   */
00535   template<typename _Container>
00536     class insert_iterator
00537     : public iterator<output_iterator_tag, void, void, void, void>
00538     {
00539     protected:
00540       _Container* container;
00541       typename _Container::iterator iter;
00542 
00543     public:
00544       /// A nested typedef for the type of whatever container you used.
00545       typedef _Container          container_type;
00546 
00547       /**
00548        *  The only way to create this %iterator is with a container and an
00549        *  initial position (a normal %iterator into the container).
00550       */
00551       insert_iterator(_Container& __x, typename _Container::iterator __i)
00552       : container(&__x), iter(__i) {}
00553 
00554       /**
00555        *  @param  value  An instance of whatever type
00556        *                 container_type::const_reference is; presumably a
00557        *                 reference-to-const T for container<T>.
00558        *  @return  This %iterator, for chained operations.
00559        *
00560        *  This kind of %iterator maintains its own position in the
00561        *  container.  Assigning a value to the %iterator will insert the
00562        *  value into the container at the place before the %iterator.
00563        *
00564        *  The position is maintained such that subsequent assignments will
00565        *  insert values immediately after one another.  For example,
00566        *  @code
00567        *     // vector v contains A and Z
00568        *
00569        *     insert_iterator i (v, ++v.begin());
00570        *     i = 1;
00571        *     i = 2;
00572        *     i = 3;
00573        *
00574        *     // vector v contains A, 1, 2, 3, and Z
00575        *  @endcode
00576       */
00577       insert_iterator&
00578       operator=(const typename _Container::const_reference __value)
00579       {
00580     iter = container->insert(iter, __value);
00581     ++iter;
00582     return *this;
00583       }
00584 
00585       /// Simply returns *this.
00586       insert_iterator&
00587       operator*()
00588       { return *this; }
00589 
00590       /// Simply returns *this.  (This %iterator does not "move".)
00591       insert_iterator&
00592       operator++()
00593       { return *this; }
00594 
00595       /// Simply returns *this.  (This %iterator does not "move".)
00596       insert_iterator&
00597       operator++(int)
00598       { return *this; }
00599     };
00600 
00601   /**
00602    *  @param  x  A container of arbitrary type.
00603    *  @return  An instance of insert_iterator working on @p x.
00604    *
00605    *  This wrapper function helps in creating insert_iterator instances.
00606    *  Typing the name of the %iterator requires knowing the precise full
00607    *  type of the container, which can be tedious and impedes generic
00608    *  programming.  Using this function lets you take advantage of automatic
00609    *  template parameter deduction, making the compiler match the correct
00610    *  types for you.
00611   */
00612   template<typename _Container, typename _Iterator>
00613     inline insert_iterator<_Container>
00614     inserter(_Container& __x, _Iterator __i)
00615     {
00616       return insert_iterator<_Container>(__x,
00617                      typename _Container::iterator(__i));
00618     }
00619 } // namespace std
00620 
00621 namespace __gnu_cxx
00622 {
00623   // This iterator adapter is 'normal' in the sense that it does not
00624   // change the semantics of any of the operators of its iterator
00625   // parameter.  Its primary purpose is to convert an iterator that is
00626   // not a class, e.g. a pointer, into an iterator that is a class.
00627   // The _Container parameter exists solely so that different containers
00628   // using this template can instantiate different types, even if the
00629   // _Iterator parameter is the same.
00630   using std::iterator_traits;
00631   using std::iterator;
00632   template<typename _Iterator, typename _Container>
00633     class __normal_iterator
00634     {
00635     protected:
00636       _Iterator _M_current;
00637 
00638     public:
00639       typedef typename iterator_traits<_Iterator>::iterator_category
00640                                                              iterator_category;
00641       typedef typename iterator_traits<_Iterator>::value_type  value_type;
00642       typedef typename iterator_traits<_Iterator>::difference_type
00643                                                              difference_type;
00644       typedef typename iterator_traits<_Iterator>::reference reference;
00645       typedef typename iterator_traits<_Iterator>::pointer   pointer;
00646 
00647       __normal_iterator() : _M_current(_Iterator()) { }
00648 
00649       explicit
00650       __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
00651 
00652       // Allow iterator to const_iterator conversion
00653       template<typename _Iter>
00654         __normal_iterator(const __normal_iterator<_Iter,
00655               typename std::__enable_if<_Container,
00656               (std::__are_same<_Iter,
00657                typename _Container::pointer>::__value)
00658               >::__type>& __i)
00659         : _M_current(__i.base()) { }
00660 
00661       // Forward iterator requirements
00662       reference
00663       operator*() const
00664       { return *_M_current; }
00665 
00666       pointer
00667       operator->() const
00668       { return _M_current; }
00669 
00670       __normal_iterator&
00671       operator++()
00672       {
00673     ++_M_current;
00674     return *this;
00675       }
00676 
00677       __normal_iterator
00678       operator++(int)
00679       { return __normal_iterator(_M_current++); }
00680 
00681       // Bidirectional iterator requirements
00682       __normal_iterator&
00683       operator--()
00684       {
00685     --_M_current;
00686     return *this;
00687       }
00688 
00689       __normal_iterator
00690       operator--(int)
00691       { return __normal_iterator(_M_current--); }
00692 
00693       // Random access iterator requirements
00694       reference
00695       operator[](const difference_type& __n) const
00696       { return _M_current[__n]; }
00697 
00698       __normal_iterator&
00699       operator+=(const difference_type& __n)
00700       { _M_current += __n; return *this; }
00701 
00702       __normal_iterator
00703       operator+(const difference_type& __n) const
00704       { return __normal_iterator(_M_current + __n); }
00705 
00706       __normal_iterator&
00707       operator-=(const difference_type& __n)
00708       { _M_current -= __n; return *this; }
00709 
00710       __normal_iterator
00711       operator-(const difference_type& __n) const
00712       { return __normal_iterator(_M_current - __n); }
00713 
00714       const _Iterator&
00715       base() const
00716       { return _M_current; }
00717     };
00718 
00719   // Note: In what follows, the left- and right-hand-side iterators are
00720   // allowed to vary in types (conceptually in cv-qualification) so that
00721   // comparaison between cv-qualified and non-cv-qualified iterators be
00722   // valid.  However, the greedy and unfriendly operators in std::rel_ops
00723   // will make overload resolution ambiguous (when in scope) if we don't
00724   // provide overloads whose operands are of the same type.  Can someone
00725   // remind me what generic programming is about? -- Gaby
00726 
00727   // Forward iterator requirements
00728   template<typename _IteratorL, typename _IteratorR, typename _Container>
00729     inline bool
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 bool
00736     operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
00737            const __normal_iterator<_Iterator, _Container>& __rhs)
00738     { return __lhs.base() == __rhs.base(); }
00739 
00740   template<typename _IteratorL, typename _IteratorR, typename _Container>
00741     inline bool
00742     operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00743            const __normal_iterator<_IteratorR, _Container>& __rhs)
00744     { return __lhs.base() != __rhs.base(); }
00745 
00746   template<typename _Iterator, typename _Container>
00747     inline bool
00748     operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
00749            const __normal_iterator<_Iterator, _Container>& __rhs)
00750     { return __lhs.base() != __rhs.base(); }
00751 
00752   // Random access iterator requirements
00753   template<typename _IteratorL, typename _IteratorR, typename _Container>
00754     inline bool
00755     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
00756           const __normal_iterator<_IteratorR, _Container>& __rhs)
00757     { return __lhs.base() < __rhs.base(); }
00758 
00759   template<typename _Iterator, typename _Container>
00760     inline bool
00761     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
00762           const __normal_iterator<_Iterator, _Container>& __rhs)
00763     { return __lhs.base() < __rhs.base(); }
00764 
00765   template<typename _IteratorL, typename _IteratorR, typename _Container>
00766     inline bool
00767     operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
00768           const __normal_iterator<_IteratorR, _Container>& __rhs)
00769     { return __lhs.base() > __rhs.base(); }
00770 
00771   template<typename _Iterator, typename _Container>
00772     inline bool
00773     operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
00774           const __normal_iterator<_Iterator, _Container>& __rhs)
00775     { return __lhs.base() > __rhs.base(); }
00776 
00777   template<typename _IteratorL, typename _IteratorR, typename _Container>
00778     inline bool
00779     operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00780            const __normal_iterator<_IteratorR, _Container>& __rhs)
00781     { return __lhs.base() <= __rhs.base(); }
00782 
00783   template<typename _Iterator, typename _Container>
00784     inline bool
00785     operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
00786            const __normal_iterator<_Iterator, _Container>& __rhs)
00787     { return __lhs.base() <= __rhs.base(); }
00788 
00789   template<typename _IteratorL, typename _IteratorR, typename _Container>
00790     inline bool
00791     operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
00792            const __normal_iterator<_IteratorR, _Container>& __rhs)
00793     { return __lhs.base() >= __rhs.base(); }
00794 
00795   template<typename _Iterator, typename _Container>
00796     inline bool
00797     operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
00798            const __normal_iterator<_Iterator, _Container>& __rhs)
00799     { return __lhs.base() >= __rhs.base(); }
00800 
00801   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00802   // According to the resolution of DR179 not only the various comparison
00803   // operators but also operator- must accept mixed iterator/const_iterator
00804   // parameters.
00805   template<typename _IteratorL, typename _IteratorR, typename _Container>
00806     inline typename __normal_iterator<_IteratorL, _Container>::difference_type
00807     operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
00808           const __normal_iterator<_IteratorR, _Container>& __rhs)
00809     { return __lhs.base() - __rhs.base(); }
00810 
00811   template<typename _Iterator, typename _Container>
00812     inline __normal_iterator<_Iterator, _Container>
00813     operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
00814           __n, const __normal_iterator<_Iterator, _Container>& __i)
00815     { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
00816 } // namespace __gnu_cxx
00817 
00818 #endif
00819 
00820 // Local Variables:
00821 // mode:C++
00822 // End:

Generated on Tue Dec 2 03:59:28 2008 for libstdc++ by  doxygen 1.5.7.1