4#ifndef _Stroika_Foundation_Containers_DataStructures_LinkedList_h_
5#define _Stroika_Foundation_Containers_DataStructures_LinkedList_h_
7#include "Stroika/Foundation/StroikaPreComp.h"
11#include "Stroika/Foundation/Common/Common.h"
14#include "Stroika/Foundation/Containers/Common.h"
57 class ForwardIterator;
82 nonvirtual ForwardIterator begin ()
const;
87 constexpr ForwardIterator end () const noexcept;
94 nonvirtual
bool empty () const;
105 nonvirtual
size_t size () const;
112 nonvirtual optional<T>
GetFirst () const;
126 nonvirtual
void push_front (ArgByValueType<T> item);
127 template <Memory::ISpanOfT<T> SPAN_T>
128 nonvirtual
void push_front (const SPAN_T& copyFrom);
142 template <invocable<T> FUNCTION>
143 nonvirtual
void Apply (FUNCTION&& doToElement) const;
159 template <predicate<T> FUNCTION>
161 template <typename EQUALS_COMPARER = equal_to<T>>
162 nonvirtual const T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {})
const;
163 template <
typename EQUALS_COMPARER = equal_to<T>>
164 nonvirtual T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {});
173 nonvirtual T*
PeekAt (
const ForwardIterator& i);
180 nonvirtual
void SetAt (
const ForwardIterator& i, ArgByValueType<T> newValue);
189 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item);
190 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item, ForwardIterator* newLinkCreatedAt);
197 nonvirtual
void AddAfter (
const ForwardIterator& i, ArgByValueType<T> item);
206 template <
typename EQUALS_COMPARER>
207 nonvirtual
void Remove (ArgByValueType<T> item,
const EQUALS_COMPARER& equalsComparer);
208 nonvirtual
void Remove (
const ForwardIterator& i);
217 nonvirtual ForwardIterator
erase (
const ForwardIterator& i);
224 nonvirtual
void clear ();
240 nonvirtual
void push_back (ArgByValueType<T> item);
241 template <Memory::ISpanOfT<T> SPAN_T>
242 nonvirtual
void push_back (
const SPAN_T& copyFrom);
251 nonvirtual T
GetAt (
size_t i)
const;
260 nonvirtual
void SetAt (T item,
size_t i);
265 nonvirtual
void Invariant () const noexcept;
268 Link_* fHead_{
nullptr};
273#if qStroika_Foundation_Debug_AssertionsChecked
275 virtual void Invariant_ () const noexcept;
279 friend class ForwardIterator;
285 template <
typename T>
289 constexpr Link_ (ArgByValueType<T> item, Link_* next);
290 Link_ (const Link_&) = delete;
294 Link_* fNext{nullptr};
301 template <typename T>
302 class LinkedList<T>::ForwardIterator {
305 using iterator_category = forward_iterator_tag;
306 using value_type = LinkedList::value_type;
307 using difference_type = ptrdiff_t;
308 using pointer = const value_type*;
309 using reference = const value_type&;
317 constexpr ForwardIterator () noexcept = default;
318 explicit constexpr ForwardIterator (const LinkedList* data) noexcept;
319 explicit constexpr ForwardIterator (const LinkedList* data, UnderlyingIteratorRep startAt) noexcept;
320 constexpr ForwardIterator (const ForwardIterator&) noexcept = default;
321 constexpr ForwardIterator (ForwardIterator&&) noexcept = default;
324 nonvirtual ForwardIterator& operator= (const ForwardIterator&) = default;
325 nonvirtual ForwardIterator& operator= (ForwardIterator&&) noexcept = default;
331 explicit operator bool () const;
334 nonvirtual bool AtEnd () const noexcept;
337 nonvirtual ForwardIterator& operator++ () noexcept;
338 nonvirtual ForwardIterator operator++ (int) noexcept;
341 nonvirtual T operator* () const;
344 nonvirtual const T* operator->() const;
356 nonvirtual UnderlyingIteratorRep GetUnderlyingIteratorRep () const;
359 nonvirtual void SetUnderlyingIteratorRep (const UnderlyingIteratorRep l);
368 nonvirtual bool operator== (const ForwardIterator& rhs) const;
371 nonvirtual void Invariant () const noexcept;
374 const Link_* fCurrent_{
nullptr};
375#if qStroika_Foundation_Debug_AssertionsChecked
376 const LinkedList* fData_{
nullptr};
379#if qStroika_Foundation_Debug_AssertionsChecked
381 nonvirtual
void Invariant_ () const noexcept;
385 friend class LinkedList;
388 static_assert (ranges::input_range<LinkedList<int>>);
397#include "LinkedList.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.
nonvirtual void Remove(ArgByValueType< T > item, const EQUALS_COMPARER &equalsComparer)
nonvirtual void AddBefore(const ForwardIterator &i, ArgByValueType< T > item)
const Link_ * UnderlyingIteratorRep
nonvirtual T GetAt(size_t i) const
nonvirtual size_t size() const
nonvirtual void SetAt(const ForwardIterator &i, ArgByValueType< T > newValue)
nonvirtual void MoveIteratorHereAfterClone(ForwardIterator *pi, const LinkedList *movedFrom) const
nonvirtual void push_back(ArgByValueType< T > item)
nonvirtual bool empty() const
nonvirtual void push_front(ArgByValueType< T > item)
nonvirtual T * PeekAt(const ForwardIterator &i)
nonvirtual UnderlyingIteratorRep Find(FUNCTION &&firstThat) const
nonvirtual optional< T > GetFirst() const
nonvirtual void RemoveFirst()
nonvirtual ForwardIterator erase(const ForwardIterator &i)
nonvirtual void Apply(FUNCTION &&doToElement) const
nonvirtual void AddAfter(const ForwardIterator &i, ArgByValueType< T > item)
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