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

Generated on Thu Feb 10 23:22:58 2005 for libstdc++-v3 Source by  doxygen 1.4.0