# safe_iterator.h

Go to the documentation of this file.

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