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