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;
101 nonvirtual
size_t size () const;
108 nonvirtual optional<T>
GetFirst () const;
122 nonvirtual
void push_front (ArgByValueType<T> item);
123 template <Memory::ISpanOfT<T> SPAN_T>
124 nonvirtual
void push_front (const SPAN_T& copyFrom);
138 template <invocable<T> FUNCTION>
139 nonvirtual
void Apply (FUNCTION&& doToElement) const;
155 template <predicate<T> FUNCTION>
157 template <typename EQUALS_COMPARER = equal_to<T>>
158 nonvirtual const T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {})
const;
159 template <
typename EQUALS_COMPARER = equal_to<T>>
160 nonvirtual T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {});
169 nonvirtual T*
PeekAt (
const ForwardIterator& i);
176 nonvirtual
void SetAt (
const ForwardIterator& i, ArgByValueType<T> newValue);
185 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item);
186 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item, ForwardIterator* newLinkCreatedAt);
193 nonvirtual
void AddAfter (
const ForwardIterator& i, ArgByValueType<T> item);
202 template <
typename EQUALS_COMPARER>
203 nonvirtual
void Remove (ArgByValueType<T> item,
const EQUALS_COMPARER& equalsComparer);
204 nonvirtual
void Remove (
const ForwardIterator& i);
213 nonvirtual ForwardIterator
erase (
const ForwardIterator& i);
220 nonvirtual
void clear ();
236 nonvirtual
void push_back (ArgByValueType<T> item);
237 template <Memory::ISpanOfT<T> SPAN_T>
238 nonvirtual
void push_back (
const SPAN_T& copyFrom);
247 nonvirtual T
GetAt (
size_t i)
const;
256 nonvirtual
void SetAt (T item,
size_t i);
261 nonvirtual
void Invariant () const noexcept;
264 Link_* fHead_{
nullptr};
266#if qStroika_Foundation_Debug_AssertionsChecked
268 virtual void Invariant_ () const noexcept;
272 friend class ForwardIterator;
278 template <
typename T>
282 constexpr Link_ (ArgByValueType<T> item, Link_* next);
283 Link_ (const Link_&) = delete;
287 Link_* fNext{nullptr};
294 template <typename T>
295 class LinkedList<T>::ForwardIterator {
298 using iterator_category = forward_iterator_tag;
299 using value_type = LinkedList::value_type;
300 using difference_type = ptrdiff_t;
301 using pointer = const value_type*;
302 using reference = const value_type&;
310 constexpr ForwardIterator () noexcept = default;
311 explicit constexpr ForwardIterator (const LinkedList* data) noexcept;
312 explicit constexpr ForwardIterator (const LinkedList* data, UnderlyingIteratorRep startAt) noexcept;
313 constexpr ForwardIterator (const ForwardIterator&) noexcept = default;
314 constexpr ForwardIterator (ForwardIterator&&) noexcept = default;
317 nonvirtual ForwardIterator& operator= (const ForwardIterator&) = default;
318 nonvirtual ForwardIterator& operator= (ForwardIterator&&) noexcept = default;
324 explicit operator bool () const;
327 nonvirtual bool Done () const noexcept;
330 nonvirtual ForwardIterator& operator++ () noexcept;
331 nonvirtual ForwardIterator operator++ (int) noexcept;
334 nonvirtual T operator* () const;
337 nonvirtual const T* operator->() const;
349 nonvirtual UnderlyingIteratorRep GetUnderlyingIteratorRep () const;
352 nonvirtual void SetUnderlyingIteratorRep (const UnderlyingIteratorRep l);
361 nonvirtual bool operator== (const ForwardIterator& rhs) const;
364 nonvirtual void Invariant () const noexcept;
367 const Link_* fCurrent_{
nullptr};
368#if qStroika_Foundation_Debug_AssertionsChecked
369 const LinkedList* fData_{
nullptr};
372#if qStroika_Foundation_Debug_AssertionsChecked
374 nonvirtual
void Invariant_ () const noexcept;
378 friend class LinkedList;
381 static_assert (ranges::input_range<LinkedList<int>>);
390#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