29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 44 template<
typename _Sequence>
47 template<
typename _Iterator>
52 template<
typename _Iterator>
55 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
59 template<
typename _Sequence>
62 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
65 _S_size(
const _Sequence& __seq)
85 template<
typename _Iterator,
typename _Sequence>
90 typedef _Iterator _Iter_base;
92 typedef typename _Sequence::const_iterator _Const_iterator;
97 {
return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
99 typedef std::iterator_traits<_Iterator> _Traits;
101 struct _Attach_single
111 typedef _Iterator iterator_type;
112 typedef typename _Traits::iterator_category iterator_category;
113 typedef typename _Traits::value_type value_type;
114 typedef typename _Traits::difference_type difference_type;
115 typedef typename _Traits::reference reference;
116 typedef typename _Traits::pointer pointer;
130 : _Iter_base(__i),
_Safe_base(__seq, _M_constant())
133 _M_message(__msg_init_singular)
134 ._M_iterator(*
this,
"this"));
141 : _Iter_base(__x.base())
145 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
146 || __x.base() == _Iterator(),
147 _M_message(__msg_init_copy_singular)
148 ._M_iterator(*
this,
"this")
149 ._M_iterator(__x,
"other"));
153 #if __cplusplus >= 201103L 161 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
162 || __x.base() == _Iterator(),
163 _M_message(__msg_init_copy_singular)
164 ._M_iterator(*
this,
"this")
165 ._M_iterator(__x,
"other"));
168 std::swap(
base(), __x.base());
177 template<
typename _MutableIterator>
180 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
181 typename _Sequence::iterator::iterator_type>::__value),
182 _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
183 : _Iter_base(__x.base())
187 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
188 || __x.base() == _Iterator(),
189 _M_message(__msg_init_const_singular)
190 ._M_iterator(*
this,
"this")
191 ._M_iterator(__x,
"other"));
203 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
204 || __x.base() == _Iterator(),
205 _M_message(__msg_copy_singular)
206 ._M_iterator(*
this,
"this")
207 ._M_iterator(__x,
"other"));
225 #if __cplusplus >= 201103L 233 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
234 _M_message(__msg_self_move_assign)
235 ._M_iterator(*
this,
"this"));
236 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
237 || __x.base() == _Iterator(),
238 _M_message(__msg_copy_singular)
239 ._M_iterator(*
this,
"this")
240 ._M_iterator(__x,
"other"));
256 __x.base() = _Iterator();
269 _M_message(__msg_bad_deref)
270 ._M_iterator(*
this,
"this"));
282 _M_message(__msg_bad_deref)
283 ._M_iterator(*
this,
"this"));
284 return base().operator->();
296 _M_message(__msg_bad_inc)
297 ._M_iterator(*
this,
"this"));
311 _M_message(__msg_bad_inc)
312 ._M_iterator(*
this,
"this"));
325 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
326 _M_message(__msg_bad_dec)
327 ._M_iterator(*
this,
"this"));
340 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
341 _M_message(__msg_bad_dec)
342 ._M_iterator(*
this,
"this"));
349 operator[](
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
351 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
352 && this->_M_can_advance(__n+1),
353 _M_message(__msg_iter_subscript_oob)
354 ._M_iterator(*this)._M_integer(__n));
359 operator+=(
const difference_type& __n) _GLIBCXX_NOEXCEPT
361 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
362 _M_message(__msg_advance_oob)
363 ._M_iterator(*this)._M_integer(__n));
370 operator+(
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
372 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
373 _M_message(__msg_advance_oob)
374 ._M_iterator(*this)._M_integer(__n));
379 operator-=(
const difference_type& __n) _GLIBCXX_NOEXCEPT
381 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
382 _M_message(__msg_retreat_oob)
383 ._M_iterator(*this)._M_integer(__n));
390 operator-(
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
392 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
393 _M_message(__msg_retreat_oob)
394 ._M_iterator(*this)._M_integer(__n));
403 base() _GLIBCXX_NOEXCEPT {
return *
this; }
406 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
412 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
435 _Iterator __base =
base();
436 return ++__base != _M_get_sequence()->_M_base().end();
452 _M_can_advance(
const difference_type& __n)
const;
462 __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
466 _M_get_sequence()
const 472 {
return base() == _M_get_sequence()->_M_base().begin(); }
477 {
return base() == _M_get_sequence()->_M_base().end(); }
492 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
494 operator==(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
495 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
498 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
499 _M_message(__msg_iter_compare_bad)
500 ._M_iterator(__lhs,
"lhs")
501 ._M_iterator(__rhs,
"rhs"));
502 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
503 _M_message(__msg_compare_different)
504 ._M_iterator(__lhs,
"lhs")
505 ._M_iterator(__rhs,
"rhs"));
506 return __lhs.base() == __rhs.base();
509 template<
typename _Iterator,
typename _Sequence>
511 operator==(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
512 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
515 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
516 _M_message(__msg_iter_compare_bad)
517 ._M_iterator(__lhs,
"lhs")
518 ._M_iterator(__rhs,
"rhs"));
519 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
520 _M_message(__msg_compare_different)
521 ._M_iterator(__lhs,
"lhs")
522 ._M_iterator(__rhs,
"rhs"));
523 return __lhs.base() == __rhs.base();
526 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
528 operator!=(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
529 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
532 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
533 _M_message(__msg_iter_compare_bad)
534 ._M_iterator(__lhs,
"lhs")
535 ._M_iterator(__rhs,
"rhs"));
536 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
537 _M_message(__msg_compare_different)
538 ._M_iterator(__lhs,
"lhs")
539 ._M_iterator(__rhs,
"rhs"));
540 return __lhs.base() != __rhs.base();
543 template<
typename _Iterator,
typename _Sequence>
545 operator!=(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
546 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
549 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
550 _M_message(__msg_iter_compare_bad)
551 ._M_iterator(__lhs,
"lhs")
552 ._M_iterator(__rhs,
"rhs"));
553 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
554 _M_message(__msg_compare_different)
555 ._M_iterator(__lhs,
"lhs")
556 ._M_iterator(__rhs,
"rhs"));
557 return __lhs.base() != __rhs.base();
560 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
562 operator<(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
563 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
566 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
567 _M_message(__msg_iter_order_bad)
568 ._M_iterator(__lhs,
"lhs")
569 ._M_iterator(__rhs,
"rhs"));
570 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
571 _M_message(__msg_order_different)
572 ._M_iterator(__lhs,
"lhs")
573 ._M_iterator(__rhs,
"rhs"));
574 return __lhs.base() < __rhs.base();
577 template<
typename _Iterator,
typename _Sequence>
579 operator<(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
580 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
583 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
584 _M_message(__msg_iter_order_bad)
585 ._M_iterator(__lhs,
"lhs")
586 ._M_iterator(__rhs,
"rhs"));
587 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
588 _M_message(__msg_order_different)
589 ._M_iterator(__lhs,
"lhs")
590 ._M_iterator(__rhs,
"rhs"));
591 return __lhs.base() < __rhs.base();
594 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
596 operator<=(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
597 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
600 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
601 _M_message(__msg_iter_order_bad)
602 ._M_iterator(__lhs,
"lhs")
603 ._M_iterator(__rhs,
"rhs"));
604 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
605 _M_message(__msg_order_different)
606 ._M_iterator(__lhs,
"lhs")
607 ._M_iterator(__rhs,
"rhs"));
608 return __lhs.base() <= __rhs.base();
611 template<
typename _Iterator,
typename _Sequence>
613 operator<=(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
614 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
617 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
618 _M_message(__msg_iter_order_bad)
619 ._M_iterator(__lhs,
"lhs")
620 ._M_iterator(__rhs,
"rhs"));
621 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
622 _M_message(__msg_order_different)
623 ._M_iterator(__lhs,
"lhs")
624 ._M_iterator(__rhs,
"rhs"));
625 return __lhs.base() <= __rhs.base();
628 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
630 operator>(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
631 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
634 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
635 _M_message(__msg_iter_order_bad)
636 ._M_iterator(__lhs,
"lhs")
637 ._M_iterator(__rhs,
"rhs"));
638 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
639 _M_message(__msg_order_different)
640 ._M_iterator(__lhs,
"lhs")
641 ._M_iterator(__rhs,
"rhs"));
642 return __lhs.base() > __rhs.base();
645 template<
typename _Iterator,
typename _Sequence>
647 operator>(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
648 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
651 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
652 _M_message(__msg_iter_order_bad)
653 ._M_iterator(__lhs,
"lhs")
654 ._M_iterator(__rhs,
"rhs"));
655 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
656 _M_message(__msg_order_different)
657 ._M_iterator(__lhs,
"lhs")
658 ._M_iterator(__rhs,
"rhs"));
659 return __lhs.base() > __rhs.base();
662 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
664 operator>=(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
665 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
668 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
669 _M_message(__msg_iter_order_bad)
670 ._M_iterator(__lhs,
"lhs")
671 ._M_iterator(__rhs,
"rhs"));
672 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
673 _M_message(__msg_order_different)
674 ._M_iterator(__lhs,
"lhs")
675 ._M_iterator(__rhs,
"rhs"));
676 return __lhs.base() >= __rhs.base();
679 template<
typename _Iterator,
typename _Sequence>
681 operator>=(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
682 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
685 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
686 _M_message(__msg_iter_order_bad)
687 ._M_iterator(__lhs,
"lhs")
688 ._M_iterator(__rhs,
"rhs"));
689 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
690 _M_message(__msg_order_different)
691 ._M_iterator(__lhs,
"lhs")
692 ._M_iterator(__rhs,
"rhs"));
693 return __lhs.base() >= __rhs.base();
700 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
701 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
702 operator-(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
703 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
706 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
707 _M_message(__msg_distance_bad)
708 ._M_iterator(__lhs,
"lhs")
709 ._M_iterator(__rhs,
"rhs"));
710 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
711 _M_message(__msg_distance_different)
712 ._M_iterator(__lhs,
"lhs")
713 ._M_iterator(__rhs,
"rhs"));
714 return __lhs.base() - __rhs.base();
717 template<
typename _Iterator,
typename _Sequence>
718 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
719 operator-(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
720 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
723 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
724 _M_message(__msg_distance_bad)
725 ._M_iterator(__lhs,
"lhs")
726 ._M_iterator(__rhs,
"rhs"));
727 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
728 _M_message(__msg_distance_different)
729 ._M_iterator(__lhs,
"lhs")
730 ._M_iterator(__rhs,
"rhs"));
731 return __lhs.base() - __rhs.base();
734 template<
typename _Iterator,
typename _Sequence>
735 inline _Safe_iterator<_Iterator, _Sequence>
736 operator+(
typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
737 const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
738 {
return __i + __n; }
741 template<
typename _Iterator,
typename _Sequence>
747 template<
typename _Iterator,
typename _Sequence>
752 {
return __first._M_valid_range(__last, __dist); }
755 template<
typename _Iterator,
typename _Sequence>
756 inline typename _Distance_traits<_Iterator>::__type
762 template<
typename _Iterator,
typename _Sequence>
763 inline typename _Distance_traits<_Iterator>::__type
764 __get_distance(
const _Safe_iterator<_Iterator, _Sequence>& __first,
765 const _Safe_iterator<_Iterator, _Sequence>& __last,
768 typedef typename _Distance_traits<_Iterator>::__type _Diff;
769 typedef _Sequence_traits<_Sequence> _SeqTraits;
771 if (__first.base() == __last.base())
774 if (__first._M_is_before_begin())
776 if (__last._M_is_begin())
782 if (__first._M_is_begin())
784 if (__last._M_is_before_begin())
787 if (__last._M_is_end())
788 return _SeqTraits::_S_size(*__first._M_get_sequence());
793 if (__first._M_is_end())
795 if (__last._M_is_before_begin())
798 if (__last._M_is_begin())
800 _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence());
807 if (__last._M_is_before_begin() || __last._M_is_begin())
810 if (__last._M_is_end())
817 template<
typename _Iterator,
typename _Sequence>
818 inline typename _Distance_traits<_Iterator>::__type
819 __get_distance_from_begin(
const _Safe_iterator<_Iterator, _Sequence>& __it)
821 typedef _Sequence_traits<_Sequence> _SeqTraits;
825 if (__it._M_is_begin())
828 if (__it._M_is_end())
829 return _SeqTraits::_S_size(*__it._M_get_sequence());
831 typename _Distance_traits<_Iterator>::__type __res
832 =
__get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base());
834 if (__res.second == __dp_equality)
841 template<
typename _Iterator,
typename _Sequence>
842 inline typename _Distance_traits<_Iterator>::__type
843 __get_distance_to_end(
const _Safe_iterator<_Iterator, _Sequence>& __it)
845 typedef _Sequence_traits<_Sequence> _SeqTraits;
849 if (__it._M_is_begin())
850 return _SeqTraits::_S_size(*__it._M_get_sequence());
852 if (__it._M_is_end())
855 typename _Distance_traits<_Iterator>::__type __res
856 =
__get_distance(__it.base(), __it._M_get_sequence()->_M_base().end());
858 if (__res.second == __dp_equality)
864 #if __cplusplus < 201103L 865 template<
typename _Iterator,
typename _Sequence>
866 struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
867 : std::__are_same<std::random_access_iterator_tag,
868 typename std::iterator_traits<_Iterator>::
872 template<
typename _Iterator,
typename _Sequence>
874 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it,
876 {
return __it.base(); }
878 template<
typename _Iterator,
typename _Sequence>
879 const _Safe_iterator<_Iterator, _Sequence>&
880 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it,
884 template<
typename _Iterator,
typename _Sequence>
886 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it)
891 #if __cplusplus < 201103L 892 template<
typename _Iterator,
typename _Sequence>
893 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
894 {
typedef _Iterator _Type; };
897 template<
typename _Iterator,
typename _Sequence>
899 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
900 {
return __it.base(); }
_Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move assignment.
Struct holding two objects of arbitrary type.
GNU debug classes for public use.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
_Safe_iterator(const _Safe_iterator< _MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same< _MutableIterator, typename _Sequence::iterator::iterator_type >::__value), _Sequence >::__type > &__x) noexcept
Converting constructor from a mutable iterator to a constant iterator.
Base class that supports tracking of iterators that reference a sequence.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
reference operator*() const noexcept
Iterator dereference.
_Safe_iterator & operator++() noexcept
Iterator preincrement.
pointer operator->() const noexcept
Iterator dereference.
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Basic functionality for a safe iterator.
void _M_attach_single(_Safe_sequence_base *__seq)
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
_Safe_iterator operator--(int) noexcept
Iterator postdecrement.
_Safe_iterator() noexcept
_Safe_iterator & operator--() noexcept
Iterator predecrement.
_Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
_Distance_traits< _Iterator >::__type __get_distance(const _Iterator &__lhs, const _Iterator &__rhs, std::random_access_iterator_tag)
_Safe_iterator(const _Iterator &__i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
_Safe_sequence_base * _M_sequence
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
bool _M_dereferenceable() const
Is the iterator dereferenceable?
bool __valid_range(const _InputIterator &__first, const _InputIterator &__last, typename _Distance_traits< _InputIterator >::__type &__dist)
_Iterator & base() noexcept
Return the underlying iterator.
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
void _M_attach(_Safe_sequence_base *__seq)
_Safe_iterator operator++(int) noexcept
Iterator postincrement.
bool __check_dereferenceable(const _Iterator &)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
Random-access iterators support a superset of bidirectional iterator operations.
_Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise?
__gnu_cxx::__mutex & _M_get_mutex()