231 Require (not i.Done ());
232#if qStroika_Foundation_Debug_AssertionsChecked
233 Require (i.fData_ ==
this);
237 const_cast<Link_*
> (i.fCurrent_)->fItem = newValue;
240 template <
typename T>
244#if qStroika_Foundation_Debug_AssertionsChecked
245 Require (i.fData_ ==
this);
253 Link_* prev =
nullptr;
254 if ((this->fHead_ !=
nullptr) and (this->fHead_ != i.fCurrent_)) {
255 for (prev = this->fHead_; prev->fNext != i.fCurrent_; prev = prev->fNext) {
260 if (prev ==
nullptr) {
261 Assert (this->fHead_ == i.fCurrent_);
262 this->fHead_ =
new Link_{item, this->fHead_};
265 Assert (prev->fNext == i.fCurrent_);
266 prev->fNext =
new Link_{item, prev->fNext};
271 template <
typename T>
276#if qStroika_Foundation_Debug_AssertionsChecked
277 Require (i.fData_ ==
this);
285 Link_* prev =
nullptr;
286 if ((this->fHead_ !=
nullptr) and (this->fHead_ != i.fCurrent_)) {
287 for (prev = this->fHead_; prev->fNext != i.fCurrent_; prev = prev->fNext) {
292 if (prev ==
nullptr) {
293 Assert (this->fHead_ == i.fCurrent_);
294 this->fHead_ =
new Link_{item, this->fHead_};
295 *newLinkCreatedAt = ForwardIterator{
this, this->fHead_};
298 Assert (prev->fNext == i.fCurrent_);
299 prev->fNext =
new Link_{item, prev->fNext};
300 *newLinkCreatedAt = ForwardIterator{
this, prev->fNext};
305 template <
typename T>
309 Require (not i.Done ());
310#if qStroika_Foundation_Debug_AssertionsChecked
311 Require (i.fData_ ==
this);
315 const_cast<Link_*
> (i.fCurrent_)->fNext =
new Link_{newValue, i.fCurrent_->fNext};
317 template <
typename T>
320 ForwardIterator next = i;
326 template <
typename T>
330#if qStroika_Foundation_Debug_AssertionsChecked
331 Require (i.fData_ ==
this);
333 Require (not i.Done ());
337 const Link_* victim = i.fCurrent_;
344 Link_* prevLink =
nullptr;
345 if (this->fHead_ != victim) {
346 auto potentiallyPrevLink = this->fHead_;
348 for (; potentiallyPrevLink->fNext != victim; potentiallyPrevLink = potentiallyPrevLink->fNext) {
351 prevLink = potentiallyPrevLink;
353 Assert (prevLink ==
nullptr or prevLink->fNext == victim);
354 if (prevLink ==
nullptr) {
355 Require (this->fHead_ == victim);
357 this->fHead_ = victim->fNext;
360 Assert (prevLink->fNext == victim);
361 prevLink->fNext = victim->fNext;
367 template <
typename T>
368 template <
typename EQUALS_COMPARER>
369 void LinkedList<T>::Remove (ArgByValueType<T> item,
const EQUALS_COMPARER& equalsComparer)
371 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{*
this};
380 for (ForwardIterator it{
this}; not it.Done (); ++it) {
381 if (equalsComparer (*it, item)) {
388 template <
typename T>
389 template <invocable<T> FUNCTION>
390 inline void LinkedList<T>::Apply (FUNCTION&& doToElement)
const
392 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
393 for (
const Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
394 doToElement (i->fItem);
397 template <
typename T>
398 template <predicate<T> FUNCTION>
399 inline auto LinkedList<T>::Find (FUNCTION&& firstThat)
const -> UnderlyingIteratorRep
401 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
402 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
403 if (firstThat (i->fItem)) {
409 template <
typename T>
410 template <
typename EQUALS_COMPARER>
411 T* LinkedList<T>::Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer)
413 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{*
this};
414 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
415 if (equalsComparer (i->fItem, item)) {
421 template <
typename T>
422 template <
typename EQUALS_COMPARER>
423 const T* LinkedList<T>::Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer)
const
425 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
426 for (
const Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
427 if (equalsComparer (i->fItem, item)) {
433 template <
typename T>
438 for (Link_* i = fHead_; i !=
nullptr;) {
447 template <
typename T>
450 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
452 Require (i < size ());
453 const Link_* cur = fHead_;
454 for (; i != 0; cur = cur->fNext, --i) {
460 template <
typename T>
461 void LinkedList<T>::SetAt (T item,
size_t i)
465 Require (i < size ());
467 for (; i != 0; cur = cur->fNext, --i) {
473#if qStroika_Foundation_Debug_AssertionsChecked
474 template <
typename T>
475 void LinkedList<T>::Invariant_ () const noexcept
477#if qStroika_Foundation_Containers_DataStructures_LinkedList_IncludeSlowDebugChecks_
478 AssertExternallySynchronizedMutex::ReadContext declareContext{*
this};
483 for (Link_* i = fHead_; i !=
nullptr; i = i->fNext) {
494 template <
typename T>
495 constexpr LinkedList<T>::ForwardIterator::ForwardIterator ([[maybe_unused]]
const LinkedList* data, UnderlyingIteratorRep startAt) noexcept
497#if qStroika_Foundation_Debug_AssertionsChecked
503 template <
typename T>
504 constexpr LinkedList<T>::ForwardIterator::ForwardIterator (
const LinkedList* data) noexcept
509 template <
typename T>
510 inline void LinkedList<T>::ForwardIterator::Invariant () const noexcept
512#if qStroika_Foundation_Debug_AssertionsChecked
516 template <
typename T>
517 inline LinkedList<T>::ForwardIterator::operator bool ()
const
521 template <
typename T>
522 inline bool LinkedList<T>::ForwardIterator::Done () const noexcept
525 return fCurrent_ ==
nullptr;
527 template <
typename T>
528 inline auto LinkedList<T>::ForwardIterator::operator++ () noexcept -> ForwardIterator&
530 Require (not Done ());
532 Assert (fCurrent_ !=
nullptr);
533 fCurrent_ = fCurrent_->fNext;
537 template <
typename T>
538 inline auto LinkedList<T>::ForwardIterator::operator++ (
int)
noexcept -> ForwardIterator
540 ForwardIterator result = *
this;
544 template <
typename T>
545 inline T LinkedList<T>::ForwardIterator::operator* ()
const
547 Require (not(Done ()));
550 return fCurrent_->fItem;
552 template <
typename T>
553 inline const T* LinkedList<T>::ForwardIterator::operator->()
const
555 Require (not(Done ()));
558 return &fCurrent_->fItem;
560 template <
typename T>
561 size_t LinkedList<T>::ForwardIterator::CurrentIndex (
const LinkedList* data)
const
563 Require (not Done ());
564#if qStroika_Foundation_Debug_AssertionsChecked
565 Require (data == fData_);
570 for (
const Link_* l = data->fHead_;; l = l->fNext, ++i) {
572 if (l == fCurrent_) [[unlikely]] {
579 template <
typename T>
580 inline auto LinkedList<T>::ForwardIterator::GetUnderlyingIteratorRep () const -> UnderlyingIteratorRep
584 template <
typename T>
585 inline void LinkedList<T>::ForwardIterator::SetUnderlyingIteratorRep (
const UnderlyingIteratorRep l)
591 template <
typename T>
592 constexpr void LinkedList<T>::ForwardIterator::AssertDataMatches ([[maybe_unused]]
const LinkedList* data)
const
594#if qStroika_Foundation_Debug_AssertionsChecked
595 Require (data == fData_);
598 template <
typename T>
599 inline bool LinkedList<T>::ForwardIterator::operator== (
const ForwardIterator& rhs)
const
601#if qStroika_Foundation_Debug_AssertionsChecked
602 Require (fData_ ==
nullptr or rhs.fData_ ==
nullptr or fData_ == rhs.fData_);
604 return fCurrent_ == rhs.fCurrent_;
606#if qStroika_Foundation_Debug_AssertionsChecked
607 template <
typename T>
608 void LinkedList<T>::ForwardIterator::Invariant_ () const noexcept