245 for (Link_* link = fHead_; link !=
nullptr; prev = link, link = link->fNext) {
256 template <
typename T>
257 template <
typename EQUALS_COMPARER>
260 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
261 for (
const Link_* current = fHead_; current !=
nullptr; current = current->fNext) {
262 if (equalsComparer (current->fItem, item)) {
268 template <
typename T>
269 template <invocable<T> FUNCTION>
272 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
273 for (
const Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
274 doToElement (i->fItem);
277 template <
typename T>
278 template <
typename FUNCTION>
279 inline auto DoublyLinkedList<T>::Find (FUNCTION&& firstThat)
const -> UnderlyingIteratorRep
281 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
282 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
283 if (firstThat (i->fItem)) {
289 template <
typename T>
293 for (Link_* i = fHead_; i !=
nullptr;) {
301 template <
typename T>
304 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
306 Require (i < size ());
307 const Link_* cur = fHead_;
308 for (; i != 0; cur = cur->fNext, --i) {
314 template <
typename T>
319 Require (i < size ());
321 for (; i != 0; cur = cur->fNext, --i) {
327 template <
typename T>
330 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
336#if qStroika_Foundation_Debug_AssertionsChecked
337 Require (pi->fData_ == movedFrom);
339 auto newI = this->fHead_;
340 [[maybe_unused]]
auto newE =
nullptr;
341 auto oldI = movedFrom->fHead_;
342 [[maybe_unused]]
auto oldE =
nullptr;
343 while (oldI != pi->fCurrent_) {
344 Assert (newI != newE);
345 Assert (oldI != oldE);
348 Assert (newI != newE);
349 Assert (oldI != oldE);
351 Assert (oldI == pi->fCurrent_);
352 pi->fCurrent_ = newI;
353#if qStroika_Foundation_Debug_AssertionsChecked
357 template <
typename T>
358 inline auto DoublyLinkedList<T>::begin () const -> ForwardIterator
360 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
361 return ForwardIterator{
this};
363 template <
typename T>
364 constexpr auto DoublyLinkedList<T>::end () const noexcept -> ForwardIterator
366 return ForwardIterator{};
368 template <
typename T>
371 ForwardIterator next = i;
377 template <
typename T>
381 Require (not i.Done ());
382#if qStroika_Foundation_Debug_AssertionsChecked
383 Require (i.fData_ ==
this);
387 const Link_* victim = i.fCurrent_;
404 if (victim->fPrev ==
nullptr) {
406 Assert (fHead_ == victim);
407 fHead_ = victim->fNext;
408 if (fHead_ ==
nullptr) {
412 Assert (fHead_->fPrev == victim);
413 fHead_->fPrev =
nullptr;
417 Assert (victim->fPrev->fNext == victim);
418 victim->fPrev->fNext = victim->fNext;
420 if (victim->fNext ==
nullptr) {
422 Assert (victim == fTail_);
423 fTail_ = victim->fPrev;
426 Assert (victim->fNext->fPrev == victim);
427 victim->fNext->fPrev = victim->fPrev;
433 template <
typename T>
437 Require (not i.Done ());
438#if qStroika_Foundation_Debug_AssertionsChecked
439 Require (i.fData_ ==
this);
442 const_cast<Link_*
> (i.fCurrent_)->fItem = newValue;
445 template <
typename T>
449#if qStroika_Foundation_Debug_AssertionsChecked
450 Require (i.fData_ ==
this);
456 if (i.fCurrent_ ==
nullptr) {
462 push_back (newValue);
466 Link_* prev = i.fCurrent_->fPrev;
467 if (prev ==
nullptr) {
468 push_front (newValue);
478 Assert (prev->fNext == i.fCurrent_);
479 Link_* iteratorCurLink =
const_cast<Link_*
> (i.fCurrent_);
480 prev->fNext =
new Link_{newValue, prev, iteratorCurLink};
483 iteratorCurLink->fPrev = prev->fNext;
484 Assert (i.fCurrent_->fPrev->fPrev == prev);
489 template <
typename T>
493#if qStroika_Foundation_Debug_AssertionsChecked
494 Require (i.fData_ ==
this);
497 Require (not i.Done ());
499 Assert (fHead_ !=
nullptr);
507 Link_* iteratorCurLink =
const_cast<Link_*
> (i.fCurrent_);
508 Link_* newLink =
new Link_{newValue, iteratorCurLink, iteratorCurLink->fNext};
509 iteratorCurLink->fNext = newLink;
510 if (newLink->fNext !=
nullptr) {
511 newLink->fNext->fPrev = newLink;
513 if (newLink->fNext ==
nullptr) {
517 Assert (newLink->fNext->fPrev == newLink);
521#if qStroika_Foundation_Debug_AssertionsChecked
522 template <
typename T>
525#if qStroika_Foundation_Containers_DataStructures_DoublyLinkedList_IncludeSlowDebugChecks_
526 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
528 if (fHead_ !=
nullptr) {
529 Assert (fHead_->fPrev ==
nullptr);
530 if (fHead_->fNext ==
nullptr) {
531 Assert (fHead_ == fTail_);
534 Assert (fHead_->fNext->fPrev == fHead_);
537 if (fTail_ !=
nullptr) {
538 Assert (fTail_->fNext ==
nullptr);
539 if (fTail_->fPrev ==
nullptr) {
540 Assert (fHead_ == fTail_);
543 Assert (fTail_->fPrev->fNext == fTail_);
546 Assert (fHead_ ==
nullptr or fHead_->fPrev ==
nullptr);
547 Assert (fTail_ ==
nullptr or fTail_->fNext ==
nullptr);
552 size_t forwardCounter = 0;
553 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
554 Assert (i->fNext ==
nullptr or i->fNext->fPrev == i);
557 size_t backwardCounter{};
558 for (Link_* i = fTail_; i !=
nullptr; i = i->fPrev) {
559 Assert (i->fPrev ==
nullptr or i->fPrev->fNext == i);
562 Assert (forwardCounter == backwardCounter);
571 template <
typename T>
572 constexpr DoublyLinkedList<T>::ForwardIterator::ForwardIterator ([[maybe_unused]]
const DoublyLinkedList* data, UnderlyingIteratorRep startAt) noexcept
574#if qStroika_Foundation_Debug_AssertionsChecked
579 template <
typename T>
580 constexpr DoublyLinkedList<T>::ForwardIterator::ForwardIterator (
const DoublyLinkedList* data) noexcept
584 template <
typename T>
585 inline void DoublyLinkedList<T>::ForwardIterator::Invariant () const noexcept
587#if qStroika_Foundation_Debug_AssertionsChecked
591 template <
typename T>
592 inline DoublyLinkedList<T>::ForwardIterator::operator bool ()
const
596 template <
typename T>
597 inline bool DoublyLinkedList<T>::ForwardIterator::Done () const noexcept
599#if qStroika_Foundation_Debug_AssertionsChecked
600 if (fData_ !=
nullptr) {
601 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
605 return fCurrent_ ==
nullptr;
607 template <
typename T>
608 inline auto DoublyLinkedList<T>::ForwardIterator::operator++ () noexcept -> ForwardIterator&
610 Require (not Done ());
612 Assert (fCurrent_ !=
nullptr);
613 fCurrent_ = fCurrent_->fNext;
617 template <
typename T>
618 inline auto DoublyLinkedList<T>::ForwardIterator::operator++ (
int)
noexcept -> ForwardIterator
620 ForwardIterator result = *
this;
624 template <
typename T>
625 inline const T& DoublyLinkedList<T>::ForwardIterator::operator* ()
const
627#if qStroika_Foundation_Debug_AssertionsChecked
629 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
631 Require (not Done ());
634 return fCurrent_->fItem;
636 template <
typename T>
637 inline const T* DoublyLinkedList<T>::ForwardIterator::operator->()
const
639#if qStroika_Foundation_Debug_AssertionsChecked
641 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
643 Require (not Done ());
646 return &fCurrent_->fItem;
648 template <
typename T>
649 size_t DoublyLinkedList<T>::ForwardIterator::CurrentIndex (
const DoublyLinkedList* data)
const
651 Require (not Done ());
652#if qStroika_Foundation_Debug_AssertionsChecked
653 Require (data == fData_);
658 for (
const Link_* l = data->fHead_;; l = l->fNext, ++i) {
660 if (l == fCurrent_) [[unlikely]] {
667 template <
typename T>
668 inline auto DoublyLinkedList<T>::ForwardIterator::GetUnderlyingIteratorRep () const -> UnderlyingIteratorRep
672 template <
typename T>
673 inline void DoublyLinkedList<T>::ForwardIterator::SetUnderlyingIteratorRep (UnderlyingIteratorRep l)
675#if qStroika_Foundation_Debug_AssertionsChecked
676 AssertExternallySynchronizedMutex::ReadContext declareContext{*fData_};
682 template <
typename T>
683 constexpr void DoublyLinkedList<T>::ForwardIterator::AssertDataMatches ([[maybe_unused]]
const DoublyLinkedList* data)
const
685#if qStroika_Foundation_Debug_AssertionsChecked
686 Require (data == fData_);
689 template <
typename T>
690 inline bool DoublyLinkedList<T>::ForwardIterator::operator== (
const ForwardIterator& rhs)
const
692 return fCurrent_ == rhs.fCurrent_;
694#if qStroika_Foundation_Debug_AssertionsChecked
695 template <
typename T>
696 void DoublyLinkedList<T>::ForwardIterator::Invariant_ () const noexcept