29 #ifndef _GLIBCXX_DEBUG_FORWARD_LIST
30 #define _GLIBCXX_DEBUG_FORWARD_LIST 1
32 #pragma GCC system_header
38 namespace std _GLIBCXX_VISIBILITY(default)
43 template<
typename _Tp,
typename _Alloc = std::allocator<_Tp> >
45 :
public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>,
48 typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
_Base;
54 rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
59 typedef typename _Base::reference reference;
60 typedef typename _Base::const_reference const_reference;
67 typedef typename _Base::size_type size_type;
68 typedef typename _Base::difference_type difference_type;
70 typedef _Tp value_type;
71 typedef _Alloc allocator_type;
72 typedef typename _Base::pointer pointer;
73 typedef typename _Base::const_pointer const_pointer;
85 :
_Base(std::move(__list._M_base()), __al)
87 if (__list.get_allocator() == __al)
88 this->_M_swap(__list);
90 __list._M_invalidate_all();
94 forward_list(size_type __n,
const _Alloc& __al = _Alloc())
99 const _Alloc& __al = _Alloc())
100 :
_Base(__n, __value, __al)
103 template<
typename _InputIterator,
104 typename = std::_RequireInputIter<_InputIterator>>
105 forward_list(_InputIterator __first, _InputIterator __last,
106 const _Alloc& __al = _Alloc())
112 forward_list(
const forward_list& __list)
116 forward_list(forward_list&& __list) noexcept
117 :
_Base(std::move(__list._M_base()))
119 this->_M_swap(__list);
123 const _Alloc& __al = _Alloc())
127 ~forward_list() noexcept
131 operator=(
const forward_list& __list)
133 static_cast<_Base&
>(*this) = __list;
134 this->_M_invalidate_all();
139 operator=(forward_list&& __list)
140 noexcept(_Node_alloc_traits::_S_nothrow_move())
142 __glibcxx_check_self_move_assign(__list);
143 bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
144 || __list.get_allocator() == this->get_allocator();
145 static_cast<_Base&
>(*this) = std::move(__list);
147 this->_M_swap(__list);
149 this->_M_invalidate_all();
150 __list._M_invalidate_all();
157 static_cast<_Base&
>(*this) = __il;
158 this->_M_invalidate_all();
162 template<
typename _InputIterator,
163 typename = std::_RequireInputIter<_InputIterator>>
165 assign(_InputIterator __first, _InputIterator __last)
167 __glibcxx_check_valid_range(__first, __last);
170 this->_M_invalidate_all();
174 assign(size_type __n,
const _Tp& __val)
176 _Base::assign(__n, __val);
177 this->_M_invalidate_all();
184 this->_M_invalidate_all();
187 using _Base::get_allocator;
192 before_begin() noexcept
193 {
return iterator(_Base::before_begin(),
this); }
196 before_begin()
const noexcept
201 {
return iterator(_Base::begin(),
this); }
204 begin()
const noexcept
209 {
return iterator(_Base::end(),
this); }
216 cbegin()
const noexcept
220 cbefore_begin()
const noexcept
224 cend()
const noexcept
228 using _Base::max_size;
235 __glibcxx_check_nonempty();
236 return _Base::front();
242 __glibcxx_check_nonempty();
243 return _Base::front();
248 using _Base::emplace_front;
249 using _Base::push_front;
254 __glibcxx_check_nonempty();
256 {
return __it == this->_M_base().cbegin(); });
260 template<
typename... _Args>
266 std::forward<_Args>(__args)...),
274 return iterator(_Base::insert_after(__pos.
base(), __val),
this);
281 return iterator(_Base::insert_after(__pos.
base(), std::move(__val)),
286 insert_after(
const_iterator __pos, size_type __n,
const _Tp& __val)
289 return iterator(_Base::insert_after(__pos.
base(), __n, __val),
293 template<
typename _InputIterator,
294 typename = std::_RequireInputIter<_InputIterator>>
297 _InputIterator __first, _InputIterator __last)
310 return iterator(_Base::insert_after(__pos.
base(), __il),
this);
319 {
return __it == __next; });
320 return _Base::erase_after(__pos);
335 __victim != __last.
base(); ++__victim)
337 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
338 _M_message(__gnu_debug::__msg_valid_range2)
339 ._M_sequence(*
this,
"this")
340 ._M_iterator(__pos,
"pos")
341 ._M_iterator(__last,
"last"));
343 {
return __it == __victim; });
349 swap(forward_list& __list)
350 noexcept(_Node_alloc_traits::_S_nothrow_swap())
352 if (!_Node_alloc_traits::_S_propagate_on_swap())
353 __glibcxx_check_equal_allocs(__list);
355 this->_M_swap(__list);
359 resize(size_type __sz)
366 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
369 for (; __victim != __end; ++__victim)
372 {
return __it == __victim; });
382 __throw_exception_again;
387 resize(size_type __sz,
const value_type& __val)
394 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
397 for (; __victim != __end; ++__victim)
400 {
return __it == __victim; });
405 _Base::resize(__sz, __val);
410 __throw_exception_again;
418 this->_M_invalidate_all();
426 _GLIBCXX_DEBUG_VERIFY(&__list !=
this,
427 _M_message(__gnu_debug::__msg_self_splice)
428 ._M_sequence(*
this,
"this"));
429 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
430 _M_message(__gnu_debug::__msg_splice_alloc)
432 ._M_sequence(__list,
"__list"));
435 return __it != __list._M_base().cbefore_begin()
436 && __it != __list._M_base().end();
438 _Base::splice_after(__pos.
base(), std::move(__list._M_base()));
443 { splice_after(__pos, std::move(__list)); }
451 _M_message(__gnu_debug::__msg_splice_bad)
452 ._M_iterator(__i,
"__i"));
454 _M_message(__gnu_debug::__msg_splice_other)
455 ._M_iterator(__i,
"__i")
456 ._M_sequence(__list,
"__list"));
457 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
458 _M_message(__gnu_debug::__msg_splice_alloc)
460 ._M_sequence(__list,
"__list"));
466 {
return __it == __next; });
467 _Base::splice_after(__pos.
base(), std::move(__list._M_base()),
474 { splice_after(__pos, std::move(__list), __i); }
481 __glibcxx_check_valid_range(__before, __last);
483 _M_message(__gnu_debug::__msg_splice_other)
484 ._M_sequence(__list,
"list")
485 ._M_iterator(__before,
"before"));
488 _M_message(__gnu_debug::__msg_valid_range2)
489 ._M_sequence(__list,
"list")
490 ._M_iterator(__before,
"before")
491 ._M_iterator(__last,
"last"));
492 _GLIBCXX_DEBUG_VERIFY(__before != __last,
493 _M_message(__gnu_debug::__msg_valid_range2)
494 ._M_sequence(__list,
"list")
495 ._M_iterator(__before,
"before")
496 ._M_iterator(__last,
"last"));
497 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
498 _M_message(__gnu_debug::__msg_splice_alloc)
500 ._M_sequence(__list,
"__list"));
503 __tmp != __last.
base(); ++__tmp)
505 _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(),
506 _M_message(__gnu_debug::__msg_valid_range2)
508 ._M_iterator(__before,
"before")
509 ._M_iterator(__last,
"last"));
510 _GLIBCXX_DEBUG_VERIFY(&__list !=
this || __tmp != __pos.
base(),
511 _M_message(__gnu_debug::__msg_splice_overlap)
512 ._M_iterator(__tmp,
"position")
513 ._M_iterator(__before,
"before")
514 ._M_iterator(__last,
"last"));
518 {
return __it == __tmp; });
521 _Base::splice_after(__pos.
base(), std::move(__list._M_base()),
528 { splice_after(__pos, std::move(__list), __before, __last); }
531 remove(
const _Tp& __val)
535 while (__x != _Base::end())
538 __x = _M_erase_after(__old);
544 template<
typename _Pred>
546 remove_if(_Pred __pred)
550 while (__x != _Base::end())
553 __x = _M_erase_after(__old);
564 if (__first == __last)
567 while (__next != __last)
569 if (*__first == *__next)
570 __next = _M_erase_after(__first);
576 template<
typename _BinPred>
578 unique(_BinPred __binary_pred)
582 if (__first == __last)
585 while (__next != __last)
587 if (__binary_pred(*__first, *__next))
588 __next = _M_erase_after(__first);
595 merge(forward_list&& __list)
599 __glibcxx_check_sorted(_Base::begin(), _Base::end());
600 __glibcxx_check_sorted(__list._M_base().begin(),
601 __list._M_base().end());
604 return __it != __list._M_base().cbefore_begin()
605 && __it != __list._M_base().cend();
607 _Base::merge(std::move(__list._M_base()));
612 merge(forward_list& __list)
613 { merge(std::move(__list)); }
615 template<
typename _Comp>
617 merge(forward_list&& __list, _Comp __comp)
623 __list._M_base().end(), __comp);
627 return __it != __list._M_base().cbefore_begin()
628 && __it != __list._M_base().cend();
630 _Base::merge(std::move(__list._M_base()), __comp);
634 template<
typename _Comp>
636 merge(forward_list& __list, _Comp __comp)
637 { merge(std::move(__list), __comp); }
640 using _Base::reverse;
643 _M_base() noexcept {
return *
this; }
646 _M_base()
const noexcept {
return *
this; }
654 return __it != this->_M_base().cbefore_begin()
655 && __it != this->_M_base().cend();
660 _M_swap_aux(forward_list& __lhs,
664 void _M_swap(forward_list& __list);
667 template<
typename _Tp,
typename _Alloc>
676 _Safe_iterator_base* __bbegin_its = 0;
677 _Safe_iterator_base* __last_bbegin = 0;
678 for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
681 const_iterator* __victim =
static_cast<const_iterator*
>(__iter);
683 if (__victim->base() == __rhs._M_base().cbefore_begin())
686 if (__lhs_iterators == __victim)
687 __lhs_iterators = __victim->
_M_next;
690 __victim->
_M_next = __bbegin_its;
694 __last_bbegin = __victim;
695 __bbegin_its = __victim;
705 __rhs_iterators->
_M_prior = __last_bbegin;
706 __last_bbegin->
_M_next = __rhs_iterators;
708 __rhs_iterators = __bbegin_its;
714 template<
typename _Tp,
typename _Alloc>
716 forward_list<_Tp, _Alloc>::
717 _M_swap(forward_list<_Tp, _Alloc>& __list)
720 std::swap(this->_M_iterators, __list._M_iterators);
721 std::swap(this->_M_const_iterators, __list._M_const_iterators);
724 _Safe_iterator_base* __this_its = this->_M_iterators;
725 _M_swap_aux(__list, __list._M_iterators, *
this, this->_M_iterators);
726 _Safe_iterator_base* __this_const_its = this->_M_const_iterators;
727 _M_swap_aux(__list, __list._M_const_iterators, *
this,
728 this->_M_const_iterators);
729 _M_swap_aux(*
this, __this_its, __list, __list._M_iterators);
730 _M_swap_aux(*
this, __this_const_its, __list, __list._M_const_iterators);
733 template<
typename _Tp,
typename _Alloc>
735 operator==(
const forward_list<_Tp, _Alloc>& __lx,
736 const forward_list<_Tp, _Alloc>& __ly)
737 {
return __lx._M_base() == __ly._M_base(); }
739 template<
typename _Tp,
typename _Alloc>
741 operator<(const forward_list<_Tp, _Alloc>& __lx,
742 const forward_list<_Tp, _Alloc>& __ly)
743 {
return __lx._M_base() < __ly._M_base(); }
745 template<
typename _Tp,
typename _Alloc>
747 operator!=(
const forward_list<_Tp, _Alloc>& __lx,
748 const forward_list<_Tp, _Alloc>& __ly)
749 {
return !(__lx == __ly); }
752 template<
typename _Tp,
typename _Alloc>
756 {
return (__ly < __lx); }
759 template<
typename _Tp,
typename _Alloc>
763 {
return !(__lx < __ly); }
766 template<
typename _Tp,
typename _Alloc>
768 operator<=(const forward_list<_Tp, _Alloc>& __lx,
770 {
return !(__ly < __lx); }
773 template<
typename _Tp,
typename _Alloc>
782 namespace __gnu_debug
784 template<
class _Tp,
class _Alloc>
785 struct _BeforeBeginHelper<std::__debug::forward_list<_Tp, _Alloc> >
789 template<
typename _Iterator>
791 _S_Is(
const _Safe_iterator<_Iterator, _Sequence>& __it)
794 __it.base() == __it._M_get_sequence()->_M_base().before_begin();
797 template<
typename _Iterator>
799 _S_Is_Beginnest(
const _Safe_iterator<_Iterator, _Sequence>& __it)
800 {
return _S_Is(__it); }
803 #ifndef _GLIBCXX_DEBUG_PEDANTIC
804 template<
class _Tp,
class _Alloc>
805 struct _Insert_range_from_self_is_safe<
806 std::__debug::forward_list<_Tp, _Alloc> >
807 {
enum { __value = 1 }; };
void _M_revalidate_singular()
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
void _M_invalidate_if(_Predicate __pred)
_Safe_iterator_base * _M_prior
Uniform interface to C++98 and C++0x allocators.
#define __glibcxx_check_erase_range_after(_First, _Last)
void _M_detach_singular()
_Safe_iterator_base * _M_next
#define __glibcxx_check_erase_after(_Position)
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
void _M_transfer_from_if(_Safe_sequence &__from, _Predicate __pred)
bool _M_attached_to(const _Safe_sequence_base *__seq) const
_Iterator base() const noexcept
Return the underlying iterator.
Class std::forward_list with safety/checking/debug instrumentation.
#define __glibcxx_check_sorted_pred(_First, _Last, _Pred)
_Safe_sequence_base * _M_sequence
Basic functionality for a safe iterator.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
void swap(function< _Res(_Args...)> &__x, function< _Res(_Args...)> &__y)
Swap the targets of two polymorphic function object wrappers.
Base class for constructing a safe sequence type that tracks iterators that reference it...
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
#define __glibcxx_check_insert_after(_Position)
#define __glibcxx_check_insert_range_after(_Position, _First, _Last)