Home | History | Annotate | Line # | Download | only in debug
      1 // Debugging iterator implementation (out of line) -*- C++ -*-
      2 
      3 // Copyright (C) 2003-2024 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.tcc
     26  *  This file is a GNU debug extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
     30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
     31 
     32 #include <bits/stl_algobase.h>
     33 
     34 namespace __gnu_debug
     35 {
     36   template<typename _Iterator, typename _Sequence, typename _Category>
     37     typename _Distance_traits<_Iterator>::__type
     38     _Safe_iterator<_Iterator, _Sequence, _Category>::
     39     _M_get_distance_from_begin() const
     40     {
     41       typedef _Sequence_traits<_Sequence> _SeqTraits;
     42 
     43       // No need to consider before_begin as this function is only used in
     44       // _M_can_advance which won't be used for forward_list iterators.
     45       if (_M_is_begin())
     46 	return std::make_pair(0, __dp_exact);
     47 
     48       if (_M_is_end())
     49 	return _SeqTraits::_S_size(*_M_get_sequence());
     50 
     51       typename _Distance_traits<_Iterator>::__type __res
     52 	= __get_distance(_M_get_sequence()->_M_base().begin(), base());
     53 
     54       if (__res.second == __dp_equality)
     55 	return std::make_pair(1, __dp_sign);
     56 
     57       return __res;
     58     }
     59 
     60   template<typename _Iterator, typename _Sequence, typename _Category>
     61     typename _Distance_traits<_Iterator>::__type
     62     _Safe_iterator<_Iterator, _Sequence, _Category>::
     63     _M_get_distance_to_end() const
     64     {
     65       typedef _Sequence_traits<_Sequence> _SeqTraits;
     66 
     67       // No need to consider before_begin as this function is only used in
     68       // _M_can_advance which won't be used for forward_list iterators.
     69       if (_M_is_begin())
     70 	return _SeqTraits::_S_size(*_M_get_sequence());
     71 
     72       if (_M_is_end())
     73 	return std::make_pair(0, __dp_exact);
     74 
     75       typename _Distance_traits<_Iterator>::__type __res
     76 	= __get_distance(base(), _M_get_sequence()->_M_base().end());
     77 
     78       if (__res.second == __dp_equality)
     79 	return std::make_pair(1, __dp_sign);
     80 
     81       return __res;
     82     }
     83 
     84   template<typename _Iterator, typename _Sequence, typename _Category>
     85     bool
     86     _Safe_iterator<_Iterator, _Sequence, _Category>::
     87     _M_can_advance(difference_type __n, bool __strict) const
     88     {
     89       if (this->_M_value_initialized() && __n == 0)
     90 	return true;
     91 
     92       if (this->_M_singular())
     93 	return false;
     94 
     95       if (__n == 0)
     96 	return true;
     97 
     98       std::pair<difference_type, _Distance_precision> __dist = __n < 0
     99 	? _M_get_distance_from_begin()
    100 	: _M_get_distance_to_end();
    101 
    102       if (__n < 0)
    103 	__n = -__n;
    104 
    105       return __dist.second > __dp_sign
    106 	? __dist.first >= __n
    107 	: !__strict && __dist.first > 0;
    108     }
    109 
    110   template<typename _Iterator, typename _Sequence, typename _Category>
    111     template<typename _Diff>
    112       bool
    113       _Safe_iterator<_Iterator, _Sequence, _Category>::
    114       _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist,
    115 		     int __way) const
    116       {
    117 	return __dist.second == __dp_exact
    118 	  ? _M_can_advance(__way * __dist.first)
    119 	  : _M_can_advance(__way * (__dist.first == 0
    120 				    ? 0
    121 				    : __dist.first < 0 ? -1 : 1));
    122       }
    123 
    124   template<typename _Iterator, typename _Sequence, typename _Category>
    125     typename _Distance_traits<_Iterator>::__type
    126     _Safe_iterator<_Iterator, _Sequence, _Category>::
    127     _M_get_distance_to(const _Safe_iterator& __rhs) const
    128     {
    129       typedef typename _Distance_traits<_Iterator>::__type _Dist;
    130       typedef _Sequence_traits<_Sequence> _SeqTraits;
    131 
    132       _Dist __base_dist = __get_distance(this->base(), __rhs.base());
    133       if (__base_dist.second == __dp_exact)
    134 	return __base_dist;
    135 
    136       _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
    137       if (this->_M_is_before_begin())
    138 	{
    139 	  if (__rhs._M_is_begin())
    140 	    return std::make_pair(1, __dp_exact);
    141 
    142 	  return __seq_dist.second == __dp_exact
    143 	    ? std::make_pair(__seq_dist.first + 1, __dp_exact)
    144 	    : __seq_dist;
    145 	}
    146 
    147       if (this->_M_is_begin())
    148 	{
    149 	  if (__rhs._M_is_before_begin())
    150 	    return std::make_pair(-1, __dp_exact);
    151 
    152 	  if (__rhs._M_is_end())
    153 	    return __seq_dist;
    154 
    155 	  return std::make_pair(__seq_dist.first,
    156 				__seq_dist.second == __dp_exact
    157 				? __dp_sign_max_size : __seq_dist.second);
    158 	}
    159 
    160       if (this->_M_is_end())
    161 	{
    162 	  if (__rhs._M_is_before_begin())
    163 	    return __seq_dist.second == __dp_exact
    164 	      ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
    165 	      : std::make_pair(-__seq_dist.first, __dp_sign);
    166 
    167 	  if (__rhs._M_is_begin())
    168 	    return std::make_pair(-__seq_dist.first, __seq_dist.second);
    169 
    170 	  return std::make_pair(-__seq_dist.first,
    171 				__seq_dist.second == __dp_exact
    172 				? __dp_sign_max_size : __seq_dist.second);
    173 	}
    174 
    175       if (__rhs._M_is_before_begin())
    176 	return __seq_dist.second == __dp_exact
    177 	  ? std::make_pair(__seq_dist.first - 1, __dp_exact)
    178 	  : std::make_pair(-__seq_dist.first, __dp_sign);
    179 
    180       if (__rhs._M_is_begin())
    181 	return std::make_pair(-__seq_dist.first,
    182 			      __seq_dist.second == __dp_exact
    183 			      ? __dp_sign_max_size : __seq_dist.second);
    184 
    185       if (__rhs._M_is_end())
    186 	return std::make_pair(__seq_dist.first,
    187 			      __seq_dist.second == __dp_exact
    188 			      ? __dp_sign_max_size : __seq_dist.second);
    189 
    190       return std::make_pair(1, __dp_equality);
    191     }
    192 
    193   template<typename _Iterator, typename _Sequence, typename _Category>
    194     bool
    195     _Safe_iterator<_Iterator, _Sequence, _Category>::
    196     _M_valid_range(const _Safe_iterator& __rhs,
    197 		   std::pair<difference_type, _Distance_precision>& __dist,
    198 		   bool __check_dereferenceable) const
    199     {
    200       if (_M_value_initialized() && __rhs._M_value_initialized())
    201 	{
    202 	  __dist = std::make_pair(0, __dp_exact);
    203 	  return true;
    204 	}
    205 
    206       if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs))
    207 	return false;
    208 
    209       /* Determine iterators order */
    210       __dist = _M_get_distance_to(__rhs);
    211       if (__dist.second != __dp_equality)
    212 	{
    213 	  // If range is not empty first iterator must be dereferenceable.
    214 	  return __dist.first == 0
    215 	    || (__dist.first > 0
    216 		&& (!__check_dereferenceable || _M_dereferenceable()));
    217 	}
    218 
    219       // Assume that this is a valid range; we can't check anything else.
    220       return true;
    221     }
    222 
    223   template<typename _Iterator, typename _Sequence>
    224     bool
    225     _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
    226     _M_valid_range(const _Safe_iterator& __rhs,
    227 		   std::pair<difference_type,
    228 			     _Distance_precision>& __dist) const
    229     {
    230       if (this->_M_value_initialized() && __rhs._M_value_initialized())
    231 	{
    232 	  __dist = std::make_pair(0, __dp_exact);
    233 	  return true;
    234 	}
    235 
    236       if (this->_M_singular() || __rhs._M_singular()
    237 	  || !this->_M_can_compare(__rhs))
    238 	return false;
    239 
    240       /* Determine iterators order */
    241       __dist = std::make_pair(__rhs.base() - this->base(), __dp_exact);
    242 
    243       // If range is not empty first iterator must be dereferenceable.
    244       return __dist.first == 0
    245 	|| (__dist.first > 0 && this->_M_dereferenceable());
    246     }
    247 } // namespace __gnu_debug
    248 
    249 namespace std _GLIBCXX_VISIBILITY(default)
    250 {
    251 _GLIBCXX_BEGIN_NAMESPACE_VERSION
    252 
    253 #if __cplusplus < 201103L
    254   template<typename _Ite, typename _Seq>
    255     _Ite
    256     __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
    257 		 std::random_access_iterator_tag>& __it)
    258     { return __it.base(); }
    259 
    260   template<typename _Ite, typename _Cont, typename _DbgSeq>
    261     _Ite
    262     __niter_base(const ::__gnu_debug::_Safe_iterator<
    263 		 ::__gnu_cxx::__normal_iterator<_Ite, _Cont>, _DbgSeq,
    264 		 std::random_access_iterator_tag>& __it)
    265     { return __it.base().base(); }
    266 #else
    267   template<typename _Ite, typename _Seq>
    268     _GLIBCXX20_CONSTEXPR
    269     decltype(std::__niter_base(std::declval<_Ite>()))
    270     __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
    271 		 std::random_access_iterator_tag>& __it)
    272     noexcept(std::is_nothrow_copy_constructible<_Ite>::value)
    273     { return std::__niter_base(__it.base()); }
    274 #endif
    275 
    276   template<bool _IsMove,
    277 	   typename _Ite, typename _Seq, typename _Cat, typename _OI>
    278     _GLIBCXX20_CONSTEXPR
    279     _OI
    280     __copy_move_a(
    281       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
    282       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
    283       _OI __result)
    284     {
    285       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
    286       __glibcxx_check_valid_range2(__first, __last, __dist);
    287       __glibcxx_check_can_increment_dist(__result, __dist, 1);
    288 
    289       if (__dist.second > ::__gnu_debug::__dp_equality)
    290 	return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
    291 					   __result);
    292 
    293       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
    294     }
    295 
    296   template<bool _IsMove,
    297 	   typename _II, typename _Ite, typename _Seq, typename _Cat>
    298     _GLIBCXX20_CONSTEXPR
    299     __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
    300     __copy_move_a(_II __first, _II __last,
    301       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
    302     {
    303       typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
    304       __glibcxx_check_valid_range2(__first, __last, __dist);
    305       __glibcxx_check_can_increment_dist(__result, __dist, 1);
    306 
    307       if (__dist.second > ::__gnu_debug::__dp_sign
    308 	  && __result._M_can_advance(__dist.first, true))
    309 	return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
    310 		std::__copy_move_a<_IsMove>(__first, __last, __result.base()),
    311 		__result._M_sequence);
    312 
    313       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
    314     }
    315 
    316   template<bool _IsMove,
    317 	   typename _IIte, typename _ISeq, typename _ICat,
    318 	   typename _OIte, typename _OSeq, typename _OCat>
    319     _GLIBCXX20_CONSTEXPR
    320     ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
    321     __copy_move_a(
    322       const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
    323       const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
    324       const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
    325     {
    326       typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
    327       __glibcxx_check_valid_range2(__first, __last, __dist);
    328       __glibcxx_check_can_increment_dist(__result, __dist, 1);
    329 
    330       if (__dist.second > ::__gnu_debug::__dp_equality)
    331 	{
    332 	  if (__dist.second > ::__gnu_debug::__dp_sign
    333 	      && __result._M_can_advance(__dist.first, true))
    334 	    return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
    335 	      std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
    336 					  __result.base()),
    337 	      __result._M_sequence);
    338 
    339 	  return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
    340 					     __result);
    341 	}
    342 
    343       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
    344     }
    345 
    346   template<bool _IsMove,
    347 	   typename _Ite, typename _Seq, typename _Cat, typename _OI>
    348     _GLIBCXX20_CONSTEXPR
    349     _OI
    350     __copy_move_backward_a(
    351 		const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
    352 		const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
    353 		_OI __result)
    354     {
    355       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
    356       __glibcxx_check_valid_range2(__first, __last, __dist);
    357       __glibcxx_check_can_increment_dist(__result, __dist, -1);
    358 
    359       if (__dist.second > ::__gnu_debug::__dp_equality)
    360 	return std::__copy_move_backward_a<_IsMove>(
    361 		__first.base(), __last.base(), __result);
    362 
    363       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
    364     }
    365 
    366   template<bool _IsMove,
    367 	   typename _II, typename _Ite, typename _Seq, typename _Cat>
    368     _GLIBCXX20_CONSTEXPR
    369     __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
    370     __copy_move_backward_a(_II __first, _II __last,
    371 	const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
    372     {
    373       typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
    374       __glibcxx_check_valid_range2(__first, __last, __dist);
    375       __glibcxx_check_can_increment_dist(__result, __dist, -1);
    376 
    377       if (__dist.second > ::__gnu_debug::__dp_sign
    378 	  && __result._M_can_advance(-__dist.first, true))
    379 	return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
    380 		std::__copy_move_backward_a<_IsMove>(__first, __last,
    381 						     __result.base()),
    382 		__result._M_sequence);
    383 
    384       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
    385     }
    386 
    387   template<bool _IsMove,
    388 	   typename _IIte, typename _ISeq, typename _ICat,
    389 	   typename _OIte, typename _OSeq, typename _OCat>
    390     _GLIBCXX20_CONSTEXPR
    391     ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
    392     __copy_move_backward_a(
    393 	const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
    394 	const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
    395 	const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
    396     {
    397       typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
    398       __glibcxx_check_valid_range2(__first, __last, __dist);
    399       __glibcxx_check_can_increment_dist(__result, __dist, -1);
    400 
    401       if (__dist.second > ::__gnu_debug::__dp_equality)
    402 	{
    403 	  if (__dist.second > ::__gnu_debug::__dp_sign
    404 	      && __result._M_can_advance(-__dist.first, true))
    405 	    return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
    406 	      std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(),
    407 						   __result.base()),
    408 	      __result._M_sequence);
    409 
    410 	  return std::__copy_move_backward_a<_IsMove>(
    411 	    __first.base(), __last.base(), __result);
    412 	}
    413 
    414       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
    415     }
    416 
    417   template<typename _Ite, typename _Seq, typename _Cat, typename _Tp>
    418     _GLIBCXX20_CONSTEXPR
    419     void
    420     __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
    421 	     const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
    422 	     const _Tp& __value)
    423     {
    424       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
    425       __glibcxx_check_valid_range2(__first, __last, __dist);
    426 
    427       if (__dist.second > ::__gnu_debug::__dp_equality)
    428 	std::__fill_a(__first.base(), __last.base(), __value);
    429 
    430       std::__fill_a1(__first, __last, __value);
    431     }
    432 
    433   template<typename _Ite, typename _Seq, typename _Cat, typename _Size,
    434 	   typename _Tp>
    435     _GLIBCXX20_CONSTEXPR
    436     ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
    437     __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
    438 	       _Size __n, const _Tp& __value,
    439 	       std::input_iterator_tag)
    440     {
    441 #if __cplusplus >= 201103L
    442       static_assert(is_integral<_Size>{}, "fill_n must pass integral size");
    443 #endif
    444 
    445       if (__n <= 0)
    446 	return __first;
    447 
    448       __glibcxx_check_can_increment(__first, __n);
    449       if (__first._M_can_advance(__n, true))
    450 	return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
    451 		std::__fill_n_a(__first.base(), __n, __value, _Cat()),
    452 		__first._M_sequence);
    453 
    454       return std::__fill_n_a1(__first, __n, __value);
    455     }
    456 
    457   template<typename _II1, typename _Seq1, typename _Cat1, typename _II2>
    458     _GLIBCXX20_CONSTEXPR
    459     bool
    460     __equal_aux(
    461 	const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
    462 	const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
    463 	_II2 __first2)
    464     {
    465       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
    466       __glibcxx_check_valid_range2(__first1, __last1, __dist);
    467       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
    468 
    469       if (__dist.second > ::__gnu_debug::__dp_equality)
    470 	return std::__equal_aux(__first1.base(), __last1.base(), __first2);
    471 
    472       return std::__equal_aux1(__first1, __last1, __first2);
    473     }
    474 
    475   template<typename _II1, typename _II2, typename _Seq2, typename _Cat2>
    476     _GLIBCXX20_CONSTEXPR
    477     bool
    478     __equal_aux(_II1 __first1, _II1 __last1,
    479 	const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
    480     {
    481       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
    482       __glibcxx_check_valid_range2(__first1, __last1, __dist);
    483       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
    484 
    485       if (__dist.second > ::__gnu_debug::__dp_sign
    486 	  && __first2._M_can_advance(__dist.first, true))
    487 	return std::__equal_aux(__first1, __last1, __first2.base());
    488 
    489       return std::__equal_aux1(__first1, __last1, __first2);
    490     }
    491 
    492   template<typename _II1, typename _Seq1, typename _Cat1,
    493 	   typename _II2, typename _Seq2, typename _Cat2>
    494     _GLIBCXX20_CONSTEXPR
    495     bool
    496     __equal_aux(
    497 	const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
    498 	const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
    499 	const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
    500     {
    501       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
    502       __glibcxx_check_valid_range2(__first1, __last1, __dist);
    503       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
    504 
    505       if (__dist.second > ::__gnu_debug::__dp_equality)
    506 	{
    507 	  if (__dist.second > ::__gnu_debug::__dp_sign &&
    508 	      __first2._M_can_advance(__dist.first, true))
    509 	    return std::__equal_aux(__first1.base(), __last1.base(),
    510 				    __first2.base());
    511 	  return std::__equal_aux(__first1.base(), __last1.base(), __first2);
    512 	}
    513 
    514       return __equal_aux1(__first1, __last1, __first2);
    515     }
    516 
    517   template<typename _Ite1, typename _Seq1, typename _Cat1,
    518 	   typename _II2>
    519     _GLIBCXX20_CONSTEXPR
    520     bool
    521     __lexicographical_compare_aux(
    522 	const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
    523 	const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
    524 	_II2 __first2, _II2 __last2)
    525     {
    526       typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
    527       __glibcxx_check_valid_range2(__first1, __last1, __dist1);
    528       __glibcxx_check_valid_range(__first2, __last2);
    529 
    530       if (__dist1.second > ::__gnu_debug::__dp_equality)
    531 	return std::__lexicographical_compare_aux(__first1.base(),
    532 						  __last1.base(),
    533 						  __first2, __last2);
    534       return std::__lexicographical_compare_aux1(__first1, __last1,
    535 						 __first2, __last2);
    536     }
    537 
    538   template<typename _II1,
    539 	   typename _Ite2, typename _Seq2, typename _Cat2>
    540     _GLIBCXX20_CONSTEXPR
    541     bool
    542     __lexicographical_compare_aux(
    543 	_II1 __first1, _II1 __last1,
    544 	const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
    545 	const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
    546     {
    547       __glibcxx_check_valid_range(__first1, __last1);
    548       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist2;
    549       __glibcxx_check_valid_range2(__first2, __last2, __dist2);
    550 
    551       if (__dist2.second > ::__gnu_debug::__dp_equality)
    552 	return std::__lexicographical_compare_aux(__first1, __last1,
    553 						  __first2.base(),
    554 						  __last2.base());
    555       return std::__lexicographical_compare_aux1(__first1, __last1,
    556 						 __first2, __last2);
    557     }
    558 
    559   template<typename _Ite1, typename _Seq1, typename _Cat1,
    560 	   typename _Ite2, typename _Seq2, typename _Cat2>
    561     _GLIBCXX20_CONSTEXPR
    562     bool
    563     __lexicographical_compare_aux(
    564 	const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
    565 	const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
    566 	const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
    567 	const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
    568     {
    569       typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
    570       __glibcxx_check_valid_range2(__first1, __last1, __dist1);
    571       typename ::__gnu_debug::_Distance_traits<_Ite2>::__type __dist2;
    572       __glibcxx_check_valid_range2(__first2, __last2, __dist2);
    573 
    574       if (__dist1.second > ::__gnu_debug::__dp_equality)
    575 	{
    576 	  if (__dist2.second > ::__gnu_debug::__dp_equality)
    577 	    return std::__lexicographical_compare_aux(__first1.base(),
    578 						      __last1.base(),
    579 						      __first2.base(),
    580 						      __last2.base());
    581 	  return std::__lexicographical_compare_aux(__first1.base(),
    582 						    __last1.base(),
    583 						    __first2, __last2);
    584 	}
    585 
    586       if (__dist2.second > ::__gnu_debug::__dp_equality)
    587 	return std::__lexicographical_compare_aux(__first1, __last1,
    588 						  __first2.base(),
    589 						  __last2.base());
    590       return std::__lexicographical_compare_aux1(__first1, __last1,
    591 						 __first2, __last2);
    592     }
    593 
    594 _GLIBCXX_END_NAMESPACE_VERSION
    595 } // namespace std
    596 
    597 #endif
    598