safe_iterator.h

Go to the documentation of this file.
00001 // Safe iterator implementation  -*- C++ -*-
00002 
00003 // Copyright (C) 2003, 2004, 2005, 2006
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 /** @file debug/safe_iterator.h
00032  *  This file is a GNU debug extension to the Standard C++ Library.
00033  */
00034 
00035 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
00036 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
00037 
00038 #include <debug/debug.h>
00039 #include <debug/macros.h>
00040 #include <debug/functions.h>
00041 #include <debug/formatter.h>
00042 #include <debug/safe_base.h>
00043 #include <bits/stl_pair.h>
00044 #include <ext/type_traits.h>
00045 
00046 namespace __gnu_debug
00047 {
00048   /** Iterators that derive from _Safe_iterator_base but that aren't
00049    *  _Safe_iterators can be determined singular or non-singular via
00050    *  _Safe_iterator_base.
00051    */
00052   inline bool 
00053   __check_singular_aux(const _Safe_iterator_base* __x)
00054   { return __x->_M_singular(); }
00055 
00056   /** \brief Safe iterator wrapper.
00057    *
00058    *  The class template %_Safe_iterator is a wrapper around an
00059    *  iterator that tracks the iterator's movement among sequences and
00060    *  checks that operations performed on the "safe" iterator are
00061    *  legal. In additional to the basic iterator operations (which are
00062    *  validated, and then passed to the underlying iterator),
00063    *  %_Safe_iterator has member functions for iterator invalidation,
00064    *  attaching/detaching the iterator from sequences, and querying
00065    *  the iterator's state.
00066    */
00067   template<typename _Iterator, typename _Sequence>
00068     class _Safe_iterator : public _Safe_iterator_base
00069     {
00070       typedef _Safe_iterator _Self;
00071 
00072       /** The precision to which we can calculate the distance between
00073        *  two iterators.
00074        */
00075       enum _Distance_precision
00076     {
00077       __dp_equality, //< Can compare iterator equality, only
00078       __dp_sign,     //< Can determine equality and ordering
00079       __dp_exact     //< Can determine distance precisely
00080     };
00081 
00082       /// The underlying iterator
00083       _Iterator _M_current;
00084 
00085       /// Determine if this is a constant iterator.
00086       bool
00087       _M_constant() const
00088       {
00089     typedef typename _Sequence::const_iterator const_iterator;
00090     return __is_same<const_iterator, _Safe_iterator>::value;
00091       }
00092 
00093       typedef std::iterator_traits<_Iterator> _Traits;
00094 
00095     public:
00096       typedef _Iterator                           _Base_iterator;
00097       typedef typename _Traits::iterator_category iterator_category;
00098       typedef typename _Traits::value_type        value_type;
00099       typedef typename _Traits::difference_type   difference_type;
00100       typedef typename _Traits::reference         reference;
00101       typedef typename _Traits::pointer           pointer;
00102 
00103       /// @post the iterator is singular and unattached
00104       _Safe_iterator() : _M_current() { }
00105 
00106       /**
00107        * @brief Safe iterator construction from an unsafe iterator and
00108        * its sequence.
00109        *
00110        * @pre @p seq is not NULL
00111        * @post this is not singular
00112        */
00113       _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
00114       : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
00115       {
00116     _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00117                   _M_message(__msg_init_singular)
00118                   ._M_iterator(*this, "this"));
00119       }
00120 
00121       /**
00122        * @brief Copy construction.
00123        * @pre @p x is not singular
00124        */
00125       _Safe_iterator(const _Safe_iterator& __x)
00126       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
00127       {
00128     _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00129                   _M_message(__msg_init_copy_singular)
00130                   ._M_iterator(*this, "this")
00131                   ._M_iterator(__x, "other"));
00132       }
00133 
00134       /**
00135        *  @brief Converting constructor from a mutable iterator to a
00136        *  constant iterator.
00137        *
00138        *  @pre @p x is not singular
00139       */
00140       template<typename _MutableIterator>
00141         _Safe_iterator(
00142           const _Safe_iterator<_MutableIterator,
00143           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
00144                       typename _Sequence::iterator::_Base_iterator>::__value),
00145                    _Sequence>::__type>& __x)
00146     : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
00147         {
00148       _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00149                 _M_message(__msg_init_const_singular)
00150                 ._M_iterator(*this, "this")
00151                 ._M_iterator(__x, "other"));
00152     }
00153 
00154       /**
00155        * @brief Copy assignment.
00156        * @pre @p x is not singular
00157        */
00158       _Safe_iterator&
00159       operator=(const _Safe_iterator& __x)
00160       {
00161     _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00162                   _M_message(__msg_copy_singular)
00163                   ._M_iterator(*this, "this")
00164                   ._M_iterator(__x, "other"));
00165     _M_current = __x._M_current;
00166     this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
00167     return *this;
00168       }
00169 
00170       /**
00171        *  @brief Iterator dereference.
00172        *  @pre iterator is dereferenceable
00173        */
00174       reference
00175       operator*() const
00176       {
00177 
00178     _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00179                   _M_message(__msg_bad_deref)
00180                   ._M_iterator(*this, "this"));
00181     return *_M_current;
00182       }
00183 
00184       /**
00185        *  @brief Iterator dereference.
00186        *  @pre iterator is dereferenceable
00187        *  @todo Make this correct w.r.t. iterators that return proxies
00188        *  @todo Use addressof() instead of & operator
00189        */
00190       pointer
00191       operator->() const
00192       {
00193     _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00194                   _M_message(__msg_bad_deref)
00195                   ._M_iterator(*this, "this"));
00196     return &*_M_current;
00197       }
00198 
00199       // ------ Input iterator requirements ------
00200       /**
00201        *  @brief Iterator preincrement
00202        *  @pre iterator is incrementable
00203        */
00204       _Safe_iterator&
00205       operator++()
00206       {
00207     _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00208                   _M_message(__msg_bad_inc)
00209                   ._M_iterator(*this, "this"));
00210     ++_M_current;
00211     return *this;
00212       }
00213 
00214       /**
00215        *  @brief Iterator postincrement
00216        *  @pre iterator is incrementable
00217        */
00218       _Safe_iterator
00219       operator++(int)
00220       {
00221     _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00222                   _M_message(__msg_bad_inc)
00223                   ._M_iterator(*this, "this"));
00224     _Safe_iterator __tmp(*this);
00225     ++_M_current;
00226     return __tmp;
00227       }
00228 
00229       // ------ Bidirectional iterator requirements ------
00230       /**
00231        *  @brief Iterator predecrement
00232        *  @pre iterator is decrementable
00233        */
00234       _Safe_iterator&
00235       operator--()
00236       {
00237     _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00238                   _M_message(__msg_bad_dec)
00239                   ._M_iterator(*this, "this"));
00240     --_M_current;
00241     return *this;
00242       }
00243 
00244       /**
00245        *  @brief Iterator postdecrement
00246        *  @pre iterator is decrementable
00247        */
00248       _Safe_iterator
00249       operator--(int)
00250       {
00251     _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00252                   _M_message(__msg_bad_dec)
00253                   ._M_iterator(*this, "this"));
00254     _Safe_iterator __tmp(*this);
00255     --_M_current;
00256     return __tmp;
00257       }
00258 
00259       // ------ Random access iterator requirements ------
00260       reference
00261       operator[](const difference_type& __n) const
00262       {
00263     _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
00264                   && this->_M_can_advance(__n+1),
00265                   _M_message(__msg_iter_subscript_oob)
00266                   ._M_iterator(*this)._M_integer(__n));
00267 
00268     return _M_current[__n];
00269       }
00270 
00271       _Safe_iterator&
00272       operator+=(const difference_type& __n)
00273       {
00274     _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
00275                   _M_message(__msg_advance_oob)
00276                   ._M_iterator(*this)._M_integer(__n));
00277     _M_current += __n;
00278     return *this;
00279       }
00280 
00281       _Safe_iterator
00282       operator+(const difference_type& __n) const
00283       {
00284     _Safe_iterator __tmp(*this);
00285     __tmp += __n;
00286     return __tmp;
00287       }
00288 
00289       _Safe_iterator&
00290       operator-=(const difference_type& __n)
00291       {
00292     _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
00293                   _M_message(__msg_retreat_oob)
00294                   ._M_iterator(*this)._M_integer(__n));
00295     _M_current += -__n;
00296     return *this;
00297       }
00298 
00299       _Safe_iterator
00300       operator-(const difference_type& __n) const
00301       {
00302     _Safe_iterator __tmp(*this);
00303     __tmp -= __n;
00304     return __tmp;
00305       }
00306 
00307       // ------ Utilities ------
00308       /**
00309        * @brief Return the underlying iterator
00310        */
00311       _Iterator
00312       base() const { return _M_current; }
00313 
00314       /**
00315        * @brief Conversion to underlying non-debug iterator to allow
00316        * better interaction with non-debug containers.
00317        */
00318       operator _Iterator() const { return _M_current; }
00319 
00320       /** Attach iterator to the given sequence. */
00321       void
00322       _M_attach(const _Sequence* __seq)
00323       {
00324     _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
00325                        _M_constant());
00326       }
00327 
00328       /** Likewise, but not thread-safe. */
00329       void
00330       _M_attach_single(const _Sequence* __seq)
00331       {
00332     _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
00333                           _M_constant());
00334       }
00335 
00336       /** Invalidate the iterator, making it singular. */
00337       void
00338       _M_invalidate();
00339 
00340       /** Likewise, but not thread-safe. */
00341       void
00342       _M_invalidate_single();
00343 
00344       /// Is the iterator dereferenceable?
00345       bool
00346       _M_dereferenceable() const
00347       { return !this->_M_singular() && !_M_is_end(); }
00348 
00349       /// Is the iterator incrementable?
00350       bool
00351       _M_incrementable() const { return this->_M_dereferenceable(); }
00352 
00353       // Is the iterator decrementable?
00354       bool
00355       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
00356 
00357       // Can we advance the iterator @p __n steps (@p __n may be negative)
00358       bool
00359       _M_can_advance(const difference_type& __n) const;
00360 
00361       // Is the iterator range [*this, __rhs) valid?
00362       template<typename _Other>
00363         bool
00364         _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
00365 
00366       // The sequence this iterator references.
00367       const _Sequence*
00368       _M_get_sequence() const
00369       { return static_cast<const _Sequence*>(_M_sequence); }
00370 
00371     /** Determine the distance between two iterators with some known
00372      *  precision.
00373     */
00374     template<typename _Iterator1, typename _Iterator2>
00375       static std::pair<difference_type, _Distance_precision>
00376       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
00377       {
00378         typedef typename std::iterator_traits<_Iterator1>::iterator_category
00379       _Category;
00380         return _M_get_distance(__lhs, __rhs, _Category());
00381       }
00382 
00383     template<typename _Iterator1, typename _Iterator2>
00384       static std::pair<difference_type, _Distance_precision>
00385       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00386               std::random_access_iterator_tag)
00387       {
00388         return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
00389       }
00390 
00391     template<typename _Iterator1, typename _Iterator2>
00392       static std::pair<difference_type, _Distance_precision>
00393       _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00394             std::forward_iterator_tag)
00395       {
00396         return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
00397                   __dp_equality);
00398       }
00399 
00400       /// Is this iterator equal to the sequence's begin() iterator?
00401       bool _M_is_begin() const
00402       { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
00403 
00404       /// Is this iterator equal to the sequence's end() iterator?
00405       bool _M_is_end() const
00406       { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
00407     };
00408 
00409   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00410     inline bool
00411     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00412            const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00413     {
00414       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00415                 _M_message(__msg_iter_compare_bad)
00416                 ._M_iterator(__lhs, "lhs")
00417                 ._M_iterator(__rhs, "rhs"));
00418       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00419                 _M_message(__msg_compare_different)
00420                 ._M_iterator(__lhs, "lhs")
00421                 ._M_iterator(__rhs, "rhs"));
00422       return __lhs.base() == __rhs.base();
00423     }
00424 
00425   template<typename _Iterator, typename _Sequence>
00426     inline bool
00427     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00428                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00429     {
00430       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00431                 _M_message(__msg_iter_compare_bad)
00432                 ._M_iterator(__lhs, "lhs")
00433                 ._M_iterator(__rhs, "rhs"));
00434       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00435                 _M_message(__msg_compare_different)
00436                 ._M_iterator(__lhs, "lhs")
00437                 ._M_iterator(__rhs, "rhs"));
00438       return __lhs.base() == __rhs.base();
00439     }
00440 
00441   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00442     inline bool
00443     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00444            const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00445     {
00446       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00447                 _M_message(__msg_iter_compare_bad)
00448                 ._M_iterator(__lhs, "lhs")
00449                 ._M_iterator(__rhs, "rhs"));
00450       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00451                 _M_message(__msg_compare_different)
00452                 ._M_iterator(__lhs, "lhs")
00453                 ._M_iterator(__rhs, "rhs"));
00454       return __lhs.base() != __rhs.base();
00455     }
00456 
00457   template<typename _Iterator, typename _Sequence>
00458     inline bool
00459     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00460                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00461     {
00462       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00463                 _M_message(__msg_iter_compare_bad)
00464                 ._M_iterator(__lhs, "lhs")
00465                 ._M_iterator(__rhs, "rhs"));
00466       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00467                 _M_message(__msg_compare_different)
00468                 ._M_iterator(__lhs, "lhs")
00469                 ._M_iterator(__rhs, "rhs"));
00470       return __lhs.base() != __rhs.base();
00471     }
00472 
00473   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00474     inline bool
00475     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00476           const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00477     {
00478       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00479                 _M_message(__msg_iter_order_bad)
00480                 ._M_iterator(__lhs, "lhs")
00481                 ._M_iterator(__rhs, "rhs"));
00482       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00483                 _M_message(__msg_order_different)
00484                 ._M_iterator(__lhs, "lhs")
00485                 ._M_iterator(__rhs, "rhs"));
00486       return __lhs.base() < __rhs.base();
00487     }
00488 
00489   template<typename _Iterator, typename _Sequence>
00490     inline bool
00491     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00492           const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00493     {
00494       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00495                 _M_message(__msg_iter_order_bad)
00496                 ._M_iterator(__lhs, "lhs")
00497                 ._M_iterator(__rhs, "rhs"));
00498       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00499                 _M_message(__msg_order_different)
00500                 ._M_iterator(__lhs, "lhs")
00501                 ._M_iterator(__rhs, "rhs"));
00502       return __lhs.base() < __rhs.base();
00503     }
00504 
00505   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00506     inline bool
00507     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00508            const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00509     {
00510       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00511                 _M_message(__msg_iter_order_bad)
00512                 ._M_iterator(__lhs, "lhs")
00513                 ._M_iterator(__rhs, "rhs"));
00514       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00515                 _M_message(__msg_order_different)
00516                 ._M_iterator(__lhs, "lhs")
00517                 ._M_iterator(__rhs, "rhs"));
00518       return __lhs.base() <= __rhs.base();
00519     }
00520 
00521   template<typename _Iterator, typename _Sequence>
00522     inline bool
00523     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00524                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00525     {
00526       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00527                 _M_message(__msg_iter_order_bad)
00528                 ._M_iterator(__lhs, "lhs")
00529                 ._M_iterator(__rhs, "rhs"));
00530       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00531                 _M_message(__msg_order_different)
00532                 ._M_iterator(__lhs, "lhs")
00533                 ._M_iterator(__rhs, "rhs"));
00534       return __lhs.base() <= __rhs.base();
00535     }
00536 
00537   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00538     inline bool
00539     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00540           const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00541     {
00542       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00543                 _M_message(__msg_iter_order_bad)
00544                 ._M_iterator(__lhs, "lhs")
00545                 ._M_iterator(__rhs, "rhs"));
00546       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00547                 _M_message(__msg_order_different)
00548                 ._M_iterator(__lhs, "lhs")
00549                 ._M_iterator(__rhs, "rhs"));
00550       return __lhs.base() > __rhs.base();
00551     }
00552 
00553   template<typename _Iterator, typename _Sequence>
00554     inline bool
00555     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00556           const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00557     {
00558       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00559                 _M_message(__msg_iter_order_bad)
00560                 ._M_iterator(__lhs, "lhs")
00561                 ._M_iterator(__rhs, "rhs"));
00562       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00563                 _M_message(__msg_order_different)
00564                 ._M_iterator(__lhs, "lhs")
00565                 ._M_iterator(__rhs, "rhs"));
00566       return __lhs.base() > __rhs.base();
00567     }
00568 
00569   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00570     inline bool
00571     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00572            const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00573     {
00574       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00575                 _M_message(__msg_iter_order_bad)
00576                 ._M_iterator(__lhs, "lhs")
00577                 ._M_iterator(__rhs, "rhs"));
00578       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00579                 _M_message(__msg_order_different)
00580                 ._M_iterator(__lhs, "lhs")
00581                 ._M_iterator(__rhs, "rhs"));
00582       return __lhs.base() >= __rhs.base();
00583     }
00584 
00585   template<typename _Iterator, typename _Sequence>
00586     inline bool
00587     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00588                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00589     {
00590       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00591                 _M_message(__msg_iter_order_bad)
00592                 ._M_iterator(__lhs, "lhs")
00593                 ._M_iterator(__rhs, "rhs"));
00594       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00595                 _M_message(__msg_order_different)
00596                 ._M_iterator(__lhs, "lhs")
00597                 ._M_iterator(__rhs, "rhs"));
00598       return __lhs.base() >= __rhs.base();
00599     }
00600 
00601   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00602   // According to the resolution of DR179 not only the various comparison
00603   // operators but also operator- must accept mixed iterator/const_iterator
00604   // parameters.
00605   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00606     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
00607     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00608           const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00609     {
00610       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00611                 _M_message(__msg_distance_bad)
00612                 ._M_iterator(__lhs, "lhs")
00613                 ._M_iterator(__rhs, "rhs"));
00614       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00615                 _M_message(__msg_distance_different)
00616                 ._M_iterator(__lhs, "lhs")
00617                 ._M_iterator(__rhs, "rhs"));
00618       return __lhs.base() - __rhs.base();
00619     }
00620 
00621    template<typename _Iterator, typename _Sequence>
00622      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
00623      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00624            const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00625      {
00626        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00627                  _M_message(__msg_distance_bad)
00628                  ._M_iterator(__lhs, "lhs")
00629                  ._M_iterator(__rhs, "rhs"));
00630        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00631                  _M_message(__msg_distance_different)
00632                  ._M_iterator(__lhs, "lhs")
00633                  ._M_iterator(__rhs, "rhs"));
00634        return __lhs.base() - __rhs.base();
00635      }
00636 
00637   template<typename _Iterator, typename _Sequence>
00638     inline _Safe_iterator<_Iterator, _Sequence>
00639     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
00640           const _Safe_iterator<_Iterator, _Sequence>& __i)
00641     { return __i + __n; }
00642 } // namespace __gnu_debug
00643 
00644 #ifndef _GLIBCXX_EXPORT_TEMPLATE
00645 #  include <debug/safe_iterator.tcc>
00646 #endif
00647 
00648 #endif

Generated on Thu Nov 1 13:12:23 2007 for libstdc++ by  doxygen 1.5.1