193 forward_list<_Tp, _Alloc>, _Alloc, __gnu_debug::_Safe_forward_list>,
194 public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc>
196 typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
200 typedef typename _Base::iterator _Base_iterator;
201 typedef typename _Base::const_iterator _Base_const_iterator;
203 template<
typename _ItT,
typename _SeqT,
typename _CatT>
204 friend class ::__gnu_debug::_Safe_iterator;
209 _Base_ref(
const _Base& __r) : _M_ref(__r) { }
215 typedef typename _Base::reference reference;
216 typedef typename _Base::const_reference const_reference;
219 _Base_iterator, forward_list> iterator;
221 _Base_const_iterator, forward_list> const_iterator;
223 typedef typename _Base::size_type size_type;
224 typedef typename _Base::difference_type difference_type;
226 typedef _Tp value_type;
227 typedef typename _Base::allocator_type allocator_type;
228 typedef typename _Base::pointer pointer;
229 typedef typename _Base::const_pointer const_pointer;
233 forward_list() =
default;
236 forward_list(
const allocator_type& __al) noexcept
239 forward_list(
const forward_list& __list,
const allocator_type& __al)
240 : _Base(__list, __al)
243 forward_list(forward_list&& __list,
const allocator_type& __al)
246 _Base,
const allocator_type&>::value )
252 forward_list(size_type __n,
const allocator_type& __al = allocator_type())
256 forward_list(size_type __n,
const __type_identity_t<_Tp>& __value,
257 const allocator_type& __al = allocator_type())
258 : _Base(__n, __value, __al)
261 template<
typename _InputIterator,
262 typename = std::_RequireInputIter<_InputIterator>>
263 forward_list(_InputIterator __first, _InputIterator __last,
264 const allocator_type& __al = allocator_type())
266 __glibcxx_check_valid_constructor_range(__first, __last)),
270#if __glibcxx_containers_ranges
271 template<__detail::__container_compatible_range<_Tp> _Rg>
272 forward_list(from_range_t, _Rg&& __rg,
const _Alloc& __a = _Alloc())
277 forward_list(
const forward_list&) =
default;
279 forward_list(forward_list&&) =
default;
282 const allocator_type& __al = allocator_type())
286 ~forward_list() =
default;
288 forward_list(_Base_ref __x) : _Base(__x._M_ref) { }
291 operator=(
const forward_list&) =
default;
294 operator=(forward_list&&) =
default;
299 _Base::operator=(__il);
300 this->_M_invalidate_all();
304 template<
typename _InputIterator,
305 typename = std::_RequireInputIter<_InputIterator>>
307 assign(_InputIterator __first, _InputIterator __last)
309 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
310 __glibcxx_check_valid_range2(__first, __last, __dist);
312 if (__dist.second >= __gnu_debug::__dp_sign)
313 _Base::assign(__gnu_debug::__unsafe(__first),
314 __gnu_debug::__unsafe(__last));
316 _Base::assign(__first, __last);
318 this->_M_invalidate_all();
321#if __glibcxx_containers_ranges
322 template<__detail::__container_compatible_range<_Tp> _Rg>
324 assign_range(_Rg&& __rg)
329 static_assert(assignable_from<_Tp&, ranges::range_reference_t<_Rg>>);
331 auto __first = ranges::begin(__rg);
332 const auto __last = ranges::end(__rg);
333 auto __prev = _Base::before_begin();
334 auto __curr = _Base::begin();
335 const auto __end = _Base::end();
337 while (__curr != __end && __first != __last)
346 erase_after(const_iterator(__prev,
this), end());
348 _Base::insert_range_after(__prev,
355 assign(size_type __n,
const _Tp& __val)
357 _Base::assign(__n, __val);
358 this->_M_invalidate_all();
365 this->_M_invalidate_all();
368 using _Base::get_allocator;
374 before_begin()
noexcept
375 {
return { _Base::before_begin(),
this }; }
379 before_begin()
const noexcept
380 {
return { _Base::before_begin(),
this }; }
385 {
return { _Base::begin(),
this }; }
389 begin()
const noexcept
390 {
return { _Base::begin(),
this }; }
395 {
return { _Base::end(),
this }; }
400 {
return { _Base::end(),
this }; }
404 cbegin()
const noexcept
405 {
return { _Base::cbegin(),
this }; }
409 cbefore_begin()
const noexcept
410 {
return { _Base::cbefore_begin(),
this }; }
414 cend()
const noexcept
415 {
return { _Base::cend(),
this }; }
418 using _Base::max_size;
426 __glibcxx_check_nonempty();
427 return _Base::front();
434 __glibcxx_check_nonempty();
435 return _Base::front();
440 using _Base::emplace_front;
441 using _Base::push_front;
443#if __glibcxx_containers_ranges
444 using _Base::prepend_range;
450 __glibcxx_check_nonempty();
451 this->_M_invalidate_if([
this](_Base_const_iterator __it)
452 {
return __it == this->_M_base().cbegin(); });
456 template<
typename... _Args>
458 emplace_after(const_iterator __pos, _Args&&... __args)
461 return { _Base::emplace_after(__pos.
base(),
467 insert_after(const_iterator __pos,
const _Tp& __val)
470 return { _Base::insert_after(__pos.
base(), __val),
this };
474 insert_after(const_iterator __pos, _Tp&& __val)
477 return { _Base::insert_after(__pos.
base(),
std::move(__val)),
this };
481 insert_after(const_iterator __pos, size_type __n,
const _Tp& __val)
484 return { _Base::insert_after(__pos.
base(), __n, __val),
this };
487 template<
typename _InputIterator,
488 typename = std::_RequireInputIter<_InputIterator>>
490 insert_after(const_iterator __pos,
491 _InputIterator __first, _InputIterator __last)
493 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
496 if (__dist.second >= __gnu_debug::__dp_sign)
499 _Base::insert_after(__pos.
base(),
500 __gnu_debug::__unsafe(__first),
501 __gnu_debug::__unsafe(__last)),
505 return { _Base::insert_after(__pos.
base(), __first, __last),
this };
512 return { _Base::insert_after(__pos.
base(), __il),
this };
515#if __glibcxx_containers_ranges
516 template<__detail::__container_compatible_range<_Tp> _Rg>
518 insert_range_after(const_iterator __position, _Rg&& __rg)
521 = _Base::insert_range_after(__position.
base(),
523 return { __ret,
this };
528 erase_after(const_iterator __pos)
532 _Base_const_iterator __next = std::next(__pos.
base());
533 this->_M_invalidate_if([__next](_Base_const_iterator __it)
534 {
return __it == __next; });
535 return { _Base::erase_after(__pos.
base()),
this };
539 erase_after(const_iterator __pos, const_iterator __last)
542 for (_Base_const_iterator __victim = std::next(__pos.
base());
543 __victim != __last.
base(); ++__victim)
545 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
546 _M_message(__gnu_debug::__msg_valid_range2)
547 ._M_sequence(*
this,
"this")
548 ._M_iterator(__pos,
"pos")
549 ._M_iterator(__last,
"last"));
550 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
551 {
return __it == __victim; });
554 return { _Base::erase_after(__pos.
base(), __last.
base()),
this };
558 swap(forward_list& __list)
561 _Safe::_M_swap(__list);
566 resize(size_type __sz)
568 this->_M_detach_singular();
571 _Base_iterator __victim = _Base::begin();
572 _Base_iterator __end = _Base::end();
573 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
576 for (; __victim != __end; ++__victim)
578 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
579 {
return __it == __victim; });
588 this->_M_revalidate_singular();
589 __throw_exception_again;
594 resize(size_type __sz,
const value_type& __val)
596 this->_M_detach_singular();
599 _Base_iterator __victim = _Base::begin();
600 _Base_iterator __end = _Base::end();
601 for (size_type __i = __sz; __victim != __end && __i > 0; --__i)
604 for (; __victim != __end; ++__victim)
606 this->_M_invalidate_if([__victim](_Base_const_iterator __it)
607 {
return __it == __victim; });
612 _Base::resize(__sz, __val);
616 this->_M_revalidate_singular();
617 __throw_exception_again;
625 this->_M_invalidate_all();
630 splice_after(const_iterator __pos, forward_list&& __list)
634 _M_message(__gnu_debug::__msg_self_splice)
635 ._M_sequence(*
this,
"this"));
636 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
637 _M_message(__gnu_debug::__msg_splice_alloc)
639 ._M_sequence(__list,
"__list"));
640 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
642 return __it != __list._M_base().cbefore_begin()
643 && __it != __list._M_base().end();
649 splice_after(const_iterator __pos, forward_list& __list)
650 { splice_after(__pos,
std::move(__list)); }
653 splice_after(const_iterator __pos, forward_list&& __list,
658 _M_message(__gnu_debug::__msg_splice_bad)
659 ._M_iterator(__i,
"__i"));
661 _M_message(__gnu_debug::__msg_splice_other)
662 ._M_iterator(__i,
"__i")
663 ._M_sequence(__list,
"__list"));
664 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
665 _M_message(__gnu_debug::__msg_splice_alloc)
667 ._M_sequence(__list,
"__list"));
671 _Base_const_iterator __next = std::next(__i.
base());
672 this->_M_transfer_from_if(__list, [__next](_Base_const_iterator __it)
673 {
return __it == __next; });
678 splice_after(const_iterator __pos, forward_list& __list,
680 { splice_after(__pos,
std::move(__list), __i); }
683 splice_after(const_iterator __pos, forward_list&& __list,
684 const_iterator __before, const_iterator __last)
686 typename __gnu_debug::_Distance_traits<const_iterator>::__type __dist;
689 __glibcxx_check_valid_fl_range(__before, __last, __dist);
691 _M_message(__gnu_debug::__msg_splice_other)
692 ._M_sequence(__list,
"list")
693 ._M_iterator(__before,
"before"));
696 _M_message(__gnu_debug::__msg_valid_range2)
697 ._M_sequence(__list,
"list")
698 ._M_iterator(__before,
"before")
699 ._M_iterator(__last,
"last"));
700 _GLIBCXX_DEBUG_VERIFY(__before != __last,
701 _M_message(__gnu_debug::__msg_valid_range2)
702 ._M_sequence(__list,
"list")
703 ._M_iterator(__before,
"before")
704 ._M_iterator(__last,
"last"));
705 _GLIBCXX_DEBUG_VERIFY(__list.get_allocator() == this->get_allocator(),
706 _M_message(__gnu_debug::__msg_splice_alloc)
708 ._M_sequence(__list,
"__list"));
710 for (_Base_const_iterator __tmp = std::next(__before.
base());
711 __tmp != __last.
base(); ++__tmp)
713 _GLIBCXX_DEBUG_VERIFY(__tmp != __list._M_base().end(),
714 _M_message(__gnu_debug::__msg_valid_range2)
715 ._M_sequence(__list,
"list")
716 ._M_iterator(__before,
"before")
717 ._M_iterator(__last,
"last"));
718 _GLIBCXX_DEBUG_VERIFY(__listptr !=
this || __tmp != __pos.
base(),
719 _M_message(__gnu_debug::__msg_splice_overlap)
720 ._M_iterator(__tmp,
"position")
721 ._M_iterator(__before,
"before")
722 ._M_iterator(__last,
"last"));
725 this->_M_transfer_from_if(__list, [__tmp](_Base_const_iterator __it)
726 {
return __it == __tmp; });
734 splice_after(const_iterator __pos, forward_list& __list,
735 const_iterator __before, const_iterator __last)
736 { splice_after(__pos,
std::move(__list), __before, __last); }
739#if __cplusplus > 201703L
740 using __remove_return_type = size_type;
741# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG \
742 __attribute__((__abi_tag__("__cxx20")))
743# define _GLIBCXX20_ONLY(__expr) __expr
745 using __remove_return_type = void;
746# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
747# define _GLIBCXX20_ONLY(__expr)
751 _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
753 remove(
const _Tp& __val)
755 if (!this->_M_iterators && !this->_M_const_iterators)
756 return _Base::remove(__val);
758 size_type __removed __attribute__((__unused__)) = 0;
759 _Base __to_destroy(get_allocator());
760 _Base_const_iterator __x = _Base::cbefore_begin();
761 _Base_const_iterator __old = __x++;
762 while (__x != _Base::cend())
766 _Base_const_iterator __next = std::next(__old);
767 this->_M_invalidate_if([__next](_Base_const_iterator __it)
768 {
return __it == __next; });
769 __to_destroy.splice_after(__to_destroy.cbefore_begin(),
772 _GLIBCXX20_ONLY( __removed++ );
778 return _GLIBCXX20_ONLY( __removed );
781 template<
typename _Pred>
783 remove_if(_Pred __pred)
785 if (!this->_M_iterators && !this->_M_const_iterators)
786 return _Base::remove_if(__pred);
788 size_type __removed __attribute__((__unused__)) = 0;
789 _Base __to_destroy(get_allocator());
790 _Base_iterator __x = _Base::before_begin();
791 _Base_iterator __old = __x++;
792 while (__x != _Base::end())
796 this->_M_invalidate_if([__x](_Base_const_iterator __it)
797 {
return __it == __x; });
798 __to_destroy.splice_after(__to_destroy.cbefore_begin(),
801 _GLIBCXX20_ONLY( __removed++ );
807 return _GLIBCXX20_ONLY( __removed );
810 _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
815 template<
typename _BinPred>
817 unique(_BinPred __binary_pred)
819 if (!this->_M_iterators && !this->_M_const_iterators)
820 return _Base::unique(__binary_pred);
822 _Base_const_iterator __first = _Base::cbegin();
823 _Base_const_iterator __last = _Base::cend();
824 if (__first == __last)
825 return _GLIBCXX20_ONLY(0);
827 size_type __removed __attribute__((__unused__)) = 0;
828 _Base __to_destroy(get_allocator());
829 _Base_const_iterator __next = std::next(__first);
830 while (__next != __last)
832 if (__binary_pred(*__first, *__next))
834 this->_M_invalidate_if([__next](_Base_const_iterator __it)
835 {
return __it == __next; });
836 __to_destroy.splice_after(__to_destroy.cbefore_begin(),
839 _GLIBCXX20_ONLY( __removed++ );
845 return _GLIBCXX20_ONLY( __removed );
848#undef _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
849#undef _GLIBCXX20_ONLY
852 merge(forward_list&& __list)
856 __glibcxx_check_sorted(_Base::begin(), _Base::end());
857 __glibcxx_check_sorted(__list._M_base().begin(),
858 __list._M_base().end());
859 this->_M_transfer_from_if(__list, [&__list](_Base_const_iterator __it)
861 return __it != __list._M_base().cbefore_begin()
862 && __it != __list._M_base().cend();
869 merge(forward_list& __list)
872 template<
typename _Comp>
874 merge(forward_list&& __list, _Comp __comp)
880 __list._M_base().end(), __comp);
881 this->_M_transfer_from_if(__list,
882 [&__list](_Base_const_iterator __it)
884 return __it != __list._M_base().cbefore_begin()
885 && __it != __list._M_base().cend();
891 template<
typename _Comp>
893 merge(forward_list& __list, _Comp __comp)
897 using _Base::reverse;
900 _M_base()
noexcept {
return *
this; }
903 _M_base()
const noexcept {
return *
this; }