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"
32 struct ContainerDebugChangeCounts_ {
33 using ChangeCountType =
unsigned int;
34#if qStroika_Foundation_Debug_AssertionsChecked
35 static ChangeCountType mkInitial_ ();
38 ContainerDebugChangeCounts_ ();
39 ContainerDebugChangeCounts_ (
const ContainerDebugChangeCounts_& src);
40 ~ContainerDebugChangeCounts_ ();
42#if qStroika_Foundation_Debug_AssertionsChecked
47 atomic<ChangeCountType> fChangeCount{0};
52 nonvirtual
void PerformedChange ();
55 template <
typename T,
typename DATASTRUCTURE_CONTAINER>
56 struct IteratorImplHelper_DefaultTraits {
57 static_assert (not is_reference_v<T>);
58 static_assert (not is_reference_v<DATASTRUCTURE_CONTAINER>);
59 using DataStructureT = DATASTRUCTURE_CONTAINER;
60 using DataStructureIteratorT =
typename DATASTRUCTURE_CONTAINER::ForwardIterator;
61 using DataStructureContainerValueT =
typename DATASTRUCTURE_CONTAINER::value_type;
65 static constexpr T ConvertDataStructureIterationResult2ContainerIteratorResult (
const DataStructureContainerValueT& t)
68 static_assert (Common::explicitly_convertible_to<DataStructureContainerValueT, T>,
69 "dont use the default traits, but provide your own - see KeyedCollection_HashTable as example");
70 return static_cast<T
> (t);
87 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS = IteratorImplHelper_DefaultTraits<T, DATASTRUCTURE_CONTAINER>>
95 using DATASTRUCTURE_CONTAINER_ITERATOR =
typename TRAITS::DataStructureIteratorT;
96 using DATASTRUCTURE_CONTAINER_VALUE =
typename TRAITS::DataStructureContainerValueT;
99 using DataStructureImplValueType_ = DATASTRUCTURE_CONTAINER_VALUE;
105 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
106 explicit IteratorImplHelper_ (
const DATASTRUCTURE_CONTAINER* data,
const ContainerDebugChangeCounts_* changeCounter =
nullptr,
107 ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
108 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR,
const DATASTRUCTURE_CONTAINER*, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>);
109 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
110 explicit IteratorImplHelper_ (
const ContainerDebugChangeCounts_* changeCounter =
nullptr, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
111 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>);
118 virtual unique_ptr<typename Iterator<T>::IRep>
Clone ()
const override;
119 virtual void More (optional<T>* result,
bool advance)
override;
121#if qStroika_Foundation_Debug_AssertionsChecked
124 virtual void Invariant ()
const noexcept override;
141 mutable DATASTRUCTURE_CONTAINER_ITERATOR fIterator{};
142#if qStroika_Foundation_Debug_AssertionsChecked
143 const ContainerDebugChangeCounts_* fChangeCounter{
nullptr};
144 ContainerDebugChangeCounts_::ChangeCountType fLastCapturedChangeCount{};
155#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.
helper to wrap a low level 'DataStructure Container Iterator' into a 'Stroika' Iterator::IRep iterato...
nonvirtual void ValidateChangeCount() const
virtual void More(optional< T > *result, bool advance) override
nonvirtual void UpdateChangeCount()
virtual unique_ptr< typename Iterator< T >::IRep > Clone() const override
Implementation detail for iterator implementors.
An Iterator<T> is a copyable object which allows traversing the contents of some container....