Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Safe iterator implementation  -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file debug/safe_iterator.h
  26.  *  This file is a GNU debug extension to the Standard C++ Library.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
  30. #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
  31.  
  32. #include <debug/debug.h>
  33. #include <debug/macros.h>
  34. #include <debug/functions.h>
  35. #include <debug/safe_base.h>
  36. #include <bits/stl_pair.h>
  37. #include <ext/type_traits.h>
  38.  
  39. namespace __gnu_debug
  40. {
  41.   /** Helper struct to deal with sequence offering a before_begin
  42.    *  iterator.
  43.    **/
  44.   template <typename _Sequence>
  45.     struct _BeforeBeginHelper
  46.     {
  47.       template<typename _Iterator>
  48.         static bool
  49.         _S_Is(const _Safe_iterator<_Iterator, _Sequence>&)
  50.         { return false; }
  51.  
  52.       template<typename _Iterator>
  53.         static bool
  54.         _S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it)
  55.         { return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
  56.     };
  57.  
  58.   /** Iterators that derive from _Safe_iterator_base can be determined singular
  59.    *  or non-singular.
  60.    **/
  61.   inline bool
  62.   __check_singular_aux(const _Safe_iterator_base* __x)
  63.   { return __x->_M_singular(); }
  64.  
  65.   /** The precision to which we can calculate the distance between
  66.    *  two iterators.
  67.    */
  68.   enum _Distance_precision
  69.     {
  70.       __dp_equality, //< Can compare iterator equality, only
  71.       __dp_sign,     //< Can determine equality and ordering
  72.       __dp_exact     //< Can determine distance precisely
  73.     };
  74.  
  75.   /** Determine the distance between two iterators with some known
  76.    *    precision.
  77.   */
  78.   template<typename _Iterator>
  79.     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
  80.                      _Distance_precision>
  81.     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs,
  82.                    std::random_access_iterator_tag)
  83.     { return std::make_pair(__rhs - __lhs, __dp_exact); }
  84.  
  85.   template<typename _Iterator>
  86.     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
  87.                      _Distance_precision>
  88.     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs,
  89.                    std::forward_iterator_tag)
  90.     { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
  91.  
  92.   template<typename _Iterator>
  93.     inline std::pair<typename std::iterator_traits<_Iterator>::difference_type,
  94.                      _Distance_precision>
  95.     __get_distance(const _Iterator& __lhs, const _Iterator& __rhs)
  96.     {
  97.       typedef typename std::iterator_traits<_Iterator>::iterator_category
  98.           _Category;
  99.       return __get_distance(__lhs, __rhs, _Category());
  100.     }
  101.  
  102.   /** \brief Safe iterator wrapper.
  103.    *
  104.    *  The class template %_Safe_iterator is a wrapper around an
  105.    *  iterator that tracks the iterator's movement among sequences and
  106.    *  checks that operations performed on the "safe" iterator are
  107.    *  legal. In additional to the basic iterator operations (which are
  108.    *  validated, and then passed to the underlying iterator),
  109.    *  %_Safe_iterator has member functions for iterator invalidation,
  110.    *  attaching/detaching the iterator from sequences, and querying
  111.    *  the iterator's state.
  112.    *
  113.    *  Note that _Iterator must be the first base class so that it gets
  114.    *  initialized before the iterator is being attached to the container's list
  115.    *  of iterators and it is being detached before _Iterator get
  116.    *  destroyed. Otherwise it would result in a data race.
  117.    */
  118.   template<typename _Iterator, typename _Sequence>
  119.     class _Safe_iterator
  120.     : private _Iterator,
  121.       public _Safe_iterator_base
  122.     {
  123.       typedef _Iterator _Iter_base;
  124.       typedef _Safe_iterator_base _Safe_base;
  125.       typedef typename _Sequence::const_iterator _Const_iterator;
  126.  
  127.       /// Determine if this is a constant iterator.
  128.       bool
  129.       _M_constant() const
  130.       { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
  131.  
  132.       typedef std::iterator_traits<_Iterator> _Traits;
  133.  
  134.       struct _Attach_single
  135.       { };
  136.  
  137.       _Safe_iterator(const _Iterator& __i, _Safe_sequence_base* __seq,
  138.                      _Attach_single)
  139.       _GLIBCXX_NOEXCEPT
  140.       : _Iter_base(__i)
  141.       { _M_attach_single(__seq); }
  142.  
  143.     public:
  144.       typedef _Iterator                                 iterator_type;
  145.       typedef typename _Traits::iterator_category       iterator_category;
  146.       typedef typename _Traits::value_type              value_type;
  147.       typedef typename _Traits::difference_type         difference_type;
  148.       typedef typename _Traits::reference               reference;
  149.       typedef typename _Traits::pointer                 pointer;
  150.  
  151.       /// @post the iterator is singular and unattached
  152.       _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
  153.  
  154.       /**
  155.        * @brief Safe iterator construction from an unsafe iterator and
  156.        * its sequence.
  157.        *
  158.        * @pre @p seq is not NULL
  159.        * @post this is not singular
  160.        */
  161.       _Safe_iterator(const _Iterator& __i, const _Safe_sequence_base* __seq)
  162.       _GLIBCXX_NOEXCEPT
  163.       : _Iter_base(__i), _Safe_base(__seq, _M_constant())
  164.       {
  165.         _GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
  166.                               _M_message(__msg_init_singular)
  167.                               ._M_iterator(*this, "this"));
  168.       }
  169.  
  170.       /**
  171.        * @brief Copy construction.
  172.        */
  173.       _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  174.       : _Iter_base(__x.base())
  175.       {
  176.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  177.         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  178.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  179.                               || __x.base() == _Iterator(),
  180.                               _M_message(__msg_init_copy_singular)
  181.                               ._M_iterator(*this, "this")
  182.                               ._M_iterator(__x, "other"));
  183.         _M_attach(__x._M_sequence);
  184.       }
  185.  
  186. #if __cplusplus >= 201103L
  187.       /**
  188.        * @brief Move construction.
  189.        * @post __x is singular and unattached
  190.        */
  191.       _Safe_iterator(_Safe_iterator&& __x) noexcept
  192.       : _Iter_base()
  193.       {
  194.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  195.                               || __x.base() == _Iterator(),
  196.                               _M_message(__msg_init_copy_singular)
  197.                               ._M_iterator(*this, "this")
  198.                               ._M_iterator(__x, "other"));
  199.         _Safe_sequence_base* __seq = __x._M_sequence;
  200.         __x._M_detach();
  201.         std::swap(base(), __x.base());
  202.         _M_attach(__seq);
  203.       }
  204. #endif
  205.  
  206.       /**
  207.        *  @brief Converting constructor from a mutable iterator to a
  208.        *  constant iterator.
  209.       */
  210.       template<typename _MutableIterator>
  211.         _Safe_iterator(
  212.           const _Safe_iterator<_MutableIterator,
  213.           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
  214.                       typename _Sequence::iterator::iterator_type>::__value),
  215.                    _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
  216.         : _Iter_base(__x.base())
  217.         {
  218.           // _GLIBCXX_RESOLVE_LIB_DEFECTS
  219.           // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  220.           _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  221.                                 || __x.base() == _Iterator(),
  222.                                 _M_message(__msg_init_const_singular)
  223.                                 ._M_iterator(*this, "this")
  224.                                 ._M_iterator(__x, "other"));
  225.           _M_attach(__x._M_sequence);
  226.         }
  227.  
  228.       /**
  229.        * @brief Copy assignment.
  230.        */
  231.       _Safe_iterator&
  232.       operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
  233.       {
  234.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  235.         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  236.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  237.                               || __x.base() == _Iterator(),
  238.                               _M_message(__msg_copy_singular)
  239.                               ._M_iterator(*this, "this")
  240.                               ._M_iterator(__x, "other"));
  241.  
  242.         if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
  243.           {
  244.             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  245.             base() = __x.base();
  246.             _M_version = __x._M_sequence->_M_version;
  247.           }
  248.         else
  249.           {
  250.             _M_detach();
  251.             base() = __x.base();
  252.             _M_attach(__x._M_sequence);
  253.           }
  254.  
  255.         return *this;
  256.       }
  257.  
  258. #if __cplusplus >= 201103L
  259.       /**
  260.        * @brief Move assignment.
  261.        * @post __x is singular and unattached
  262.        */
  263.       _Safe_iterator&
  264.       operator=(_Safe_iterator&& __x) noexcept
  265.       {
  266.         _GLIBCXX_DEBUG_VERIFY(this != &__x,
  267.                               _M_message(__msg_self_move_assign)
  268.                               ._M_iterator(*this, "this"));
  269.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  270.                               || __x.base() == _Iterator(),
  271.                               _M_message(__msg_copy_singular)
  272.                               ._M_iterator(*this, "this")
  273.                               ._M_iterator(__x, "other"));
  274.  
  275.         if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
  276.           {
  277.             __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  278.             base() = __x.base();
  279.             _M_version = __x._M_sequence->_M_version;
  280.           }
  281.         else
  282.           {
  283.             _M_detach();
  284.             base() = __x.base();
  285.             _M_attach(__x._M_sequence);
  286.           }
  287.  
  288.         __x._M_detach();
  289.         __x.base() = _Iterator();
  290.         return *this;
  291.       }
  292. #endif
  293.  
  294.       /**
  295.        *  @brief Iterator dereference.
  296.        *  @pre iterator is dereferenceable
  297.        */
  298.       reference
  299.       operator*() const _GLIBCXX_NOEXCEPT
  300.       {
  301.         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  302.                               _M_message(__msg_bad_deref)
  303.                               ._M_iterator(*this, "this"));
  304.         return *base();
  305.       }
  306.  
  307.       /**
  308.        *  @brief Iterator dereference.
  309.        *  @pre iterator is dereferenceable
  310.        *  @todo Make this correct w.r.t. iterators that return proxies
  311.        */
  312.       pointer
  313.       operator->() const _GLIBCXX_NOEXCEPT
  314.       {
  315.         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  316.                               _M_message(__msg_bad_deref)
  317.                               ._M_iterator(*this, "this"));
  318.         return std::__addressof(*base());
  319.       }
  320.  
  321.       // ------ Input iterator requirements ------
  322.       /**
  323.        *  @brief Iterator preincrement
  324.        *  @pre iterator is incrementable
  325.        */
  326.       _Safe_iterator&
  327.       operator++() _GLIBCXX_NOEXCEPT
  328.       {
  329.         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  330.                               _M_message(__msg_bad_inc)
  331.                               ._M_iterator(*this, "this"));
  332.         __gnu_cxx::__scoped_lock(this->_M_get_mutex());
  333.         ++base();
  334.         return *this;
  335.       }
  336.  
  337.       /**
  338.        *  @brief Iterator postincrement
  339.        *  @pre iterator is incrementable
  340.        */
  341.       _Safe_iterator
  342.       operator++(int) _GLIBCXX_NOEXCEPT
  343.       {
  344.         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  345.                               _M_message(__msg_bad_inc)
  346.                               ._M_iterator(*this, "this"));
  347.         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  348.         return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
  349.       }
  350.  
  351.       // ------ Bidirectional iterator requirements ------
  352.       /**
  353.        *  @brief Iterator predecrement
  354.        *  @pre iterator is decrementable
  355.        */
  356.       _Safe_iterator&
  357.       operator--() _GLIBCXX_NOEXCEPT
  358.       {
  359.         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  360.                               _M_message(__msg_bad_dec)
  361.                               ._M_iterator(*this, "this"));
  362.         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  363.         --base();
  364.         return *this;
  365.       }
  366.  
  367.       /**
  368.        *  @brief Iterator postdecrement
  369.        *  @pre iterator is decrementable
  370.        */
  371.       _Safe_iterator
  372.       operator--(int) _GLIBCXX_NOEXCEPT
  373.       {
  374.         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  375.                               _M_message(__msg_bad_dec)
  376.                               ._M_iterator(*this, "this"));
  377.         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  378.         return _Safe_iterator(base()--, this->_M_sequence, _Attach_single());
  379.       }
  380.  
  381.       // ------ Random access iterator requirements ------
  382.       reference
  383.       operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
  384.       {
  385.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
  386.                               && this->_M_can_advance(__n+1),
  387.                               _M_message(__msg_iter_subscript_oob)
  388.                               ._M_iterator(*this)._M_integer(__n));
  389.         return base()[__n];
  390.       }
  391.  
  392.       _Safe_iterator&
  393.       operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
  394.       {
  395.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
  396.                               _M_message(__msg_advance_oob)
  397.                               ._M_iterator(*this)._M_integer(__n));
  398.         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  399.         base() += __n;
  400.         return *this;
  401.       }
  402.  
  403.       _Safe_iterator
  404.       operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
  405.       {
  406.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
  407.                               _M_message(__msg_advance_oob)
  408.                               ._M_iterator(*this)._M_integer(__n));
  409.         return _Safe_iterator(base() + __n, this->_M_sequence);
  410.       }
  411.  
  412.       _Safe_iterator&
  413.       operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
  414.       {
  415.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
  416.                               _M_message(__msg_retreat_oob)
  417.                               ._M_iterator(*this)._M_integer(__n));
  418.         __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
  419.         base() -= __n;
  420.         return *this;
  421.       }
  422.  
  423.       _Safe_iterator
  424.       operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
  425.       {
  426.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
  427.                               _M_message(__msg_retreat_oob)
  428.                               ._M_iterator(*this)._M_integer(__n));
  429.         return _Safe_iterator(base() - __n, this->_M_sequence);
  430.       }
  431.  
  432.       // ------ Utilities ------
  433.       /**
  434.        * @brief Return the underlying iterator
  435.        */
  436.       _Iterator&
  437.       base() _GLIBCXX_NOEXCEPT { return *this; }
  438.  
  439.       const _Iterator&
  440.       base() const _GLIBCXX_NOEXCEPT { return *this; }
  441.  
  442.       /**
  443.        * @brief Conversion to underlying non-debug iterator to allow
  444.        * better interaction with non-debug containers.
  445.        */
  446.       operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
  447.  
  448.       /** Attach iterator to the given sequence. */
  449.       void
  450.       _M_attach(_Safe_sequence_base* __seq)
  451.       { _Safe_base::_M_attach(__seq, _M_constant()); }
  452.  
  453.       /** Likewise, but not thread-safe. */
  454.       void
  455.       _M_attach_single(_Safe_sequence_base* __seq)
  456.       { _Safe_base::_M_attach_single(__seq, _M_constant()); }
  457.  
  458.       /// Is the iterator dereferenceable?
  459.       bool
  460.       _M_dereferenceable() const
  461.       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
  462.  
  463.       /// Is the iterator before a dereferenceable one?
  464.       bool
  465.       _M_before_dereferenceable() const
  466.       {
  467.         if (this->_M_incrementable())
  468.         {
  469.           _Iterator __base = base();
  470.           return ++__base != _M_get_sequence()->_M_base().end();
  471.         }
  472.         return false;
  473.       }
  474.  
  475.       /// Is the iterator incrementable?
  476.       bool
  477.       _M_incrementable() const
  478.       { return !this->_M_singular() && !_M_is_end(); }
  479.  
  480.       // Is the iterator decrementable?
  481.       bool
  482.       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
  483.  
  484.       // Can we advance the iterator @p __n steps (@p __n may be negative)
  485.       bool
  486.       _M_can_advance(const difference_type& __n) const;
  487.  
  488.       // Is the iterator range [*this, __rhs) valid?
  489.       bool
  490.       _M_valid_range(const _Safe_iterator& __rhs) const;
  491.  
  492.       // The sequence this iterator references.
  493.       typename
  494.       __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
  495.                                                     _Safe_iterator>::__value,
  496.                                     const _Sequence*,
  497.                                     _Sequence*>::__type
  498.       _M_get_sequence() const
  499.       { return static_cast<_Sequence*>(_M_sequence); }
  500.  
  501.       /// Is this iterator equal to the sequence's begin() iterator?
  502.       bool
  503.       _M_is_begin() const
  504.       { return base() == _M_get_sequence()->_M_base().begin(); }
  505.  
  506.       /// Is this iterator equal to the sequence's end() iterator?
  507.       bool
  508.       _M_is_end() const
  509.       { return base() == _M_get_sequence()->_M_base().end(); }
  510.  
  511.       /// Is this iterator equal to the sequence's before_begin() iterator if
  512.       /// any?
  513.       bool
  514.       _M_is_before_begin() const
  515.       { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
  516.  
  517.       /// Is this iterator equal to the sequence's before_begin() iterator if
  518.       /// any or begin() otherwise?
  519.       bool
  520.       _M_is_beginnest() const
  521.       { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
  522.     };
  523.  
  524.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  525.     inline bool
  526.     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  527.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  528.     _GLIBCXX_NOEXCEPT
  529.     {
  530.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  531.                             _M_message(__msg_iter_compare_bad)
  532.                             ._M_iterator(__lhs, "lhs")
  533.                             ._M_iterator(__rhs, "rhs"));
  534.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  535.                             _M_message(__msg_compare_different)
  536.                             ._M_iterator(__lhs, "lhs")
  537.                             ._M_iterator(__rhs, "rhs"));
  538.       return __lhs.base() == __rhs.base();
  539.     }
  540.  
  541.   template<typename _Iterator, typename _Sequence>
  542.     inline bool
  543.     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  544.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  545.     _GLIBCXX_NOEXCEPT
  546.     {
  547.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  548.                             _M_message(__msg_iter_compare_bad)
  549.                             ._M_iterator(__lhs, "lhs")
  550.                             ._M_iterator(__rhs, "rhs"));
  551.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  552.                             _M_message(__msg_compare_different)
  553.                             ._M_iterator(__lhs, "lhs")
  554.                             ._M_iterator(__rhs, "rhs"));
  555.       return __lhs.base() == __rhs.base();
  556.     }
  557.  
  558.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  559.     inline bool
  560.     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  561.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  562.     _GLIBCXX_NOEXCEPT
  563.     {
  564.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  565.                             _M_message(__msg_iter_compare_bad)
  566.                             ._M_iterator(__lhs, "lhs")
  567.                             ._M_iterator(__rhs, "rhs"));
  568.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  569.                             _M_message(__msg_compare_different)
  570.                             ._M_iterator(__lhs, "lhs")
  571.                             ._M_iterator(__rhs, "rhs"));
  572.       return __lhs.base() != __rhs.base();
  573.     }
  574.  
  575.   template<typename _Iterator, typename _Sequence>
  576.     inline bool
  577.     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  578.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  579.     _GLIBCXX_NOEXCEPT
  580.     {
  581.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  582.                             _M_message(__msg_iter_compare_bad)
  583.                             ._M_iterator(__lhs, "lhs")
  584.                             ._M_iterator(__rhs, "rhs"));
  585.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  586.                             _M_message(__msg_compare_different)
  587.                             ._M_iterator(__lhs, "lhs")
  588.                             ._M_iterator(__rhs, "rhs"));
  589.       return __lhs.base() != __rhs.base();
  590.     }
  591.  
  592.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  593.     inline bool
  594.     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  595.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  596.     _GLIBCXX_NOEXCEPT
  597.     {
  598.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  599.                             _M_message(__msg_iter_order_bad)
  600.                             ._M_iterator(__lhs, "lhs")
  601.                             ._M_iterator(__rhs, "rhs"));
  602.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  603.                             _M_message(__msg_order_different)
  604.                             ._M_iterator(__lhs, "lhs")
  605.                             ._M_iterator(__rhs, "rhs"));
  606.       return __lhs.base() < __rhs.base();
  607.     }
  608.  
  609.   template<typename _Iterator, typename _Sequence>
  610.     inline bool
  611.     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  612.               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  613.     _GLIBCXX_NOEXCEPT
  614.     {
  615.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  616.                             _M_message(__msg_iter_order_bad)
  617.                             ._M_iterator(__lhs, "lhs")
  618.                             ._M_iterator(__rhs, "rhs"));
  619.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  620.                             _M_message(__msg_order_different)
  621.                             ._M_iterator(__lhs, "lhs")
  622.                             ._M_iterator(__rhs, "rhs"));
  623.       return __lhs.base() < __rhs.base();
  624.     }
  625.  
  626.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  627.     inline bool
  628.     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  629.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  630.     _GLIBCXX_NOEXCEPT
  631.     {
  632.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  633.                             _M_message(__msg_iter_order_bad)
  634.                             ._M_iterator(__lhs, "lhs")
  635.                             ._M_iterator(__rhs, "rhs"));
  636.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  637.                             _M_message(__msg_order_different)
  638.                             ._M_iterator(__lhs, "lhs")
  639.                             ._M_iterator(__rhs, "rhs"));
  640.       return __lhs.base() <= __rhs.base();
  641.     }
  642.  
  643.   template<typename _Iterator, typename _Sequence>
  644.     inline bool
  645.     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  646.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  647.     _GLIBCXX_NOEXCEPT
  648.     {
  649.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  650.                             _M_message(__msg_iter_order_bad)
  651.                             ._M_iterator(__lhs, "lhs")
  652.                             ._M_iterator(__rhs, "rhs"));
  653.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  654.                             _M_message(__msg_order_different)
  655.                             ._M_iterator(__lhs, "lhs")
  656.                             ._M_iterator(__rhs, "rhs"));
  657.       return __lhs.base() <= __rhs.base();
  658.     }
  659.  
  660.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  661.     inline bool
  662.     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  663.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  664.     _GLIBCXX_NOEXCEPT
  665.     {
  666.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  667.                             _M_message(__msg_iter_order_bad)
  668.                             ._M_iterator(__lhs, "lhs")
  669.                             ._M_iterator(__rhs, "rhs"));
  670.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  671.                             _M_message(__msg_order_different)
  672.                             ._M_iterator(__lhs, "lhs")
  673.                             ._M_iterator(__rhs, "rhs"));
  674.       return __lhs.base() > __rhs.base();
  675.     }
  676.  
  677.   template<typename _Iterator, typename _Sequence>
  678.     inline bool
  679.     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  680.               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  681.     _GLIBCXX_NOEXCEPT
  682.     {
  683.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  684.                             _M_message(__msg_iter_order_bad)
  685.                             ._M_iterator(__lhs, "lhs")
  686.                             ._M_iterator(__rhs, "rhs"));
  687.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  688.                             _M_message(__msg_order_different)
  689.                             ._M_iterator(__lhs, "lhs")
  690.                             ._M_iterator(__rhs, "rhs"));
  691.       return __lhs.base() > __rhs.base();
  692.     }
  693.  
  694.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  695.     inline bool
  696.     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  697.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  698.     _GLIBCXX_NOEXCEPT
  699.     {
  700.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  701.                             _M_message(__msg_iter_order_bad)
  702.                             ._M_iterator(__lhs, "lhs")
  703.                             ._M_iterator(__rhs, "rhs"));
  704.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  705.                             _M_message(__msg_order_different)
  706.                             ._M_iterator(__lhs, "lhs")
  707.                             ._M_iterator(__rhs, "rhs"));
  708.       return __lhs.base() >= __rhs.base();
  709.     }
  710.  
  711.   template<typename _Iterator, typename _Sequence>
  712.     inline bool
  713.     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  714.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  715.     _GLIBCXX_NOEXCEPT
  716.     {
  717.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  718.                             _M_message(__msg_iter_order_bad)
  719.                             ._M_iterator(__lhs, "lhs")
  720.                             ._M_iterator(__rhs, "rhs"));
  721.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  722.                             _M_message(__msg_order_different)
  723.                             ._M_iterator(__lhs, "lhs")
  724.                             ._M_iterator(__rhs, "rhs"));
  725.       return __lhs.base() >= __rhs.base();
  726.     }
  727.  
  728.   // _GLIBCXX_RESOLVE_LIB_DEFECTS
  729.   // According to the resolution of DR179 not only the various comparison
  730.   // operators but also operator- must accept mixed iterator/const_iterator
  731.   // parameters.
  732.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  733.     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
  734.     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  735.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  736.     _GLIBCXX_NOEXCEPT
  737.     {
  738.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  739.                             _M_message(__msg_distance_bad)
  740.                             ._M_iterator(__lhs, "lhs")
  741.                             ._M_iterator(__rhs, "rhs"));
  742.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  743.                             _M_message(__msg_distance_different)
  744.                             ._M_iterator(__lhs, "lhs")
  745.                             ._M_iterator(__rhs, "rhs"));
  746.       return __lhs.base() - __rhs.base();
  747.     }
  748.  
  749.    template<typename _Iterator, typename _Sequence>
  750.      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
  751.      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  752.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  753.     _GLIBCXX_NOEXCEPT
  754.      {
  755.        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  756.                              _M_message(__msg_distance_bad)
  757.                              ._M_iterator(__lhs, "lhs")
  758.                              ._M_iterator(__rhs, "rhs"));
  759.        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  760.                              _M_message(__msg_distance_different)
  761.                              ._M_iterator(__lhs, "lhs")
  762.                              ._M_iterator(__rhs, "rhs"));
  763.        return __lhs.base() - __rhs.base();
  764.      }
  765.  
  766.   template<typename _Iterator, typename _Sequence>
  767.     inline _Safe_iterator<_Iterator, _Sequence>
  768.     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
  769.               const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
  770.     { return __i + __n; }
  771. } // namespace __gnu_debug
  772.  
  773. #include <debug/safe_iterator.tcc>
  774.  
  775. #endif
  776.