29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
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
41 typedef _Sequence_traits<_Sequence> _SeqTraits;
46 return std::make_pair(0, __dp_exact);
49 return _SeqTraits::_S_size(*_M_get_sequence());
51 typename _Distance_traits<_Iterator>::__type __res
54 if (__res.second == __dp_equality)
55 return std::make_pair(1, __dp_sign);
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
65 typedef _Sequence_traits<_Sequence> _SeqTraits;
70 return _SeqTraits::_S_size(*_M_get_sequence());
73 return std::make_pair(0, __dp_exact);
75 typename _Distance_traits<_Iterator>::__type __res
78 if (__res.second == __dp_equality)
79 return std::make_pair(1, __dp_sign);
84 template<
typename _Iterator,
typename _Sequence,
typename _Category>
86 _Safe_iterator<_Iterator, _Sequence, _Category>::
87 _M_can_advance(difference_type __n,
bool __strict)
const
89 if (this->_M_singular())
98 _M_get_distance_from_begin();
99 return __dist.
second == __dp_exact
100 ? __dist.
first >= -__n
101 : !__strict && __dist.
first > 0;
106 _M_get_distance_to_end();
107 return __dist.
second == __dp_exact
108 ? __dist.
first >= __n
109 : !__strict && __dist.
first > 0;
113 template<
typename _Iterator,
typename _Sequence,
typename _Category>
114 typename _Distance_traits<_Iterator>::__type
115 _Safe_iterator<_Iterator, _Sequence, _Category>::
116 _M_get_distance_to(
const _Safe_iterator& __rhs)
const
118 typedef typename _Distance_traits<_Iterator>::__type _Dist;
119 typedef _Sequence_traits<_Sequence> _SeqTraits;
122 if (__base_dist.second == __dp_exact)
125 _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
126 if (this->_M_is_before_begin())
128 if (__rhs._M_is_begin())
129 return std::make_pair(1, __dp_exact);
131 return __seq_dist.second == __dp_exact
132 ? std::make_pair(__seq_dist.first + 1, __dp_exact)
136 if (this->_M_is_begin())
138 if (__rhs._M_is_before_begin())
139 return std::make_pair(-1, __dp_exact);
141 if (__rhs._M_is_end())
144 return std::make_pair(__seq_dist.first,
145 __seq_dist.second == __dp_exact
146 ? __dp_sign_max_size : __seq_dist.second);
149 if (this->_M_is_end())
151 if (__rhs._M_is_before_begin())
152 return __seq_dist.second == __dp_exact
153 ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
154 :
std::make_pair(-__seq_dist.first, __dp_sign);
156 if (__rhs._M_is_begin())
157 return std::make_pair(-__seq_dist.first, __seq_dist.second);
159 return std::make_pair(-__seq_dist.first,
160 __seq_dist.second == __dp_exact
161 ? __dp_sign_max_size : __seq_dist.second);
164 if (__rhs._M_is_before_begin())
165 return __seq_dist.second == __dp_exact
166 ? std::make_pair(__seq_dist.first - 1, __dp_exact)
167 :
std::make_pair(-__seq_dist.first, __dp_sign);
169 if (__rhs._M_is_begin())
170 return std::make_pair(-__seq_dist.first,
171 __seq_dist.second == __dp_exact
172 ? __dp_sign_max_size : __seq_dist.second);
174 if (__rhs._M_is_end())
175 return std::make_pair(__seq_dist.first,
176 __seq_dist.second == __dp_exact
177 ? __dp_sign_max_size : __seq_dist.second);
179 return std::make_pair(1, __dp_equality);
182 template<
typename _Iterator,
typename _Sequence,
typename _Category>
184 _Safe_iterator<_Iterator, _Sequence, _Category>::
185 _M_valid_range(
const _Safe_iterator& __rhs,
187 bool __check_dereferenceable)
const
189 if (!_M_can_compare(__rhs))
193 __dist = _M_get_distance_to(__rhs);
197 if (__dist.
first == 0)
204 if (__dist.
first > 0)
205 return !__check_dereferenceable || _M_dereferenceable();
206 return __dist.
first == 0;
213 template<
typename _Iterator,
typename _Sequence>
215 _Safe_iterator<_Iterator, _Sequence, std::random_access_iterator_tag>::
216 _M_valid_range(
const _Safe_iterator& __rhs,
220 if (!this->_M_can_compare(__rhs))
224 __dist = std::make_pair(__rhs.base() - this->base(), __dp_exact);
227 if (__dist.
first > 0)
228 return this->_M_dereferenceable();
229 return __dist.
first == 0;
233 namespace std _GLIBCXX_VISIBILITY(default)
235 _GLIBCXX_BEGIN_NAMESPACE_VERSION
237 template<
typename _Ite,
typename _Seq>
239 __niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
241 {
return __it.base(); }
243 template<
bool _IsMove,
244 typename _Ite,
typename _Seq,
typename _Cat,
typename _OI>
247 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
248 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
251 typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
252 __glibcxx_check_valid_range2(__first, __last, __dist);
253 __glibcxx_check_can_increment(__result, __dist.first);
255 if (__dist.second > ::__gnu_debug::__dp_equality)
256 return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
259 return std::__copy_move_a1<_IsMove>(__first, __last, __result);
262 template<
bool _IsMove,
263 typename _II,
typename _Ite,
typename _Seq,
typename _Cat>
265 __copy_move_a(_II __first, _II __last,
266 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
268 typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
269 __glibcxx_check_valid_range2(__first, __last, __dist);
270 __glibcxx_check_can_increment(__result, __dist.first);
272 if (__dist.second > ::__gnu_debug::__dp_sign
273 && __result._M_can_advance(__dist.first,
true))
274 return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
275 std::__copy_move_a<_IsMove>(__first, __last, __result.base()),
276 __result._M_sequence);
278 return std::__copy_move_a1<_IsMove>(__first, __last, __result);
281 template<
bool _IsMove,
282 typename _IIte,
typename _ISeq,
typename _ICat,
283 typename _OIte,
typename _OSeq,
typename _OCat>
286 const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
287 const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
288 const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
290 typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
291 __glibcxx_check_valid_range2(__first, __last, __dist);
292 __glibcxx_check_can_increment(__result, __dist.first);
294 if (__dist.second > ::__gnu_debug::__dp_equality)
296 if (__dist.second > ::__gnu_debug::__dp_sign
297 && __result._M_can_advance(__dist.first,
true))
298 return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
299 std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
301 __result._M_sequence);
303 return std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
307 return std::__copy_move_a1<_IsMove>(__first, __last, __result);
310 template<
bool _IsMove,
311 typename _Ite,
typename _Seq,
typename _Cat,
typename _OI>
313 __copy_move_backward_a(
314 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
315 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
318 typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
319 __glibcxx_check_valid_range2(__first, __last, __dist);
320 __glibcxx_check_can_increment(__result, -__dist.first);
322 if (__dist.second > ::__gnu_debug::__dp_equality)
323 return std::__copy_move_backward_a<_IsMove>(
324 __first.base(), __last.base(), __result);
326 return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
329 template<
bool _IsMove,
330 typename _II,
typename _Ite,
typename _Seq,
typename _Cat>
332 __copy_move_backward_a(_II __first, _II __last,
333 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result)
335 typename ::__gnu_debug::_Distance_traits<_II>::__type __dist;
336 __glibcxx_check_valid_range2(__first, __last, __dist);
337 __glibcxx_check_can_increment(__result, -__dist.first);
339 if (__dist.second > ::__gnu_debug::__dp_sign
340 && __result._M_can_advance(-__dist.first,
true))
341 return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
342 std::__copy_move_backward_a<_IsMove>(__first, __last,
344 __result._M_sequence);
346 return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
349 template<
bool _IsMove,
350 typename _IIte,
typename _ISeq,
typename _ICat,
351 typename _OIte,
typename _OSeq,
typename _OCat>
353 __copy_move_backward_a(
354 const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first,
355 const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last,
356 const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result)
358 typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist;
359 __glibcxx_check_valid_range2(__first, __last, __dist);
360 __glibcxx_check_can_increment(__result, -__dist.first);
362 if (__dist.second > ::__gnu_debug::__dp_equality)
364 if (__dist.second > ::__gnu_debug::__dp_sign
365 && __result._M_can_advance(-__dist.first,
true))
366 return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
367 std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(),
369 __result._M_sequence);
371 return std::__copy_move_backward_a<_IsMove>(
372 __first.base(), __last.base(), __result);
375 return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result);
378 template<
typename _Ite,
typename _Seq,
typename _Cat,
typename _Tp>
380 __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
381 const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last,
384 typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist;
385 __glibcxx_check_valid_range2(__first, __last, __dist);
387 if (__dist.second > ::__gnu_debug::__dp_equality)
388 std::__fill_a(__first.base(), __last.base(), __value);
390 std::__fill_a1(__first, __last, __value);
393 template<
typename _Ite,
typename _Seq,
typename _Cat,
typename _Size,
396 __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first,
397 _Size __n,
const _Tp& __value,
400 #if __cplusplus >= 201103L
401 static_assert(is_integral<_Size>{},
"fill_n must pass integral size");
407 __glibcxx_check_can_increment(__first, __n);
408 if (__first._M_can_advance(__n,
true))
409 return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
410 std::__fill_n_a(__first.base(), __n, __value, _Cat()),
411 __first._M_sequence);
413 return std::__fill_n_a1(__first, __n, __value);
416 template<
typename _II1,
typename _Seq1,
typename _Cat1,
typename _II2>
419 const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
420 const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
423 typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
424 __glibcxx_check_valid_range2(__first1, __last1, __dist);
425 __glibcxx_check_can_increment(__first2, __dist.first);
427 if (__dist.second > ::__gnu_debug::__dp_equality)
428 return std::__equal_aux(__first1.base(), __last1.base(), __first2);
430 return std::__equal_aux1(__first1, __last1, __first2);
433 template<
typename _II1,
typename _II2,
typename _Seq2,
typename _Cat2>
435 __equal_aux(_II1 __first1, _II1 __last1,
436 const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
438 typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
439 __glibcxx_check_valid_range2(__first1, __last1, __dist);
440 __glibcxx_check_can_increment(__first2, __dist.first);
442 if (__dist.second > ::__gnu_debug::__dp_sign
443 && __first2._M_can_advance(__dist.first,
true))
444 return std::__equal_aux(__first1, __last1, __first2.base());
446 return std::__equal_aux1(__first1, __last1, __first2);
449 template<
typename _II1,
typename _Seq1,
typename _Cat1,
450 typename _II2,
typename _Seq2,
typename _Cat2>
453 const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1,
454 const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1,
455 const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2)
457 typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist;
458 __glibcxx_check_valid_range2(__first1, __last1, __dist);
459 __glibcxx_check_can_increment(__first2, __dist.first);
461 if (__dist.second > ::__gnu_debug::__dp_equality)
463 if (__dist.second > ::__gnu_debug::__dp_sign &&
464 __first2._M_can_advance(__dist.first,
true))
465 return std::__equal_aux(__first1.base(), __last1.base(),
467 return std::__equal_aux(__first1.base(), __last1.base(), __first2);
470 return __equal_aux1(__first1, __last1, __first2);
473 template<
typename _Ite1,
typename _Seq1,
typename _Cat1,
476 __lexicographical_compare_aux(
477 const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
478 const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
479 _II2 __first2, _II2 __last2)
481 typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
482 __glibcxx_check_valid_range2(__first1, __last1, __dist1);
483 __glibcxx_check_valid_range(__first2, __last2);
485 if (__dist1.second > ::__gnu_debug::__dp_equality)
486 return std::__lexicographical_compare_aux(__first1.base(),
489 return std::__lexicographical_compare_aux1(__first1, __last1,
493 template<
typename _II1,
494 typename _Ite2,
typename _Seq2,
typename _Cat2>
496 __lexicographical_compare_aux(
497 _II1 __first1, _II1 __last1,
498 const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
499 const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
501 __glibcxx_check_valid_range(__first1, __last1);
502 typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist2;
503 __glibcxx_check_valid_range2(__first2, __last2, __dist2);
505 if (__dist2.second > ::__gnu_debug::__dp_equality)
506 return std::__lexicographical_compare_aux(__first1, __last1,
509 return std::__lexicographical_compare_aux1(__first1, __last1,
513 template<
typename _Ite1,
typename _Seq1,
typename _Cat1,
514 typename _Ite2,
typename _Seq2,
typename _Cat2>
516 __lexicographical_compare_aux(
517 const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __first1,
518 const ::__gnu_debug::_Safe_iterator<_Ite1, _Seq1, _Cat1>& __last1,
519 const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __first2,
520 const ::__gnu_debug::_Safe_iterator<_Ite2, _Seq2, _Cat2>& __last2)
522 typename ::__gnu_debug::_Distance_traits<_Ite1>::__type __dist1;
523 __glibcxx_check_valid_range2(__first1, __last1, __dist1);
524 typename ::__gnu_debug::_Distance_traits<_Ite2>::__type __dist2;
525 __glibcxx_check_valid_range2(__first2, __last2, __dist2);
527 if (__dist1.second > ::__gnu_debug::__dp_equality)
529 if (__dist2.second > ::__gnu_debug::__dp_equality)
530 return std::__lexicographical_compare_aux(__first1.base(),
534 return std::__lexicographical_compare_aux(__first1.base(),
539 if (__dist2.second > ::__gnu_debug::__dp_equality)
540 return std::__lexicographical_compare_aux(__first1, __last1,
543 return std::__lexicographical_compare_aux1(__first1, __last1,
547 _GLIBCXX_END_NAMESPACE_VERSION