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;
109 nonvirtual
void push_front (ArgByValueType<T> item);
110 template <Memory::ISpanOfT<T> SPAN_T>
111 nonvirtual
void push_front (
const SPAN_T& copyFrom);
123 nonvirtual
void push_back (ArgByValueType<T> item);
124 template <Memory::ISpanOfT<T> SPAN_T>
125 nonvirtual
void push_back (
const SPAN_T& copyFrom);
153 template <
typename EQUALS_COMPARER = equal_to<T>>
154 nonvirtual
bool Contains (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {})
const;
161 template <invocable<T> FUNCTION>
162 nonvirtual
void Apply (FUNCTION&& doToElement)
const;
170 template <
typename FUNCTION>
187 template <
typename EQUALS_COMPARER = equal_to<T>>
188 nonvirtual
void Remove (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {});
189 nonvirtual
void Remove (
const ForwardIterator& i);
198 nonvirtual ForwardIterator
erase (
const ForwardIterator& i);
206 nonvirtual
void clear ();
214 nonvirtual T
GetAt (
size_t i)
const;
222 nonvirtual
void SetAt (
size_t i, ArgByValueType<T> item);
233 nonvirtual
void MoveIteratorHereAfterClone (ForwardIterator* pi,
const DoublyLinkedList<T>* movedFrom)
const;
238 nonvirtual ForwardIterator begin ()
const;
243 constexpr ForwardIterator end () const noexcept;
250 nonvirtual
void SetAt (const ForwardIterator& i, ArgByValueType<T> newValue);
259 nonvirtual
void AddBefore (const ForwardIterator& i, ArgByValueType<T> item);
266 nonvirtual
void AddAfter (const ForwardIterator& i, ArgByValueType<T> item);
269 nonvirtual
void Invariant () const noexcept;
275#if qStroika_Foundation_Debug_AssertionsChecked
277 virtual void Invariant_ () const noexcept;
281 friend class ForwardIterator;
288 template <
typename T>
292 Link_ (const Link_&) = delete;
293 constexpr Link_ (ArgByValueType<T> item, Link_* prev, Link_* next);
297 Link_* fPrev{nullptr};
298 Link_* fNext{nullptr};
307 template <typename T>
308 class DoublyLinkedList<T>::ForwardIterator {
311 using iterator_category = forward_iterator_tag;
312 using value_type = DoublyLinkedList::value_type;
313 using difference_type = ptrdiff_t;
314 using pointer = const value_type*;
315 using reference = const value_type&;
323 constexpr ForwardIterator () noexcept = default;
324 explicit constexpr ForwardIterator (const DoublyLinkedList* data) noexcept;
325 explicit constexpr ForwardIterator (const DoublyLinkedList* data, UnderlyingIteratorRep startAt) noexcept;
326 constexpr ForwardIterator (const ForwardIterator&) noexcept = default;
327 constexpr ForwardIterator (ForwardIterator&&) noexcept = default;
330 nonvirtual ForwardIterator& operator= (const ForwardIterator&) = default;
331 nonvirtual ForwardIterator& operator= (ForwardIterator&&) noexcept = default;
337 explicit operator bool () const;
340 nonvirtual bool Done () const noexcept;
343 nonvirtual const T& operator* () const;
346 nonvirtual const T* operator->() const;
349 nonvirtual ForwardIterator& operator++ () noexcept;
350 nonvirtual ForwardIterator operator++ (int) noexcept;
361 nonvirtual UnderlyingIteratorRep GetUnderlyingIteratorRep () const;
364 nonvirtual void SetUnderlyingIteratorRep (UnderlyingIteratorRep l);
373 nonvirtual bool operator== (const ForwardIterator& rhs) const;
376 nonvirtual void Invariant () const noexcept;
379 const Link_* fCurrent_{
nullptr};
380#if qStroika_Foundation_Debug_AssertionsChecked
381 const DoublyLinkedList* fData_{
nullptr};
384#if qStroika_Foundation_Debug_AssertionsChecked
386 nonvirtual
void Invariant_ () const noexcept;
390 friend class DoublyLinkedList;
393 static_assert (ranges::input_range<DoublyLinkedList<int>>);
402#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 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