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;
77 nonvirtual
void MoveIteratorHereAfterClone (ForwardIterator* pi,
const LinkedList* movedFrom)
const;
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;
119 nonvirtual
void push_front (ArgByValueType<T> item);
134 template <invocable<T> FUNCTION>
135 nonvirtual
void Apply (FUNCTION&& doToElement) const;
151 template <predicate<T> FUNCTION>
153 template <typename EQUALS_COMPARER = equal_to<T>>
154 nonvirtual const T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {})
const;
155 template <
typename EQUALS_COMPARER = equal_to<T>>
156 nonvirtual T*
Find (ArgByValueType<T> item, EQUALS_COMPARER&& equalsComparer = {});
165 nonvirtual T*
PeekAt (
const ForwardIterator& i);
172 nonvirtual
void SetAt (
const ForwardIterator& i, ArgByValueType<T> newValue);
181 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item);
182 nonvirtual
void AddBefore (
const ForwardIterator& i, ArgByValueType<T> item, ForwardIterator* newLinkCreatedAt);
189 nonvirtual
void AddAfter (
const ForwardIterator& i, ArgByValueType<T> item);
198 template <
typename EQUALS_COMPARER>
199 nonvirtual
void Remove (ArgByValueType<T> item,
const EQUALS_COMPARER& equalsComparer);
200 nonvirtual
void Remove (
const ForwardIterator& i);
209 nonvirtual ForwardIterator
erase (
const ForwardIterator& i);
230 nonvirtual
void push_back (ArgByValueType<T> item);
239 nonvirtual T GetAt (
size_t i)
const;
248 nonvirtual
void SetAt (T item,
size_t i);
251 nonvirtual
void Invariant () const noexcept;
254 Link_* fHead_{
nullptr};
256#if qStroika_Foundation_Debug_AssertionsChecked
258 virtual void Invariant_ () const noexcept;
262 friend class ForwardIterator;
268 template <
typename T>
272 constexpr Link_ (ArgByValueType<T> item, Link_* next);
273 Link_ (const Link_&) = delete;
277 Link_* fNext{nullptr};
284 template <typename T>
285 class LinkedList<T>::ForwardIterator {
288 using iterator_category = forward_iterator_tag;
289 using value_type = LinkedList::value_type;
290 using difference_type = ptrdiff_t;
291 using pointer = const value_type*;
292 using reference = const value_type&;
300 constexpr ForwardIterator () noexcept = default;
301 explicit constexpr ForwardIterator (const LinkedList* data) noexcept;
302 explicit constexpr ForwardIterator (const LinkedList* data, UnderlyingIteratorRep startAt) noexcept;
303 constexpr ForwardIterator (const ForwardIterator&) noexcept = default;
304 constexpr ForwardIterator (ForwardIterator&&) noexcept = default;
307 nonvirtual ForwardIterator& operator= (const ForwardIterator&) = default;
308 nonvirtual ForwardIterator& operator= (ForwardIterator&&) noexcept = default;
314 explicit operator bool () const;
317 nonvirtual bool Done () const noexcept;
320 nonvirtual ForwardIterator& operator++ () noexcept;
321 nonvirtual ForwardIterator operator++ (int) noexcept;
324 nonvirtual T operator* () const;
327 nonvirtual const T* operator->() const;
339 nonvirtual UnderlyingIteratorRep GetUnderlyingIteratorRep () const;
342 nonvirtual void SetUnderlyingIteratorRep (const UnderlyingIteratorRep l);
351 nonvirtual bool operator== (const ForwardIterator& rhs) const;
354 nonvirtual void Invariant () const noexcept;
357 const Link_* fCurrent_{
nullptr};
358#if qStroika_Foundation_Debug_AssertionsChecked
359 const LinkedList* fData_{
nullptr};
362#if qStroika_Foundation_Debug_AssertionsChecked
364 nonvirtual
void Invariant_ () const noexcept;
368 friend class LinkedList;
371 static_assert (ranges::input_range<LinkedList<int>>);
380#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 size_t size() const
nonvirtual void SetAt(const ForwardIterator &i, ArgByValueType< T > newValue)
nonvirtual void push_back(ArgByValueType< T > item)
nonvirtual bool empty() const
nonvirtual void push_front(ArgByValueType< T > item)
nonvirtual void RemoveAll()
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