278 for (ForwardIterator it{
this}; not it.AtEnd (); ++it) {
279 if (equalsComparer (*it, item)) {
286 template <
typename T>
287 template <
typename EQUALS_COMPARER>
288 bool DoublyLinkedList<T>::Contains (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer)
const
290 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
291 for (
const Link_* current = fHead_; current !=
nullptr; current = current->fNext) {
292 if (forward<EQUALS_COMPARER> (equalsComparer) (current->fItem, item)) {
298 template <
typename T>
299 template <invocable<T> FUNCTION>
300 inline void DoublyLinkedList<T>::Apply (FUNCTION&& doToElement)
const
302 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
303 for (
const Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
304 forward<FUNCTION> (doToElement) (i->fItem);
307 template <
typename T>
308 template <
typename FUNCTION>
309 inline auto DoublyLinkedList<T>::Find (FUNCTION&& firstThat)
const -> UnderlyingIteratorRep
311 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
312 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
313 if (forward<FUNCTION> (firstThat) (i->fItem)) {
319 template <
typename T>
323 for (Link_* i = fHead_; i !=
nullptr;) {
332 template <
typename T>
335 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
337 Require (i < size ());
338 const Link_* cur = fHead_;
339 for (; i != 0; cur = cur->fNext, --i) {
345 template <
typename T>
350 Require (i < size ());
352 for (; i != 0; cur = cur->fNext, --i) {
358 template <
typename T>
361 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
367#if qStroika_Foundation_Debug_AssertionsChecked
368 Require (pi->fData_ == movedFrom);
370 auto newI = this->fHead_;
371 [[maybe_unused]]
auto newE =
nullptr;
372 auto oldI = movedFrom->fHead_;
373 [[maybe_unused]]
auto oldE =
nullptr;
374 while (oldI != pi->_fCurrent) {
375 Assert (newI != newE);
376 Assert (oldI != oldE);
379 Assert (newI != newE);
380 Assert (oldI != oldE);
382 Assert (oldI == pi->_fCurrent);
383 pi->_fCurrent = newI;
384#if qStroika_Foundation_Debug_AssertionsChecked
388 template <
typename T>
389 inline auto DoublyLinkedList<T>::begin () const -> ForwardIterator
391 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
392 return ForwardIterator{
this};
394 template <
typename T>
395 constexpr auto DoublyLinkedList<T>::end () const noexcept -> ForwardIterator
397 return ForwardIterator{};
399 template <
typename T>
402 ForwardIterator next = i;
408 template <
typename T>
412 Require (not i.AtEnd ());
413#if qStroika_Foundation_Debug_AssertionsChecked
414 Require (i.fData_ ==
this);
418 const Link_* victim = i._fCurrent;
435 if (victim->fPrev ==
nullptr) {
437 Assert (fHead_ == victim);
438 fHead_ = victim->fNext;
439 if (fHead_ ==
nullptr) {
443 Assert (fHead_->fPrev == victim);
444 fHead_->fPrev =
nullptr;
448 Assert (victim->fPrev->fNext == victim);
449 victim->fPrev->fNext = victim->fNext;
451 if (victim->fNext ==
nullptr) {
453 Assert (victim == fTail_);
454 fTail_ = victim->fPrev;
457 Assert (victim->fNext->fPrev == victim);
458 victim->fNext->fPrev = victim->fPrev;
465 template <
typename T>
469 Require (not i.AtEnd ());
470#if qStroika_Foundation_Debug_AssertionsChecked
471 Require (i.fData_ ==
this);
474 const_cast<Link_*
> (i._fCurrent)->fItem = newValue;
477 template <
typename T>
481#if qStroika_Foundation_Debug_AssertionsChecked
482 Require (i.fData_ ==
this);
488 if (i._fCurrent ==
nullptr) {
494 push_back (newValue);
498 Link_* prev = i._fCurrent->fPrev;
499 if (prev ==
nullptr) {
500 push_front (newValue);
510 Assert (prev->fNext == i._fCurrent);
511 Link_* iteratorCurLink =
const_cast<Link_*
> (i._fCurrent);
512 prev->fNext =
new Link_{newValue, prev, iteratorCurLink};
515 iteratorCurLink->fPrev = prev->fNext;
517 Assert (i._fCurrent->fPrev->fPrev == prev);
522 template <
typename T>
526#if qStroika_Foundation_Debug_AssertionsChecked
527 Require (i.fData_ ==
this);
530 Require (not i.AtEnd ());
532 Assert (fHead_ !=
nullptr);
540 Link_* iteratorCurLink =
const_cast<Link_*
> (i._fCurrent);
541 Link_* newLink =
new Link_{newValue, iteratorCurLink, iteratorCurLink->fNext};
542 iteratorCurLink->fNext = newLink;
543 if (newLink->fNext !=
nullptr) {
544 newLink->fNext->fPrev = newLink;
546 if (newLink->fNext ==
nullptr) {
550 Assert (newLink->fNext->fPrev == newLink);
555#if qStroika_Foundation_Debug_AssertionsChecked
556 template <
typename T>
559#if qStroika_Foundation_Containers_DataStructures_DoublyLinkedList_IncludeSlowDebugChecks_
560 AssertExternallySynchronizedChecker::ReadContext declareContext{*
this};
562 if (fHead_ !=
nullptr) {
563 Assert (fHead_->fPrev ==
nullptr);
564 if (fHead_->fNext ==
nullptr) {
565 Assert (fHead_ == fTail_);
568 Assert (fHead_->fNext->fPrev == fHead_);
571 if (fTail_ !=
nullptr) {
572 Assert (fTail_->fNext ==
nullptr);
573 if (fTail_->fPrev ==
nullptr) {
574 Assert (fHead_ == fTail_);
577 Assert (fTail_->fPrev->fNext == fTail_);
583 for (
const Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
586 Assert (n == fLength_);
588 Assert (fHead_ ==
nullptr or fHead_->fPrev ==
nullptr);
589 Assert (fTail_ ==
nullptr or fTail_->fNext ==
nullptr);
594 size_t forwardCounter = 0;
595 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
596 Assert (i->fNext ==
nullptr or i->fNext->fPrev == i);
599 size_t backwardCounter{};
600 for (Link_* i = fTail_; i !=
nullptr; i = i->fPrev) {
601 Assert (i->fPrev ==
nullptr or i->fPrev->fNext == i);
604 Assert (forwardCounter == backwardCounter);
613 template <
typename T>
614 constexpr DoublyLinkedList<T>::ForwardIterator::ForwardIterator ([[maybe_unused]]
const DoublyLinkedList* data, UnderlyingIteratorRep startAt) noexcept
616#if qStroika_Foundation_Debug_AssertionsChecked
621 template <
typename T>
622 constexpr DoublyLinkedList<T>::ForwardIterator::ForwardIterator (
const DoublyLinkedList* data) noexcept
626 template <
typename T>
627 inline void DoublyLinkedList<T>::ForwardIterator::Invariant () const noexcept
629#if qStroika_Foundation_Debug_AssertionsChecked
633 template <
typename T>
634 inline DoublyLinkedList<T>::ForwardIterator::operator bool ()
const
638 template <
typename T>
639 inline bool DoublyLinkedList<T>::ForwardIterator::AtEnd () const noexcept
641#if qStroika_Foundation_Debug_AssertionsChecked
642 if (fData_ !=
nullptr) {
643 AssertExternallySynchronizedChecker::ReadContext declareContext{*fData_};
647 return _fCurrent ==
nullptr;
649 template <
typename T>
650 inline auto DoublyLinkedList<T>::ForwardIterator::operator++ () noexcept -> ForwardIterator&
652 Require (not AtEnd ());
654 Assert (_fCurrent !=
nullptr);
655 _fCurrent = _fCurrent->fNext;
659 template <
typename T>
660 inline auto DoublyLinkedList<T>::ForwardIterator::operator++ (
int)
noexcept -> ForwardIterator
662 ForwardIterator result = *
this;
666 template <
typename T>
667 inline const T& DoublyLinkedList<T>::ForwardIterator::operator* ()
const
669#if qStroika_Foundation_Debug_AssertionsChecked
671 AssertExternallySynchronizedChecker::ReadContext declareContext{*fData_};
673 Require (not AtEnd ());
676 return _fCurrent->fItem;
678 template <
typename T>
679 inline const T* DoublyLinkedList<T>::ForwardIterator::operator->()
const
681#if qStroika_Foundation_Debug_AssertionsChecked
683 AssertExternallySynchronizedChecker::ReadContext declareContext{*fData_};
685 Require (not AtEnd ());
688 return &_fCurrent->fItem;
690 template <
typename T>
691 size_t DoublyLinkedList<T>::ForwardIterator::CurrentIndex (
const DoublyLinkedList* data)
const
693 Require (not AtEnd ());
694#if qStroika_Foundation_Debug_AssertionsChecked
695 Require (data == fData_);
700 for (
const Link_* l = data->fHead_;; l = l->fNext, ++i) {
702 if (l == _fCurrent) [[unlikely]] {
709 template <
typename T>
710 inline auto DoublyLinkedList<T>::ForwardIterator::GetUnderlyingIteratorRep () const -> UnderlyingIteratorRep
714 template <
typename T>
715 inline void DoublyLinkedList<T>::ForwardIterator::SetUnderlyingIteratorRep (UnderlyingIteratorRep l)
717#if qStroika_Foundation_Debug_AssertionsChecked
718 AssertExternallySynchronizedChecker::ReadContext declareContext{*fData_};
724 template <
typename T>
725 constexpr void DoublyLinkedList<T>::ForwardIterator::AssertDataMatches ([[maybe_unused]]
const DoublyLinkedList* data)
const
727#if qStroika_Foundation_Debug_AssertionsChecked
728 Require (data == fData_);
731 template <
typename T>
732 inline bool DoublyLinkedList<T>::ForwardIterator::operator== (
const ForwardIterator& rhs)
const
734 return _fCurrent == rhs._fCurrent;
736#if qStroika_Foundation_Debug_AssertionsChecked
737 template <
typename T>
738 void DoublyLinkedList<T>::ForwardIterator::Invariant_ () const noexcept
740 if (fData_ !=
nullptr) {
751 template <
typename T>
752 constexpr DoublyLinkedList<T>::BidirectionalIterator::BidirectionalIterator ([[maybe_unused]]
const DoublyLinkedList* data,
753 UnderlyingIteratorRep startAt) noexcept
754 : inherited{data, startAt}
758 template <
typename T>
759 constexpr DoublyLinkedList<T>::BidirectionalIterator::BidirectionalIterator (
const DoublyLinkedList* data) noexcept
764 template <
typename T>
765 inline bool DoublyLinkedList<T>::BidirectionalIterator::AtStart () const noexcept
767 if (this->_fCurrent ==
nullptr) {
769 return this->fData_->empty ();
771 return this->_fCurrent->fPrev ==
nullptr;
773 template <
typename T>
774 inline auto DoublyLinkedList<T>::BidirectionalIterator::operator++ () noexcept -> BidirectionalIterator&
776 inherited::operator++ ();
779 template <
typename T>
780 inline auto DoublyLinkedList<T>::BidirectionalIterator::operator++ (
int)
noexcept -> BidirectionalIterator
782 BidirectionalIterator result{*
this};
786 template <
typename T>
787 inline auto DoublyLinkedList<T>::BidirectionalIterator::operator-- () noexcept -> BidirectionalIterator&
789 Require (not this->AtStart ());
791 if (this->_fCurrent ==
nullptr) {
792 this->_fCurrent = this->fData_->fTail_;
795 this->_fCurrent = this->_fCurrent->fPrev;
797 Assert (this->_fCurrent !=
nullptr);
801 template <
typename T>
802 inline auto DoublyLinkedList<T>::BidirectionalIterator::operator-- (
int)
noexcept -> BidirectionalIterator
804 BidirectionalIterator result{*
this};
808 template <
typename T>
809 inline auto DoublyLinkedList<T>::BidirectionalIterator::operator- (ptrdiff_t i)
const -> BidirectionalIterator
811 BidirectionalIterator result{*
this};