4#ifndef _Stroika_Foundation_Containers_DataStructures_DoublyLinkedList_h_
5#define _Stroika_Foundation_Containers_DataStructures_DoublyLinkedList_h_
7#include "Stroika/Foundation/StroikaPreComp.h"
9#include "Stroika/Foundation/Common/Common.h"
12#include "Stroika/Foundation/Containers/Common.h"
69 class ForwardIterator;
76 nonvirtual
bool empty ()
const;
83 nonvirtual
size_t size ()
const;
90 nonvirtual optional<T>
GetFirst ()
const;
97 nonvirtual optional<T>
GetLast ()
const;
106 nonvirtual
void push_front (ArgByValueType<T> item);
115 nonvirtual
void push_back (ArgByValueType<T> item);
143 template <
typename EQUALS_COMPARER = equal_to<T>>
144 nonvirtual
bool Contains (ArgByValueType<T> item,
const EQUALS_COMPARER& equalsComparer = {})
const;
151 template <invocable<T> FUNCTION>
152 nonvirtual
void Apply (FUNCTION&& doToElement)
const;
160 template <
typename FUNCTION>
177 template <
typename EQUALS_COMPARER = equal_to<T>>
178 nonvirtual
void Remove (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {});
179 nonvirtual
void Remove (
const ForwardIterator& i);
188 nonvirtual ForwardIterator
erase (
const ForwardIterator& i);
204 nonvirtual T
GetAt (
size_t i)
const;
212 nonvirtual
void SetAt (
size_t i, ArgByValueType<T> item);
223 nonvirtual
void MoveIteratorHereAfterClone (ForwardIterator* pi,
const DoublyLinkedList<T>* movedFrom)
const;
228 nonvirtual ForwardIterator begin ()
const;
233 constexpr ForwardIterator end () const noexcept;
240 nonvirtual
void SetAt (const ForwardIterator& i, ArgByValueType<T> newValue);
249 nonvirtual
void AddBefore (const ForwardIterator& i, ArgByValueType<T> item);
256 nonvirtual
void AddAfter (const ForwardIterator& i, ArgByValueType<T> item);
259 nonvirtual
void Invariant () const noexcept;
265#if qStroika_Foundation_Debug_AssertionsChecked
267 virtual void Invariant_ () const noexcept;
271 friend class ForwardIterator;
278 template <
typename T>
282 Link_ (const Link_&) = delete;
283 constexpr Link_ (ArgByValueType<T> item, Link_* prev, Link_* next);
287 Link_* fPrev{nullptr};
288 Link_* fNext{nullptr};
297 template <typename T>
298 class DoublyLinkedList<T>::ForwardIterator {
301 using iterator_category = forward_iterator_tag;
302 using value_type = DoublyLinkedList::value_type;
303 using difference_type = ptrdiff_t;
304 using pointer = const value_type*;
305 using reference = const value_type&;
313 constexpr ForwardIterator () noexcept = default;
314 explicit constexpr ForwardIterator (const DoublyLinkedList* data) noexcept;
315 explicit constexpr ForwardIterator (const DoublyLinkedList* data, UnderlyingIteratorRep startAt) noexcept;
316 constexpr ForwardIterator (const ForwardIterator&) noexcept = default;
317 constexpr ForwardIterator (ForwardIterator&&) noexcept = default;
320 nonvirtual ForwardIterator& operator= (const ForwardIterator&) = default;
321 nonvirtual ForwardIterator& operator= (ForwardIterator&&) noexcept = default;
327 explicit operator bool () const;
330 nonvirtual bool Done () const noexcept;
333 nonvirtual const T& operator* () const;
336 nonvirtual const T* operator->() const;
339 nonvirtual ForwardIterator& operator++ () noexcept;
340 nonvirtual ForwardIterator operator++ (int) noexcept;
351 nonvirtual UnderlyingIteratorRep GetUnderlyingIteratorRep () const;
354 nonvirtual void SetUnderlyingIteratorRep (UnderlyingIteratorRep l);
363 nonvirtual bool operator== (const ForwardIterator& rhs) const;
366 nonvirtual void Invariant () const noexcept;
369 const Link_* fCurrent_{
nullptr};
370#if qStroika_Foundation_Debug_AssertionsChecked
371 const DoublyLinkedList* fData_{
nullptr};
374#if qStroika_Foundation_Debug_AssertionsChecked
376 nonvirtual
void Invariant_ () const noexcept;
380 friend class DoublyLinkedList;
383 static_assert (ranges::input_range<DoublyLinkedList<int>>);
392#include "DoublyLinkedList.inl"
conditional_t< qStroika_Foundation_Memory_PreferBlockAllocation and andTrueCheck, BlockAllocationUseHelper< T >, Common::Empty > UseBlockAllocationIfAppropriate
Use this to enable block allocation for a particular class. Beware of subclassing.
const Link_ * UnderlyingIteratorRep
nonvirtual void AddBefore(const ForwardIterator &i, ArgByValueType< T > item)
nonvirtual void push_back(ArgByValueType< T > item)
nonvirtual ForwardIterator erase(const ForwardIterator &i)
nonvirtual size_t size() const
nonvirtual void Remove(ArgByValueType< T > item, EQUALS_COMPARER &&equalsComparer={})
nonvirtual void Apply(FUNCTION &&doToElement) const
nonvirtual void SetAt(size_t i, ArgByValueType< T > item)
nonvirtual optional< T > GetLast() const
nonvirtual T GetAt(size_t i) const
nonvirtual UnderlyingIteratorRep Find(FUNCTION &&firstThat) const
nonvirtual bool empty() const
nonvirtual optional< T > GetFirst() const
nonvirtual void push_front(ArgByValueType< T > item)
nonvirtual void RemoveLast()
nonvirtual void RemoveAll()
nonvirtual void AddAfter(const ForwardIterator &i, ArgByValueType< T > item)
nonvirtual void RemoveFirst()
NOT a real mutex - just a debugging infrastructure support tool so in debug builds can be assured thr...
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
constexpr void AssertDataMatches(const DoublyLinkedList *data) const
nonvirtual size_t CurrentIndex(const DoublyLinkedList *data) const