https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114316

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
For a debug mode _Safe_iterator pair __valid_range uses this overload:

  template<typename _Iterator, typename _Sequence, typename _Category>
    inline bool
    __valid_range(const _Safe_iterator<_Iterator, _Sequence,
                                       _Category>& __first,
                  const _Safe_iterator<_Iterator, _Sequence,
                                       _Category>& __last)
    {
      typename _Distance_traits<_Iterator>::__type __dist;
      return __first._M_valid_range(__last, __dist);
    }


Which calls:

  template<typename _Iterator, typename _Sequence, typename _Category>
    bool
    _Safe_iterator<_Iterator, _Sequence, _Category>::
    _M_valid_range(const _Safe_iterator& __rhs,
                   std::pair<difference_type, _Distance_precision>& __dist,
                   bool __check_dereferenceable) const
    {
      if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs))
        return false;

So it doesn't consider whether the range is empty.

For non-debug mode iterators we have:

  template<typename _InputIterator>
    _GLIBCXX_CONSTEXPR
    inline bool
    __valid_range_aux(_InputIterator __first, _InputIterator __last,
                      std::input_iterator_tag)
    {
      return __first == __last
        || (!__gnu_debug::__check_singular(__first)
              && !__gnu_debug::__check_singular(__last));
    }

which gets it right.

Reply via email to