1 // Debugging iterator implementation (out of line) -*- C++ -*-
2 
3 // Copyright (C) 2003-2022 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>::
_M_get_distance_from_begin() const39     _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>::
_M_get_distance_to_end() const63     _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>::
_M_can_advance(difference_type __n,bool __strict) const87     _M_can_advance(difference_type __n, bool __strict) const
88     {
89       if (this->_M_singular())
90           return false;
91 
92       if (__n == 0)
93           return true;
94 
95       std::pair<difference_type, _Distance_precision> __dist = __n < 0
96           ? _M_get_distance_from_begin()
97           : _M_get_distance_to_end();
98 
99       if (__n < 0)
100           __n = -__n;
101 
102       return __dist.second > __dp_sign
103           ? __dist.first >= __n
104           : !__strict && __dist.first > 0;
105     }
106 
107   template<typename _Iterator, typename _Sequence, typename _Category>
108     template<typename _Diff>
109       bool
110       _Safe_iterator<_Iterator, _Sequence, _Category>::
_M_can_advance(const std::pair<_Diff,_Distance_precision> & __dist,int __way) const111       _M_can_advance(const std::pair<_Diff, _Distance_precision>& __dist,
112                          int __way) const
113       {
114           return __dist.second == __dp_exact
115             ? _M_can_advance(__way * __dist.first)
116             : _M_can_advance(__way * (__dist.first == 0
117                                             ? 0
118                                             : __dist.first < 0 ? -1 : 1));
119       }
120 
121   template<typename _Iterator, typename _Sequence, typename _Category>
122     typename _Distance_traits<_Iterator>::__type
123     _Safe_iterator<_Iterator, _Sequence, _Category>::
_M_get_distance_to(const _Safe_iterator & __rhs) const124     _M_get_distance_to(const _Safe_iterator& __rhs) const
125     {
126       typedef typename _Distance_traits<_Iterator>::__type _Dist;
127       typedef _Sequence_traits<_Sequence> _SeqTraits;
128 
129       _Dist __base_dist = __get_distance(this->base(), __rhs.base());
130       if (__base_dist.second == __dp_exact)
131           return __base_dist;
132 
133       _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
134       if (this->_M_is_before_begin())
135           {
136             if (__rhs._M_is_begin())
137               return std::make_pair(1, __dp_exact);
138 
139             return __seq_dist.second == __dp_exact
140               ? std::make_pair(__seq_dist.first + 1, __dp_exact)
141               : __seq_dist;
142           }
143 
144       if (this->_M_is_begin())
145           {
146             if (__rhs._M_is_before_begin())
147               return std::make_pair(-1, __dp_exact);
148 
149             if (__rhs._M_is_end())
150               return __seq_dist;
151 
152             return std::make_pair(__seq_dist.first,
153                                         __seq_dist.second == __dp_exact
154                                         ? __dp_sign_max_size : __seq_dist.second);
155           }
156 
157       if (this->_M_is_end())
158           {
159             if (__rhs._M_is_before_begin())
160               return __seq_dist.second == __dp_exact
161                 ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
162                 : std::make_pair(-__seq_dist.first, __dp_sign);
163 
164             if (__rhs._M_is_begin())
165               return std::make_pair(-__seq_dist.first, __seq_dist.second);
166 
167             return std::make_pair(-__seq_dist.first,
168                                         __seq_dist.second == __dp_exact
169                                         ? __dp_sign_max_size : __seq_dist.second);
170           }
171 
172       if (__rhs._M_is_before_begin())
173           return __seq_dist.second == __dp_exact
174             ? std::make_pair(__seq_dist.first - 1, __dp_exact)
175             : std::make_pair(-__seq_dist.first, __dp_sign);
176 
177       if (__rhs._M_is_begin())
178           return std::make_pair(-__seq_dist.first,
179                                     __seq_dist.second == __dp_exact
180                                     ? __dp_sign_max_size : __seq_dist.second);
181 
182       if (__rhs._M_is_end())
183           return std::make_pair(__seq_dist.first,
184                                     __seq_dist.second == __dp_exact
185                                     ? __dp_sign_max_size : __seq_dist.second);
186 
187       return std::make_pair(1, __dp_equality);
188     }
189 
190   template<typename _Iterator, typename _Sequence, typename _Category>
191     bool
192     _Safe_iterator<_Iterator, _Sequence, _Category>::
_M_valid_range(const _Safe_iterator & __rhs,std::pair<difference_type,_Distance_precision> & __dist,bool __check_dereferenceable) const193     _M_valid_range(const _Safe_iterator& __rhs,
194                        std::pair<difference_type, _Distance_precision>& __dist,
195                        bool __check_dereferenceable) const
196     {
197       if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs))
198           return false;
199 
200       /* Determine iterators order */
201       __dist = _M_get_distance_to(__rhs);
202       if (__dist.second != __dp_equality)
203           {
204             // If range is not empty first iterator must be dereferenceable.
205             return __dist.first == 0
206               || (__dist.first > 0
207                     && (!__check_dereferenceable || _M_dereferenceable()));
208           }
209 
210       // Assume that this is a valid range; we can't check anything else.
211       return true;
212     }
213 
214   template<typename _Iterator, typename _Sequence>
215     bool
216     _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
_M_valid_range(const _Safe_iterator & __rhs,std::pair<difference_type,_Distance_precision> & __dist) const217     _M_valid_range(const _Safe_iterator& __rhs,
218                        std::pair<difference_type,
219                                    _Distance_precision>& __dist) const
220     {
221       if (this->_M_singular() || __rhs._M_singular()
222             || !this->_M_can_compare(__rhs))
223           return false;
224 
225       /* Determine iterators order */
226       __dist = std::make_pair(__rhs.base() - this->base(), __dp_exact);
227 
228       // If range is not empty first iterator must be dereferenceable.
229       return __dist.first == 0
230           || (__dist.first > 0 && this->_M_dereferenceable());
231     }
232 } // namespace __gnu_debug
233 
234 namespace std _GLIBCXX_VISIBILITY(default)
235 {
236 _GLIBCXX_BEGIN_NAMESPACE_VERSION
237 
238   template<typename _Ite, typename _Seq>
239     _Ite
__niter_base(const::__gnu_debug::_Safe_iterator<_Ite,_Seq,std::random_access_iterator_tag> & __it)240     __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
241                      std::random_access_iterator_tag>& __it)
242     { return __it.base(); }
243 
244   template<bool _IsMove,
245              typename _Ite, typename _Seq, typename _Cat, typename _OI>
246     _OI
__copy_move_a(const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __first,const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __last,_OI __result)247     __copy_move_a(
248       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
249       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
250       _OI __result)
251     {
252       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
253       __glibcxx_check_valid_range2(__first, __last, __dist);
254       __glibcxx_check_can_increment_dist(__result, __dist, 1);
255 
256       if (__dist.second > ::__gnu_debug::__dp_equality)
257           return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
258                                                      __result);
259 
260       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
261     }
262 
263   template<bool _IsMove,
264              typename _II, typename _Ite, typename _Seq, typename _Cat>
265     __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
__copy_move_a(_II __first,_II __last,const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __result)266     __copy_move_a(_II __first, _II __last,
267       const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
268     {
269       typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
270       __glibcxx_check_valid_range2(__first, __last, __dist);
271       __glibcxx_check_can_increment_dist(__result, __dist, 1);
272 
273       if (__dist.second > ::__gnu_debug::__dp_sign
274             && __result._M_can_advance(__dist.first, true))
275           return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
276                     std::__copy_move_a<_IsMove>(__first, __last, __result.base()),
277                     __result._M_sequence);
278 
279       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
280     }
281 
282   template<bool _IsMove,
283              typename _IIte, typename _ISeq, typename _ICat,
284              typename _OIte, typename _OSeq, typename _OCat>
285     ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
__copy_move_a(const::__gnu_debug::_Safe_iterator<_IIte,_ISeq,_ICat> & __first,const::__gnu_debug::_Safe_iterator<_IIte,_ISeq,_ICat> & __last,const::__gnu_debug::_Safe_iterator<_OIte,_OSeq,_OCat> & __result)286     __copy_move_a(
287       const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
288       const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
289       const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
290     {
291       typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
292       __glibcxx_check_valid_range2(__first, __last, __dist);
293       __glibcxx_check_can_increment_dist(__result, __dist, 1);
294 
295       if (__dist.second > ::__gnu_debug::__dp_equality)
296           {
297             if (__dist.second > ::__gnu_debug::__dp_sign
298                 && __result._M_can_advance(__dist.first, true))
299               return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
300                 std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
301                                                     __result.base()),
302                 __result._M_sequence);
303 
304             return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
305                                                        __result);
306           }
307 
308       return std::__copy_move_a1<_IsMove>(__first, __last, __result);
309     }
310 
311   template<bool _IsMove,
312              typename _Ite, typename _Seq, typename _Cat, typename _OI>
313     _OI
__copy_move_backward_a(const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __first,const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __last,_OI __result)314     __copy_move_backward_a(
315                     const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
316                     const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
317                     _OI __result)
318     {
319       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
320       __glibcxx_check_valid_range2(__first, __last, __dist);
321       __glibcxx_check_can_increment_dist(__result, __dist, -1);
322 
323       if (__dist.second > ::__gnu_debug::__dp_equality)
324           return std::__copy_move_backward_a<_IsMove>(
325                     __first.base(), __last.base(), __result);
326 
327       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
328     }
329 
330   template<bool _IsMove,
331              typename _II, typename _Ite, typename _Seq, typename _Cat>
332     __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
__copy_move_backward_a(_II __first,_II __last,const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __result)333     __copy_move_backward_a(_II __first, _II __last,
334           const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
335     {
336       typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
337       __glibcxx_check_valid_range2(__first, __last, __dist);
338       __glibcxx_check_can_increment_dist(__result, __dist, -1);
339 
340       if (__dist.second > ::__gnu_debug::__dp_sign
341             && __result._M_can_advance(-__dist.first, true))
342           return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
343                     std::__copy_move_backward_a<_IsMove>(__first, __last,
344                                                                  __result.base()),
345                     __result._M_sequence);
346 
347       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
348     }
349 
350   template<bool _IsMove,
351              typename _IIte, typename _ISeq, typename _ICat,
352              typename _OIte, typename _OSeq, typename _OCat>
353     ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>
__copy_move_backward_a(const::__gnu_debug::_Safe_iterator<_IIte,_ISeq,_ICat> & __first,const::__gnu_debug::_Safe_iterator<_IIte,_ISeq,_ICat> & __last,const::__gnu_debug::_Safe_iterator<_OIte,_OSeq,_OCat> & __result)354     __copy_move_backward_a(
355           const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
356           const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
357           const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
358     {
359       typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
360       __glibcxx_check_valid_range2(__first, __last, __dist);
361       __glibcxx_check_can_increment_dist(__result, __dist, -1);
362 
363       if (__dist.second > ::__gnu_debug::__dp_equality)
364           {
365             if (__dist.second > ::__gnu_debug::__dp_sign
366                 && __result._M_can_advance(-__dist.first, true))
367               return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
368                 std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(),
369                                                                __result.base()),
370                 __result._M_sequence);
371 
372             return std::__copy_move_backward_a<_IsMove>(
373               __first.base(), __last.base(), __result);
374           }
375 
376       return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
377     }
378 
379   template<typename _Ite, typename _Seq, typename _Cat, typename _Tp>
380     void
__fill_a(const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __first,const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __last,const _Tp & __value)381     __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
382                const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
383                const _Tp& __value)
384     {
385       typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
386       __glibcxx_check_valid_range2(__first, __last, __dist);
387 
388       if (__dist.second > ::__gnu_debug::__dp_equality)
389           std::__fill_a(__first.base(), __last.base(), __value);
390 
391       std::__fill_a1(__first, __last, __value);
392     }
393 
394   template<typename _Ite, typename _Seq, typename _Cat, typename _Size,
395              typename _Tp>
396     ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>
__fill_n_a(const::__gnu_debug::_Safe_iterator<_Ite,_Seq,_Cat> & __first,_Size __n,const _Tp & __value,std::input_iterator_tag)397     __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
398                  _Size __n, const _Tp& __value,
399                  std::input_iterator_tag)
400     {
401 #if __cplusplus >= 201103L
402       static_assert(is_integral<_Size>{}, "fill_n must pass integral size");
403 #endif
404 
405       if (__n <= 0)
406           return __first;
407 
408       __glibcxx_check_can_increment(__first, __n);
409       if (__first._M_can_advance(__n, true))
410           return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
411                     std::__fill_n_a(__first.base(), __n, __value, _Cat()),
412                     __first._M_sequence);
413 
414       return std::__fill_n_a1(__first, __n, __value);
415     }
416 
417   template<typename _II1, typename _Seq1, typename _Cat1, typename _II2>
418     bool
__equal_aux(const::__gnu_debug::_Safe_iterator<_II1,_Seq1,_Cat1> & __first1,const::__gnu_debug::_Safe_iterator<_II1,_Seq1,_Cat1> & __last1,_II2 __first2)419     __equal_aux(
420           const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
421           const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
422           _II2 __first2)
423     {
424       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
425       __glibcxx_check_valid_range2(__first1, __last1, __dist);
426       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
427 
428       if (__dist.second > ::__gnu_debug::__dp_equality)
429           return std::__equal_aux(__first1.base(), __last1.base(), __first2);
430 
431       return std::__equal_aux1(__first1, __last1, __first2);
432     }
433 
434   template<typename _II1, typename _II2, typename _Seq2, typename _Cat2>
435     bool
__equal_aux(_II1 __first1,_II1 __last1,const::__gnu_debug::_Safe_iterator<_II2,_Seq2,_Cat2> & __first2)436     __equal_aux(_II1 __first1, _II1 __last1,
437           const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
438     {
439       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
440       __glibcxx_check_valid_range2(__first1, __last1, __dist);
441       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
442 
443       if (__dist.second > ::__gnu_debug::__dp_sign
444             && __first2._M_can_advance(__dist.first, true))
445           return std::__equal_aux(__first1, __last1, __first2.base());
446 
447       return std::__equal_aux1(__first1, __last1, __first2);
448     }
449 
450   template<typename _II1, typename _Seq1, typename _Cat1,
451              typename _II2, typename _Seq2, typename _Cat2>
452     bool
__equal_aux(const::__gnu_debug::_Safe_iterator<_II1,_Seq1,_Cat1> & __first1,const::__gnu_debug::_Safe_iterator<_II1,_Seq1,_Cat1> & __last1,const::__gnu_debug::_Safe_iterator<_II2,_Seq2,_Cat2> & __first2)453     __equal_aux(
454           const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
455           const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
456           const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
457     {
458       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
459       __glibcxx_check_valid_range2(__first1, __last1, __dist);
460       __glibcxx_check_can_increment_dist(__first2, __dist, 1);
461 
462       if (__dist.second > ::__gnu_debug::__dp_equality)
463           {
464             if (__dist.second > ::__gnu_debug::__dp_sign &&
465                 __first2._M_can_advance(__dist.first, true))
466               return std::__equal_aux(__first1.base(), __last1.base(),
467                                             __first2.base());
468             return std::__equal_aux(__first1.base(), __last1.base(), __first2);
469           }
470 
471       return __equal_aux1(__first1, __last1, __first2);
472     }
473 
474   template<typename _Ite1, typename _Seq1, typename _Cat1,
475              typename _II2>
476     bool
__lexicographical_compare_aux(const::__gnu_debug::_Safe_iterator<_Ite1,_Seq1,_Cat1> & __first1,const::__gnu_debug::_Safe_iterator<_Ite1,_Seq1,_Cat1> & __last1,_II2 __first2,_II2 __last2)477     __lexicographical_compare_aux(
478           const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
479           const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
480           _II2 __first2, _II2 __last2)
481     {
482       typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
483       __glibcxx_check_valid_range2(__first1, __last1, __dist1);
484       __glibcxx_check_valid_range(__first2, __last2);
485 
486       if (__dist1.second > ::__gnu_debug::__dp_equality)
487           return std::__lexicographical_compare_aux(__first1.base(),
488                                                               __last1.base(),
489                                                               __first2, __last2);
490       return std::__lexicographical_compare_aux1(__first1, __last1,
491                                                              __first2, __last2);
492     }
493 
494   template<typename _II1,
495              typename _Ite2, typename _Seq2, typename _Cat2>
496     bool
__lexicographical_compare_aux(_II1 __first1,_II1 __last1,const::__gnu_debug::_Safe_iterator<_Ite2,_Seq2,_Cat2> & __first2,const::__gnu_debug::_Safe_iterator<_Ite2,_Seq2,_Cat2> & __last2)497     __lexicographical_compare_aux(
498           _II1 __first1, _II1 __last1,
499           const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
500           const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
501     {
502       __glibcxx_check_valid_range(__first1, __last1);
503       typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist2;
504       __glibcxx_check_valid_range2(__first2, __last2, __dist2);
505 
506       if (__dist2.second > ::__gnu_debug::__dp_equality)
507           return std::__lexicographical_compare_aux(__first1, __last1,
508                                                               __first2.base(),
509                                                               __last2.base());
510       return std::__lexicographical_compare_aux1(__first1, __last1,
511                                                              __first2, __last2);
512     }
513 
514   template<typename _Ite1, typename _Seq1, typename _Cat1,
515              typename _Ite2, typename _Seq2, typename _Cat2>
516     bool
__lexicographical_compare_aux(const::__gnu_debug::_Safe_iterator<_Ite1,_Seq1,_Cat1> & __first1,const::__gnu_debug::_Safe_iterator<_Ite1,_Seq1,_Cat1> & __last1,const::__gnu_debug::_Safe_iterator<_Ite2,_Seq2,_Cat2> & __first2,const::__gnu_debug::_Safe_iterator<_Ite2,_Seq2,_Cat2> & __last2)517     __lexicographical_compare_aux(
518           const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
519           const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
520           const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
521           const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
522     {
523       typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
524       __glibcxx_check_valid_range2(__first1, __last1, __dist1);
525       typename ::__gnu_debug::_Distance_traits<_Ite2>::__type __dist2;
526       __glibcxx_check_valid_range2(__first2, __last2, __dist2);
527 
528       if (__dist1.second > ::__gnu_debug::__dp_equality)
529           {
530             if (__dist2.second > ::__gnu_debug::__dp_equality)
531               return std::__lexicographical_compare_aux(__first1.base(),
532                                                                   __last1.base(),
533                                                                   __first2.base(),
534                                                                   __last2.base());
535             return std::__lexicographical_compare_aux(__first1.base(),
536                                                                 __last1.base(),
537                                                                 __first2, __last2);
538           }
539 
540       if (__dist2.second > ::__gnu_debug::__dp_equality)
541           return std::__lexicographical_compare_aux(__first1, __last1,
542                                                               __first2.base(),
543                                                               __last2.base());
544       return std::__lexicographical_compare_aux1(__first1, __last1,
545                                                              __first2, __last2);
546     }
547 
548 _GLIBCXX_END_NAMESPACE_VERSION
549 } // namespace std
550 
551 #endif
552