Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Safe iterator implementation  -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2013 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.       typedef typename _Sequence::const_iterator _It;
  48.       typedef typename _It::iterator_type _BaseIt;
  49.  
  50.       static bool
  51.       _S_Is(_BaseIt, const _Sequence*)
  52.       { return false; }
  53.  
  54.       static bool
  55.       _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
  56.       { return __it == __seq->_M_base().begin(); }
  57.     };
  58.  
  59.   /** Iterators that derive from _Safe_iterator_base but that aren't
  60.    *  _Safe_iterators can be determined singular or non-singular via
  61.    *  _Safe_iterator_base.
  62.    */
  63.   inline bool
  64.   __check_singular_aux(const _Safe_iterator_base* __x)
  65.   { return __x->_M_singular(); }
  66.  
  67.   /** The precision to which we can calculate the distance between
  68.    *  two iterators.
  69.    */
  70.   enum _Distance_precision
  71.     {
  72.       __dp_equality, //< Can compare iterator equality, only
  73.       __dp_sign,     //< Can determine equality and ordering
  74.       __dp_exact     //< Can determine distance precisely
  75.     };
  76.  
  77.   /** Determine the distance between two iterators with some known
  78.    *    precision.
  79.   */
  80.   template<typename _Iterator1, typename _Iterator2>
  81.     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
  82.                      _Distance_precision>
  83.     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
  84.                    std::random_access_iterator_tag)
  85.     { return std::make_pair(__rhs - __lhs, __dp_exact); }
  86.  
  87.   template<typename _Iterator1, typename _Iterator2>
  88.     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
  89.                      _Distance_precision>
  90.     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
  91.                    std::forward_iterator_tag)
  92.     { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
  93.  
  94.   template<typename _Iterator1, typename _Iterator2>
  95.     inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
  96.                      _Distance_precision>
  97.     __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
  98.     {
  99.       typedef typename std::iterator_traits<_Iterator1>::iterator_category
  100.           _Category;
  101.       return __get_distance(__lhs, __rhs, _Category());
  102.     }
  103.  
  104.   /** \brief Safe iterator wrapper.
  105.    *
  106.    *  The class template %_Safe_iterator is a wrapper around an
  107.    *  iterator that tracks the iterator's movement among sequences and
  108.    *  checks that operations performed on the "safe" iterator are
  109.    *  legal. In additional to the basic iterator operations (which are
  110.    *  validated, and then passed to the underlying iterator),
  111.    *  %_Safe_iterator has member functions for iterator invalidation,
  112.    *  attaching/detaching the iterator from sequences, and querying
  113.    *  the iterator's state.
  114.    */
  115.   template<typename _Iterator, typename _Sequence>
  116.     class _Safe_iterator : public _Safe_iterator_base
  117.     {
  118.       typedef _Safe_iterator _Self;
  119.  
  120.       /// The underlying iterator
  121.       _Iterator _M_current;
  122.  
  123.       /// Determine if this is a constant iterator.
  124.       bool
  125.       _M_constant() const
  126.       {
  127.         typedef typename _Sequence::const_iterator const_iterator;
  128.         return std::__are_same<const_iterator, _Safe_iterator>::__value;
  129.       }
  130.  
  131.       typedef std::iterator_traits<_Iterator> _Traits;
  132.  
  133.     public:
  134.       typedef _Iterator                           iterator_type;
  135.       typedef typename _Traits::iterator_category iterator_category;
  136.       typedef typename _Traits::value_type        value_type;
  137.       typedef typename _Traits::difference_type   difference_type;
  138.       typedef typename _Traits::reference         reference;
  139.       typedef typename _Traits::pointer           pointer;
  140.  
  141.       /// @post the iterator is singular and unattached
  142.       _Safe_iterator() : _M_current() { }
  143.  
  144.       /**
  145.        * @brief Safe iterator construction from an unsafe iterator and
  146.        * its sequence.
  147.        *
  148.        * @pre @p seq is not NULL
  149.        * @post this is not singular
  150.        */
  151.       _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
  152.       : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
  153.       {
  154.         _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
  155.                               _M_message(__msg_init_singular)
  156.                               ._M_iterator(*this, "this"));
  157.       }
  158.  
  159.       /**
  160.        * @brief Copy construction.
  161.        */
  162.       _Safe_iterator(const _Safe_iterator& __x)
  163.       : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
  164.       {
  165.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  166.         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  167.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  168.                               || __x._M_current == _Iterator(),
  169.                               _M_message(__msg_init_copy_singular)
  170.                               ._M_iterator(*this, "this")
  171.                               ._M_iterator(__x, "other"));
  172.       }
  173.  
  174. #if __cplusplus >= 201103L
  175.       /**
  176.        * @brief Move construction.
  177.        * @post __x is singular and unattached
  178.        */
  179.       _Safe_iterator(_Safe_iterator&& __x) : _M_current()
  180.       {
  181.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  182.                               || __x._M_current == _Iterator(),
  183.                               _M_message(__msg_init_copy_singular)
  184.                               ._M_iterator(*this, "this")
  185.                               ._M_iterator(__x, "other"));
  186.         std::swap(_M_current, __x._M_current);
  187.         this->_M_attach(__x._M_sequence);
  188.         __x._M_detach();
  189.       }
  190. #endif
  191.  
  192.       /**
  193.        *  @brief Converting constructor from a mutable iterator to a
  194.        *  constant iterator.
  195.       */
  196.       template<typename _MutableIterator>
  197.         _Safe_iterator(
  198.           const _Safe_iterator<_MutableIterator,
  199.           typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
  200.                       typename _Sequence::iterator::iterator_type>::__value),
  201.                    _Sequence>::__type>& __x)
  202.         : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
  203.         {
  204.           // _GLIBCXX_RESOLVE_LIB_DEFECTS
  205.           // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  206.           _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  207.                                 || __x.base() == _Iterator(),
  208.                                 _M_message(__msg_init_const_singular)
  209.                                 ._M_iterator(*this, "this")
  210.                                 ._M_iterator(__x, "other"));
  211.         }
  212.  
  213.       /**
  214.        * @brief Copy assignment.
  215.        */
  216.       _Safe_iterator&
  217.       operator=(const _Safe_iterator& __x)
  218.       {
  219.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  220.         // DR 408. Is vector<reverse_iterator<char*> > forbidden?
  221.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  222.                               || __x._M_current == _Iterator(),
  223.                               _M_message(__msg_copy_singular)
  224.                               ._M_iterator(*this, "this")
  225.                               ._M_iterator(__x, "other"));
  226.         _M_current = __x._M_current;
  227.         this->_M_attach(__x._M_sequence);
  228.         return *this;
  229.       }
  230.  
  231. #if __cplusplus >= 201103L
  232.       /**
  233.        * @brief Move assignment.
  234.        * @post __x is singular and unattached
  235.        */
  236.       _Safe_iterator&
  237.       operator=(_Safe_iterator&& __x)
  238.       {
  239.         _GLIBCXX_DEBUG_VERIFY(this != &__x,
  240.                               _M_message(__msg_self_move_assign)
  241.                               ._M_iterator(*this, "this"));
  242.         _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
  243.                               || __x._M_current == _Iterator(),
  244.                               _M_message(__msg_copy_singular)
  245.                               ._M_iterator(*this, "this")
  246.                               ._M_iterator(__x, "other"));
  247.         _M_current = __x._M_current;
  248.         _M_attach(__x._M_sequence);
  249.         __x._M_detach();
  250.         __x._M_current = _Iterator();
  251.         return *this;
  252.       }
  253. #endif
  254.  
  255.       /**
  256.        *  @brief Iterator dereference.
  257.        *  @pre iterator is dereferenceable
  258.        */
  259.       reference
  260.       operator*() const
  261.       {
  262.         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  263.                               _M_message(__msg_bad_deref)
  264.                               ._M_iterator(*this, "this"));
  265.         return *_M_current;
  266.       }
  267.  
  268.       /**
  269.        *  @brief Iterator dereference.
  270.        *  @pre iterator is dereferenceable
  271.        *  @todo Make this correct w.r.t. iterators that return proxies
  272.        *  @todo Use addressof() instead of & operator
  273.        */
  274.       pointer
  275.       operator->() const
  276.       {
  277.         _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
  278.                               _M_message(__msg_bad_deref)
  279.                               ._M_iterator(*this, "this"));
  280.         return &*_M_current;
  281.       }
  282.  
  283.       // ------ Input iterator requirements ------
  284.       /**
  285.        *  @brief Iterator preincrement
  286.        *  @pre iterator is incrementable
  287.        */
  288.       _Safe_iterator&
  289.       operator++()
  290.       {
  291.         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  292.                               _M_message(__msg_bad_inc)
  293.                               ._M_iterator(*this, "this"));
  294.         ++_M_current;
  295.         return *this;
  296.       }
  297.  
  298.       /**
  299.        *  @brief Iterator postincrement
  300.        *  @pre iterator is incrementable
  301.        */
  302.       _Safe_iterator
  303.       operator++(int)
  304.       {
  305.         _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
  306.                               _M_message(__msg_bad_inc)
  307.                               ._M_iterator(*this, "this"));
  308.         _Safe_iterator __tmp(*this);
  309.         ++_M_current;
  310.         return __tmp;
  311.       }
  312.  
  313.       // ------ Bidirectional iterator requirements ------
  314.       /**
  315.        *  @brief Iterator predecrement
  316.        *  @pre iterator is decrementable
  317.        */
  318.       _Safe_iterator&
  319.       operator--()
  320.       {
  321.         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  322.                               _M_message(__msg_bad_dec)
  323.                               ._M_iterator(*this, "this"));
  324.         --_M_current;
  325.         return *this;
  326.       }
  327.  
  328.       /**
  329.        *  @brief Iterator postdecrement
  330.        *  @pre iterator is decrementable
  331.        */
  332.       _Safe_iterator
  333.       operator--(int)
  334.       {
  335.         _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
  336.                               _M_message(__msg_bad_dec)
  337.                               ._M_iterator(*this, "this"));
  338.         _Safe_iterator __tmp(*this);
  339.         --_M_current;
  340.         return __tmp;
  341.       }
  342.  
  343.       // ------ Random access iterator requirements ------
  344.       reference
  345.       operator[](const difference_type& __n) const
  346.       {
  347.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
  348.                               && this->_M_can_advance(__n+1),
  349.                               _M_message(__msg_iter_subscript_oob)
  350.                               ._M_iterator(*this)._M_integer(__n));
  351.  
  352.         return _M_current[__n];
  353.       }
  354.  
  355.       _Safe_iterator&
  356.       operator+=(const difference_type& __n)
  357.       {
  358.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
  359.                               _M_message(__msg_advance_oob)
  360.                               ._M_iterator(*this)._M_integer(__n));
  361.         _M_current += __n;
  362.         return *this;
  363.       }
  364.  
  365.       _Safe_iterator
  366.       operator+(const difference_type& __n) const
  367.       {
  368.         _Safe_iterator __tmp(*this);
  369.         __tmp += __n;
  370.         return __tmp;
  371.       }
  372.  
  373.       _Safe_iterator&
  374.       operator-=(const difference_type& __n)
  375.       {
  376.         _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
  377.                               _M_message(__msg_retreat_oob)
  378.                               ._M_iterator(*this)._M_integer(__n));
  379.         _M_current += -__n;
  380.         return *this;
  381.       }
  382.  
  383.       _Safe_iterator
  384.       operator-(const difference_type& __n) const
  385.       {
  386.         _Safe_iterator __tmp(*this);
  387.         __tmp -= __n;
  388.         return __tmp;
  389.       }
  390.  
  391.       // ------ Utilities ------
  392.       /**
  393.        * @brief Return the underlying iterator
  394.        */
  395.       _Iterator
  396.       base() const { return _M_current; }
  397.  
  398.       /**
  399.        * @brief Conversion to underlying non-debug iterator to allow
  400.        * better interaction with non-debug containers.
  401.        */
  402.       operator _Iterator() const { return _M_current; }
  403.  
  404.       /** Attach iterator to the given sequence. */
  405.       void
  406.       _M_attach(_Safe_sequence_base* __seq)
  407.       {
  408.         _Safe_iterator_base::_M_attach(__seq, _M_constant());
  409.       }
  410.  
  411.       /** Likewise, but not thread-safe. */
  412.       void
  413.       _M_attach_single(_Safe_sequence_base* __seq)
  414.       {
  415.         _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
  416.       }
  417.  
  418.       /// Is the iterator dereferenceable?
  419.       bool
  420.       _M_dereferenceable() const
  421.       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
  422.  
  423.       /// Is the iterator before a dereferenceable one?
  424.       bool
  425.       _M_before_dereferenceable() const
  426.       {
  427.         if (this->_M_incrementable())
  428.         {
  429.           _Iterator __base = base();
  430.           return ++__base != _M_get_sequence()->_M_base().end();
  431.         }
  432.         return false;
  433.       }
  434.  
  435.       /// Is the iterator incrementable?
  436.       bool
  437.       _M_incrementable() const
  438.       { return !this->_M_singular() && !_M_is_end(); }
  439.  
  440.       // Is the iterator decrementable?
  441.       bool
  442.       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
  443.  
  444.       // Can we advance the iterator @p __n steps (@p __n may be negative)
  445.       bool
  446.       _M_can_advance(const difference_type& __n) const;
  447.  
  448.       // Is the iterator range [*this, __rhs) valid?
  449.       template<typename _Other>
  450.         bool
  451.         _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
  452.  
  453.       // The sequence this iterator references.
  454.       const _Sequence*
  455.       _M_get_sequence() const
  456.       { return static_cast<const _Sequence*>(_M_sequence); }
  457.  
  458.       /// Is this iterator equal to the sequence's begin() iterator?
  459.       bool _M_is_begin() const
  460.       { return base() == _M_get_sequence()->_M_base().begin(); }
  461.  
  462.       /// Is this iterator equal to the sequence's end() iterator?
  463.       bool _M_is_end() const
  464.       { return base() == _M_get_sequence()->_M_base().end(); }
  465.  
  466.       /// Is this iterator equal to the sequence's before_begin() iterator if
  467.       /// any?
  468.       bool _M_is_before_begin() const
  469.       {
  470.         return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence());
  471.       }
  472.  
  473.       /// Is this iterator equal to the sequence's before_begin() iterator if
  474.       /// any or begin() otherwise?
  475.       bool _M_is_beginnest() const
  476.       {
  477.         return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(),
  478.                                                           _M_get_sequence());
  479.       }
  480.     };
  481.  
  482.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  483.     inline bool
  484.     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  485.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  486.     {
  487.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  488.                             _M_message(__msg_iter_compare_bad)
  489.                             ._M_iterator(__lhs, "lhs")
  490.                             ._M_iterator(__rhs, "rhs"));
  491.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  492.                             _M_message(__msg_compare_different)
  493.                             ._M_iterator(__lhs, "lhs")
  494.                             ._M_iterator(__rhs, "rhs"));
  495.       return __lhs.base() == __rhs.base();
  496.     }
  497.  
  498.   template<typename _Iterator, typename _Sequence>
  499.     inline bool
  500.     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  501.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  502.     {
  503.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  504.                             _M_message(__msg_iter_compare_bad)
  505.                             ._M_iterator(__lhs, "lhs")
  506.                             ._M_iterator(__rhs, "rhs"));
  507.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  508.                             _M_message(__msg_compare_different)
  509.                             ._M_iterator(__lhs, "lhs")
  510.                             ._M_iterator(__rhs, "rhs"));
  511.       return __lhs.base() == __rhs.base();
  512.     }
  513.  
  514.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  515.     inline bool
  516.     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  517.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  518.     {
  519.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  520.                             _M_message(__msg_iter_compare_bad)
  521.                             ._M_iterator(__lhs, "lhs")
  522.                             ._M_iterator(__rhs, "rhs"));
  523.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  524.                             _M_message(__msg_compare_different)
  525.                             ._M_iterator(__lhs, "lhs")
  526.                             ._M_iterator(__rhs, "rhs"));
  527.       return __lhs.base() != __rhs.base();
  528.     }
  529.  
  530.   template<typename _Iterator, typename _Sequence>
  531.     inline bool
  532.     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  533.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  534.     {
  535.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  536.                             _M_message(__msg_iter_compare_bad)
  537.                             ._M_iterator(__lhs, "lhs")
  538.                             ._M_iterator(__rhs, "rhs"));
  539.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  540.                             _M_message(__msg_compare_different)
  541.                             ._M_iterator(__lhs, "lhs")
  542.                             ._M_iterator(__rhs, "rhs"));
  543.       return __lhs.base() != __rhs.base();
  544.     }
  545.  
  546.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  547.     inline bool
  548.     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  549.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  550.     {
  551.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  552.                             _M_message(__msg_iter_order_bad)
  553.                             ._M_iterator(__lhs, "lhs")
  554.                             ._M_iterator(__rhs, "rhs"));
  555.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  556.                             _M_message(__msg_order_different)
  557.                             ._M_iterator(__lhs, "lhs")
  558.                             ._M_iterator(__rhs, "rhs"));
  559.       return __lhs.base() < __rhs.base();
  560.     }
  561.  
  562.   template<typename _Iterator, typename _Sequence>
  563.     inline bool
  564.     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  565.               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  566.     {
  567.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  568.                             _M_message(__msg_iter_order_bad)
  569.                             ._M_iterator(__lhs, "lhs")
  570.                             ._M_iterator(__rhs, "rhs"));
  571.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  572.                             _M_message(__msg_order_different)
  573.                             ._M_iterator(__lhs, "lhs")
  574.                             ._M_iterator(__rhs, "rhs"));
  575.       return __lhs.base() < __rhs.base();
  576.     }
  577.  
  578.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  579.     inline bool
  580.     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  581.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  582.     {
  583.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  584.                             _M_message(__msg_iter_order_bad)
  585.                             ._M_iterator(__lhs, "lhs")
  586.                             ._M_iterator(__rhs, "rhs"));
  587.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  588.                             _M_message(__msg_order_different)
  589.                             ._M_iterator(__lhs, "lhs")
  590.                             ._M_iterator(__rhs, "rhs"));
  591.       return __lhs.base() <= __rhs.base();
  592.     }
  593.  
  594.   template<typename _Iterator, typename _Sequence>
  595.     inline bool
  596.     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  597.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  598.     {
  599.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  600.                             _M_message(__msg_iter_order_bad)
  601.                             ._M_iterator(__lhs, "lhs")
  602.                             ._M_iterator(__rhs, "rhs"));
  603.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  604.                             _M_message(__msg_order_different)
  605.                             ._M_iterator(__lhs, "lhs")
  606.                             ._M_iterator(__rhs, "rhs"));
  607.       return __lhs.base() <= __rhs.base();
  608.     }
  609.  
  610.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  611.     inline bool
  612.     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  613.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  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 _Iterator, typename _Sequence>
  627.     inline bool
  628.     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  629.               const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  630.     {
  631.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  632.                             _M_message(__msg_iter_order_bad)
  633.                             ._M_iterator(__lhs, "lhs")
  634.                             ._M_iterator(__rhs, "rhs"));
  635.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  636.                             _M_message(__msg_order_different)
  637.                             ._M_iterator(__lhs, "lhs")
  638.                             ._M_iterator(__rhs, "rhs"));
  639.       return __lhs.base() > __rhs.base();
  640.     }
  641.  
  642.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  643.     inline bool
  644.     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  645.                const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  646.     {
  647.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  648.                             _M_message(__msg_iter_order_bad)
  649.                             ._M_iterator(__lhs, "lhs")
  650.                             ._M_iterator(__rhs, "rhs"));
  651.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  652.                             _M_message(__msg_order_different)
  653.                             ._M_iterator(__lhs, "lhs")
  654.                             ._M_iterator(__rhs, "rhs"));
  655.       return __lhs.base() >= __rhs.base();
  656.     }
  657.  
  658.   template<typename _Iterator, typename _Sequence>
  659.     inline bool
  660.     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  661.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  662.     {
  663.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  664.                             _M_message(__msg_iter_order_bad)
  665.                             ._M_iterator(__lhs, "lhs")
  666.                             ._M_iterator(__rhs, "rhs"));
  667.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  668.                             _M_message(__msg_order_different)
  669.                             ._M_iterator(__lhs, "lhs")
  670.                             ._M_iterator(__rhs, "rhs"));
  671.       return __lhs.base() >= __rhs.base();
  672.     }
  673.  
  674.   // _GLIBCXX_RESOLVE_LIB_DEFECTS
  675.   // According to the resolution of DR179 not only the various comparison
  676.   // operators but also operator- must accept mixed iterator/const_iterator
  677.   // parameters.
  678.   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
  679.     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
  680.     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
  681.               const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
  682.     {
  683.       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  684.                             _M_message(__msg_distance_bad)
  685.                             ._M_iterator(__lhs, "lhs")
  686.                             ._M_iterator(__rhs, "rhs"));
  687.       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  688.                             _M_message(__msg_distance_different)
  689.                             ._M_iterator(__lhs, "lhs")
  690.                             ._M_iterator(__rhs, "rhs"));
  691.       return __lhs.base() - __rhs.base();
  692.     }
  693.  
  694.    template<typename _Iterator, typename _Sequence>
  695.      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
  696.      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
  697.                const _Safe_iterator<_Iterator, _Sequence>& __rhs)
  698.      {
  699.        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
  700.                              _M_message(__msg_distance_bad)
  701.                              ._M_iterator(__lhs, "lhs")
  702.                              ._M_iterator(__rhs, "rhs"));
  703.        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
  704.                              _M_message(__msg_distance_different)
  705.                              ._M_iterator(__lhs, "lhs")
  706.                              ._M_iterator(__rhs, "rhs"));
  707.        return __lhs.base() - __rhs.base();
  708.      }
  709.  
  710.   template<typename _Iterator, typename _Sequence>
  711.     inline _Safe_iterator<_Iterator, _Sequence>
  712.     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
  713.               const _Safe_iterator<_Iterator, _Sequence>& __i)
  714.     { return __i + __n; }
  715. } // namespace __gnu_debug
  716.  
  717. #include <debug/safe_iterator.tcc>
  718.  
  719. #endif
  720.