safe_iterator.tcc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. // Debugging iterator implementation (out of line) -*- C++ -*-
  2. // Copyright (C) 2003-2023 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file debug/safe_iterator.tcc
  21. * This file is a GNU debug extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
  24. #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
  25. #include <bits/stl_algobase.h>
  26. namespace __gnu_debug
  27. {
  28. template<typename _Iterator, typename _Sequence, typename _Category>
  29. typename _Distance_traits<_Iterator>::__type
  30. _Safe_iterator<_Iterator, _Sequence, _Category>::
  31. _M_get_distance_from_begin() const
  32. {
  33. typedef _Sequence_traits<_Sequence> _SeqTraits;
  34. // No need to consider before_begin as this function is only used in
  35. // _M_can_advance which won't be used for forward_list iterators.
  36. if (_M_is_begin())
  37. return std::make_pair(0, __dp_exact);
  38. if (_M_is_end())
  39. return _SeqTraits::_S_size(*_M_get_sequence());
  40. typename _Distance_traits<_Iterator>::__type __res
  41. = __get_distance(_M_get_sequence()->_M_base().begin(), base());
  42. if (__res.second == __dp_equality)
  43. return std::make_pair(1, __dp_sign);
  44. return __res;
  45. }
  46. template<typename _Iterator, typename _Sequence, typename _Category>
  47. typename _Distance_traits<_Iterator>::__type
  48. _Safe_iterator<_Iterator, _Sequence, _Category>::
  49. _M_get_distance_to_end() const
  50. {
  51. typedef _Sequence_traits<_Sequence> _SeqTraits;
  52. // No need to consider before_begin as this function is only used in
  53. // _M_can_advance which won't be used for forward_list iterators.
  54. if (_M_is_begin())
  55. return _SeqTraits::_S_size(*_M_get_sequence());
  56. if (_M_is_end())
  57. return std::make_pair(0, __dp_exact);
  58. typename _Distance_traits<_Iterator>::__type __res
  59. = __get_distance(base(), _M_get_sequence()->_M_base().end());
  60. if (__res.second == __dp_equality)
  61. return std::make_pair(1, __dp_sign);
  62. return __res;
  63. }
  64. template<typename _Iterator, typename _Sequence, typename _Category>
  65. bool
  66. _Safe_iterator<_Iterator, _Sequence, _Category>::
  67. _M_can_advance(difference_type __n, bool __strict) const
  68. {
  69. if (this->_M_value_initialized() && __n == 0)
  70. return true;
  71. if (this->_M_singular())
  72. return false;
  73. if (__n == 0)
  74. return true;
  75. std::pair<difference_type, _Distance_precision> __dist = __n < 0
  76. ? _M_get_distance_from_begin()
  77. : _M_get_distance_to_end();
  78. if (__n < 0)
  79. __n = -__n;
  80. return __dist.second > __dp_sign
  81. ? __dist.first >= __n
  82. : !__strict && __dist.first > 0;
  83. }
  84. template<typename _Iterator, typename _Sequence, typename _Category>
  85. template<typename _Diff>
  86. bool
  87. _Safe_iterator<_Iterator, _Sequence, _Category>::
  88. _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist,
  89. int __way) const
  90. {
  91. return __dist.second == __dp_exact
  92. ? _M_can_advance(__way * __dist.first)
  93. : _M_can_advance(__way * (__dist.first == 0
  94. ? 0
  95. : __dist.first < 0 ? -1 : 1));
  96. }
  97. template<typename _Iterator, typename _Sequence, typename _Category>
  98. typename _Distance_traits<_Iterator>::__type
  99. _Safe_iterator<_Iterator, _Sequence, _Category>::
  100. _M_get_distance_to(const _Safe_iterator& __rhs) const
  101. {
  102. typedef typename _Distance_traits<_Iterator>::__type _Dist;
  103. typedef _Sequence_traits<_Sequence> _SeqTraits;
  104. _Dist __base_dist = __get_distance(this->base(), __rhs.base());
  105. if (__base_dist.second == __dp_exact)
  106. return __base_dist;
  107. _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
  108. if (this->_M_is_before_begin())
  109. {
  110. if (__rhs._M_is_begin())
  111. return std::make_pair(1, __dp_exact);
  112. return __seq_dist.second == __dp_exact
  113. ? std::make_pair(__seq_dist.first + 1, __dp_exact)
  114. : __seq_dist;
  115. }
  116. if (this->_M_is_begin())
  117. {
  118. if (__rhs._M_is_before_begin())
  119. return std::make_pair(-1, __dp_exact);
  120. if (__rhs._M_is_end())
  121. return __seq_dist;
  122. return std::make_pair(__seq_dist.first,
  123. __seq_dist.second == __dp_exact
  124. ? __dp_sign_max_size : __seq_dist.second);
  125. }
  126. if (this->_M_is_end())
  127. {
  128. if (__rhs._M_is_before_begin())
  129. return __seq_dist.second == __dp_exact
  130. ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
  131. : std::make_pair(-__seq_dist.first, __dp_sign);
  132. if (__rhs._M_is_begin())
  133. return std::make_pair(-__seq_dist.first, __seq_dist.second);
  134. return std::make_pair(-__seq_dist.first,
  135. __seq_dist.second == __dp_exact
  136. ? __dp_sign_max_size : __seq_dist.second);
  137. }
  138. if (__rhs._M_is_before_begin())
  139. return __seq_dist.second == __dp_exact
  140. ? std::make_pair(__seq_dist.first - 1, __dp_exact)
  141. : std::make_pair(-__seq_dist.first, __dp_sign);
  142. if (__rhs._M_is_begin())
  143. return std::make_pair(-__seq_dist.first,
  144. __seq_dist.second == __dp_exact
  145. ? __dp_sign_max_size : __seq_dist.second);
  146. if (__rhs._M_is_end())
  147. return std::make_pair(__seq_dist.first,
  148. __seq_dist.second == __dp_exact
  149. ? __dp_sign_max_size : __seq_dist.second);
  150. return std::make_pair(1, __dp_equality);
  151. }
  152. template<typename _Iterator, typename _Sequence, typename _Category>
  153. bool
  154. _Safe_iterator<_Iterator, _Sequence, _Category>::
  155. _M_valid_range(const _Safe_iterator& __rhs,
  156. std::pair<difference_type, _Distance_precision>& __dist,
  157. bool __check_dereferenceable) const
  158. {
  159. if (_M_value_initialized() && __rhs._M_value_initialized())
  160. {
  161. __dist = std::make_pair(0, __dp_exact);
  162. return true;
  163. }
  164. if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs))
  165. return false;
  166. /* Determine iterators order */
  167. __dist = _M_get_distance_to(__rhs);
  168. if (__dist.second != __dp_equality)
  169. {
  170. // If range is not empty first iterator must be dereferenceable.
  171. return __dist.first == 0
  172. || (__dist.first > 0
  173. && (!__check_dereferenceable || _M_dereferenceable()));
  174. }
  175. // Assume that this is a valid range; we can't check anything else.
  176. return true;
  177. }
  178. template<typename _Iterator, typename _Sequence>
  179. bool
  180. _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
  181. _M_valid_range(const _Safe_iterator& __rhs,
  182. std::pair<difference_type,
  183. _Distance_precision>& __dist) const
  184. {
  185. if (this->_M_value_initialized() && __rhs._M_value_initialized())
  186. {
  187. __dist = std::make_pair(0, __dp_exact);
  188. return true;
  189. }
  190. if (this->_M_singular() || __rhs._M_singular()
  191. || !this->_M_can_compare(__rhs))
  192. return false;
  193. /* Determine iterators order */
  194. __dist = std::make_pair(__rhs.base() - this->base(), __dp_exact);
  195. // If range is not empty first iterator must be dereferenceable.
  196. return __dist.first == 0
  197. || (__dist.first > 0 && this->_M_dereferenceable());
  198. }
  199. } // namespace __gnu_debug
  200. namespace std _GLIBCXX_VISIBILITY(default)
  201. {
  202. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  203. template<typename _Ite, typename _Seq>
  204. _Ite
  205. __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
  206. std::random_access_iterator_tag>& __it)
  207. { return __it.base(); }
  208. template<bool _IsMove,
  209. typename _Ite, typename _Seq, typename _Cat, typename _OI>
  210. _OI
  211. __copy_move_a(
  212. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
  213. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
  214. _OI __result)
  215. {
  216. typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
  217. __glibcxx_check_valid_range2(__first, __last, __dist);
  218. __glibcxx_check_can_increment_dist(__result, __dist, 1);
  219. if (__dist.second > ::__gnu_debug::__dp_equality)
  220. return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
  221. __result);
  222. return std::__copy_move_a1<_IsMove>(__first, __last, __result);
  223. }
  224. template<bool _IsMove,
  225. typename _II, typename _Ite, typename _Seq, typename _Cat>
  226. __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
  227. __copy_move_a(_II __first, _II __last,
  228. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
  229. {
  230. typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
  231. __glibcxx_check_valid_range2(__first, __last, __dist);
  232. __glibcxx_check_can_increment_dist(__result, __dist, 1);
  233. if (__dist.second > ::__gnu_debug::__dp_sign
  234. && __result._M_can_advance(__dist.first, true))
  235. return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
  236. std::__copy_move_a<_IsMove>(__first, __last, __result.base()),
  237. __result._M_sequence);
  238. return std::__copy_move_a1<_IsMove>(__first, __last, __result);
  239. }
  240. template<bool _IsMove,
  241. typename _IIte, typename _ISeq, typename _ICat,
  242. typename _OIte, typename _OSeq, typename _OCat>
  243. ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
  244. __copy_move_a(
  245. const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
  246. const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
  247. const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
  248. {
  249. typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
  250. __glibcxx_check_valid_range2(__first, __last, __dist);
  251. __glibcxx_check_can_increment_dist(__result, __dist, 1);
  252. if (__dist.second > ::__gnu_debug::__dp_equality)
  253. {
  254. if (__dist.second > ::__gnu_debug::__dp_sign
  255. && __result._M_can_advance(__dist.first, true))
  256. return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
  257. std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
  258. __result.base()),
  259. __result._M_sequence);
  260. return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
  261. __result);
  262. }
  263. return std::__copy_move_a1<_IsMove>(__first, __last, __result);
  264. }
  265. template<bool _IsMove,
  266. typename _Ite, typename _Seq, typename _Cat, typename _OI>
  267. _OI
  268. __copy_move_backward_a(
  269. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
  270. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
  271. _OI __result)
  272. {
  273. typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
  274. __glibcxx_check_valid_range2(__first, __last, __dist);
  275. __glibcxx_check_can_increment_dist(__result, __dist, -1);
  276. if (__dist.second > ::__gnu_debug::__dp_equality)
  277. return std::__copy_move_backward_a<_IsMove>(
  278. __first.base(), __last.base(), __result);
  279. return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
  280. }
  281. template<bool _IsMove,
  282. typename _II, typename _Ite, typename _Seq, typename _Cat>
  283. __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
  284. __copy_move_backward_a(_II __first, _II __last,
  285. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
  286. {
  287. typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
  288. __glibcxx_check_valid_range2(__first, __last, __dist);
  289. __glibcxx_check_can_increment_dist(__result, __dist, -1);
  290. if (__dist.second > ::__gnu_debug::__dp_sign
  291. && __result._M_can_advance(-__dist.first, true))
  292. return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
  293. std::__copy_move_backward_a<_IsMove>(__first, __last,
  294. __result.base()),
  295. __result._M_sequence);
  296. return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
  297. }
  298. template<bool _IsMove,
  299. typename _IIte, typename _ISeq, typename _ICat,
  300. typename _OIte, typename _OSeq, typename _OCat>
  301. ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
  302. __copy_move_backward_a(
  303. const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
  304. const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
  305. const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
  306. {
  307. typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
  308. __glibcxx_check_valid_range2(__first, __last, __dist);
  309. __glibcxx_check_can_increment_dist(__result, __dist, -1);
  310. if (__dist.second > ::__gnu_debug::__dp_equality)
  311. {
  312. if (__dist.second > ::__gnu_debug::__dp_sign
  313. && __result._M_can_advance(-__dist.first, true))
  314. return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
  315. std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(),
  316. __result.base()),
  317. __result._M_sequence);
  318. return std::__copy_move_backward_a<_IsMove>(
  319. __first.base(), __last.base(), __result);
  320. }
  321. return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
  322. }
  323. template<typename _Ite, typename _Seq, typename _Cat, typename _Tp>
  324. void
  325. __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
  326. const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
  327. const _Tp& __value)
  328. {
  329. typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
  330. __glibcxx_check_valid_range2(__first, __last, __dist);
  331. if (__dist.second > ::__gnu_debug::__dp_equality)
  332. std::__fill_a(__first.base(), __last.base(), __value);
  333. std::__fill_a1(__first, __last, __value);
  334. }
  335. template<typename _Ite, typename _Seq, typename _Cat, typename _Size,
  336. typename _Tp>
  337. ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
  338. __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
  339. _Size __n, const _Tp& __value,
  340. std::input_iterator_tag)
  341. {
  342. #if __cplusplus >= 201103L
  343. static_assert(is_integral<_Size>{}, "fill_n must pass integral size");
  344. #endif
  345. if (__n <= 0)
  346. return __first;
  347. __glibcxx_check_can_increment(__first, __n);
  348. if (__first._M_can_advance(__n, true))
  349. return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
  350. std::__fill_n_a(__first.base(), __n, __value, _Cat()),
  351. __first._M_sequence);
  352. return std::__fill_n_a1(__first, __n, __value);
  353. }
  354. template<typename _II1, typename _Seq1, typename _Cat1, typename _II2>
  355. bool
  356. __equal_aux(
  357. const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
  358. const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
  359. _II2 __first2)
  360. {
  361. typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
  362. __glibcxx_check_valid_range2(__first1, __last1, __dist);
  363. __glibcxx_check_can_increment_dist(__first2, __dist, 1);
  364. if (__dist.second > ::__gnu_debug::__dp_equality)
  365. return std::__equal_aux(__first1.base(), __last1.base(), __first2);
  366. return std::__equal_aux1(__first1, __last1, __first2);
  367. }
  368. template<typename _II1, typename _II2, typename _Seq2, typename _Cat2>
  369. bool
  370. __equal_aux(_II1 __first1, _II1 __last1,
  371. const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
  372. {
  373. typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
  374. __glibcxx_check_valid_range2(__first1, __last1, __dist);
  375. __glibcxx_check_can_increment_dist(__first2, __dist, 1);
  376. if (__dist.second > ::__gnu_debug::__dp_sign
  377. && __first2._M_can_advance(__dist.first, true))
  378. return std::__equal_aux(__first1, __last1, __first2.base());
  379. return std::__equal_aux1(__first1, __last1, __first2);
  380. }
  381. template<typename _II1, typename _Seq1, typename _Cat1,
  382. typename _II2, typename _Seq2, typename _Cat2>
  383. bool
  384. __equal_aux(
  385. const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
  386. const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
  387. const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
  388. {
  389. typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
  390. __glibcxx_check_valid_range2(__first1, __last1, __dist);
  391. __glibcxx_check_can_increment_dist(__first2, __dist, 1);
  392. if (__dist.second > ::__gnu_debug::__dp_equality)
  393. {
  394. if (__dist.second > ::__gnu_debug::__dp_sign &&
  395. __first2._M_can_advance(__dist.first, true))
  396. return std::__equal_aux(__first1.base(), __last1.base(),
  397. __first2.base());
  398. return std::__equal_aux(__first1.base(), __last1.base(), __first2);
  399. }
  400. return __equal_aux1(__first1, __last1, __first2);
  401. }
  402. template<typename _Ite1, typename _Seq1, typename _Cat1,
  403. typename _II2>
  404. bool
  405. __lexicographical_compare_aux(
  406. const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
  407. const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
  408. _II2 __first2, _II2 __last2)
  409. {
  410. typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
  411. __glibcxx_check_valid_range2(__first1, __last1, __dist1);
  412. __glibcxx_check_valid_range(__first2, __last2);
  413. if (__dist1.second > ::__gnu_debug::__dp_equality)
  414. return std::__lexicographical_compare_aux(__first1.base(),
  415. __last1.base(),
  416. __first2, __last2);
  417. return std::__lexicographical_compare_aux1(__first1, __last1,
  418. __first2, __last2);
  419. }
  420. template<typename _II1,
  421. typename _Ite2, typename _Seq2, typename _Cat2>
  422. bool
  423. __lexicographical_compare_aux(
  424. _II1 __first1, _II1 __last1,
  425. const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
  426. const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
  427. {
  428. __glibcxx_check_valid_range(__first1, __last1);
  429. typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist2;
  430. __glibcxx_check_valid_range2(__first2, __last2, __dist2);
  431. if (__dist2.second > ::__gnu_debug::__dp_equality)
  432. return std::__lexicographical_compare_aux(__first1, __last1,
  433. __first2.base(),
  434. __last2.base());
  435. return std::__lexicographical_compare_aux1(__first1, __last1,
  436. __first2, __last2);
  437. }
  438. template<typename _Ite1, typename _Seq1, typename _Cat1,
  439. typename _Ite2, typename _Seq2, typename _Cat2>
  440. bool
  441. __lexicographical_compare_aux(
  442. const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
  443. const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
  444. const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
  445. const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
  446. {
  447. typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
  448. __glibcxx_check_valid_range2(__first1, __last1, __dist1);
  449. typename ::__gnu_debug::_Distance_traits<_Ite2>::__type __dist2;
  450. __glibcxx_check_valid_range2(__first2, __last2, __dist2);
  451. if (__dist1.second > ::__gnu_debug::__dp_equality)
  452. {
  453. if (__dist2.second > ::__gnu_debug::__dp_equality)
  454. return std::__lexicographical_compare_aux(__first1.base(),
  455. __last1.base(),
  456. __first2.base(),
  457. __last2.base());
  458. return std::__lexicographical_compare_aux(__first1.base(),
  459. __last1.base(),
  460. __first2, __last2);
  461. }
  462. if (__dist2.second > ::__gnu_debug::__dp_equality)
  463. return std::__lexicographical_compare_aux(__first1, __last1,
  464. __first2.base(),
  465. __last2.base());
  466. return std::__lexicographical_compare_aux1(__first1, __last1,
  467. __first2, __last2);
  468. }
  469. _GLIBCXX_END_NAMESPACE_VERSION
  470. } // namespace std
  471. #endif