4#ifndef _Stroika_Foundation_Containers_Private_IteratorImplHelper_h_
5#define _Stroika_Foundation_Containers_Private_IteratorImplHelper_h_
7#include "Stroika/Foundation/StroikaPreComp.h"
9#include "Stroika/Foundation/Common/Common.h"
10#include "Stroika/Foundation/Containers/Common.h"
35 struct ContainerDebugChangeCounts_ {
36 using ChangeCountType =
unsigned int;
37#if qStroika_Foundation_Debug_AssertionsChecked
38 static ChangeCountType mkInitial_ ();
41 ContainerDebugChangeCounts_ ();
42 ContainerDebugChangeCounts_ (
const ContainerDebugChangeCounts_& src);
43 ~ContainerDebugChangeCounts_ ();
45#if qStroika_Foundation_Debug_AssertionsChecked
50 atomic<ChangeCountType> fChangeCount{0};
55 nonvirtual
void PerformedChange ();
58 template <
typename T,
typename DATASTRUCTURE_CONTAINER>
59 struct IteratorImplHelper_DefaultTraits {
60 static_assert (not is_reference_v<T>);
61 static_assert (not is_reference_v<DATASTRUCTURE_CONTAINER>);
62 using DataStructureT = DATASTRUCTURE_CONTAINER;
63 using DataStructureIteratorT =
typename DATASTRUCTURE_CONTAINER::ForwardIterator;
64 using DataStructureContainerValueT =
typename DATASTRUCTURE_CONTAINER::value_type;
68 static constexpr T ConvertDataStructureIterationResult2ContainerIteratorResult (
const DataStructureContainerValueT& t)
71 static_assert (Common::explicitly_convertible_to<DataStructureContainerValueT, T>,
72 "dont use the default traits, but provide your own - see KeyedCollection_HashTable as example");
73 return static_cast<T
> (t);
95 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS = IteratorImplHelper_DefaultTraits<T, DATASTRUCTURE_CONTAINER>,
96 typename BASE_IREP =
typename Iterator<T>::IRep>
100 using inherited = BASE_IREP;
104 using DATASTRUCTURE_CONTAINER_ITERATOR =
typename TRAITS::DataStructureIteratorT;
105 using DATASTRUCTURE_CONTAINER_VALUE =
typename TRAITS::DataStructureContainerValueT;
108 using DataStructureImplValueType_ = DATASTRUCTURE_CONTAINER_VALUE;
114 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
115 explicit IteratorImplHelper_ (
const DATASTRUCTURE_CONTAINER* data,
const ContainerDebugChangeCounts_* changeCounter =
nullptr,
116 ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
117 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR,
const DATASTRUCTURE_CONTAINER*, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>);
118 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
119 explicit IteratorImplHelper_ (
const ContainerDebugChangeCounts_* changeCounter =
nullptr, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
120 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>);
127 virtual unique_ptr<typename Iterator<T>::IRep> Clone ()
const override;
128 virtual bool AtEnd ()
const override;
129 virtual optional<T> Current ()
const override;
130 virtual optional<T> More ()
override;
132#if qStroika_Foundation_Debug_AssertionsChecked
135 virtual void Invariant ()
const noexcept override;
152 mutable DATASTRUCTURE_CONTAINER_ITERATOR fIterator{};
153#if qStroika_Foundation_Debug_AssertionsChecked
154 const ContainerDebugChangeCounts_* fChangeCounter{
nullptr};
155 ContainerDebugChangeCounts_::ChangeCountType fLastCapturedChangeCount{};
167 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS = IteratorImplHelper_DefaultTraits<T, DATASTRUCTURE_CONTAINER>,
168 typename BASE_IREP =
typename Traversal::B
idirectionalIterator<T>::IRep>
174 using inherited::inherited;
182 virtual unique_ptr<typename Iterator<T>::IRep> Clone ()
const override;
185 virtual bool AtStart ()
const override;
186 virtual T Back ()
override;
192 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS = IteratorImplHelper_DefaultTraits<T, DATASTRUCTURE_CONTAINER>>
204 virtual unique_ptr<typename Iterator<T>::IRep> Clone ()
const override;
207 virtual void Advance (ptrdiff_t i)
override;
209 virtual const T* PeekAtElement (ptrdiff_t i)
const override;
219#include "IteratorImplHelper.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.
like IteratorImplHelper_ but for bidirectional iterators.
helper to wrap a low level 'DataStructure Container Iterator' into a 'Stroika' Iterator::IRep iterato...
nonvirtual void UpdateChangeCount()
nonvirtual void ValidateChangeCount() const
like IteratorImplHelper_ but for random access iterators.
Implementation detail for iterator implementors.
The interface for the internal representation of a RandomAccessIterator.