16#if qStroika_Foundation_Debug_AssertionsChecked
17 inline ContainerDebugChangeCounts_::ChangeCountType ContainerDebugChangeCounts_::mkInitial_ ()
22 uniform_int_distribution<ChangeCountType> distrib{1, 1000};
26 inline ContainerDebugChangeCounts_::ContainerDebugChangeCounts_ ()
27#if qStroika_Foundation_Debug_AssertionsChecked
28 : fChangeCount{mkInitial_ ()}
32 inline ContainerDebugChangeCounts_::ContainerDebugChangeCounts_ ([[maybe_unused]]
const ContainerDebugChangeCounts_& src)
33#if qStroika_Foundation_Debug_AssertionsChecked
34 : fDeleted{src.fDeleted}
35 , fChangeCount{src.fChangeCount.load ()}
39 inline ContainerDebugChangeCounts_::~ContainerDebugChangeCounts_ ()
41#if qStroika_Foundation_Debug_AssertionsChecked
45 inline void ContainerDebugChangeCounts_::PerformedChange ()
47#if qStroika_Foundation_Debug_AssertionsChecked
57 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
58 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
59 inline IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::IteratorImplHelper_ (
const DATASTRUCTURE_CONTAINER* data,
60 [[maybe_unused]]
const ContainerDebugChangeCounts_* changeCounter,
61 ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
62 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR,
const DATASTRUCTURE_CONTAINER*, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>)
63 : fIterator{data, forward<ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS> (args)...}
65 , fChangeCounter{changeCounter}
66 , fLastCapturedChangeCount{(changeCounter == nullptr) ? 0 : changeCounter->fChangeCount.load ()}
71 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
72 template <
typename... ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS>
73 inline IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::IteratorImplHelper_ (
74 [[maybe_unused]]
const ContainerDebugChangeCounts_* changeCounter, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS&&... args)
75 requires (constructible_from<DATASTRUCTURE_CONTAINER_ITERATOR, ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS...>)
76 : fIterator{forward<ADDITIONAL_BACKEND_ITERATOR_CTOR_ARGUMENTS> (args)...}
78 , fChangeCounter{changeCounter}
79 , fLastCapturedChangeCount{(changeCounter == nullptr) ? 0 : changeCounter->fChangeCount.load ()}
83 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
84 auto IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::Clone () const -> unique_ptr<typename Iterator<T>::IRep>
86 ValidateChangeCount ();
92 if constexpr (is_same_v<BASE_IREP, typename Iterator<T>::IRep>) {
93 return make_unique<IteratorImplHelper_> (*
this);
100 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
101 auto IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::AtEnd () const ->
bool
103 return fIterator.AtEnd ();
105 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
106 optional<T> IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::Current ()
const
108 if (fIterator.AtEnd ()) {
112 return TRAITS::ConvertDataStructureIterationResult2ContainerIteratorResult (*fIterator);
115 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
116 optional<T> IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::More ()
118 Require (not fIterator.AtEnd ());
119 ValidateChangeCount ();
121 if (fIterator.AtEnd ()) [[unlikely]] {
125 return TRAITS::ConvertDataStructureIterationResult2ContainerIteratorResult (*fIterator);
128 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
129 bool IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::Equals (
const typename Iterator<T>::IRep* rhs)
const
132 using ActualIterImplType_ = IteratorImplHelper_;
133 const ActualIterImplType_* rrhs = Debug::UncheckedDynamicCast<const ActualIterImplType_*> (rhs);
134 return fIterator == rrhs->fIterator;
136#if qStroika_Foundation_Debug_AssertionsChecked
137 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
138 void IteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::Invariant () const noexcept
140 ValidateChangeCount ();
143 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
146#if qStroika_Foundation_Debug_AssertionsChecked
147 if (fChangeCounter !=
nullptr) {
148 fLastCapturedChangeCount = fChangeCounter->fChangeCount;
152 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
155#if qStroika_Foundation_Debug_AssertionsChecked
156 if (fChangeCounter !=
nullptr) {
157 Require (not fChangeCounter->fDeleted);
158 Require (fChangeCounter->fChangeCount == fLastCapturedChangeCount);
168 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
171 this->ValidateChangeCount ();
175 if constexpr (is_same_v<BASE_IREP, typename Traversal::BidirectionalIterator<T>::IRep>) {
176 return make_unique<BidirectionalIteratorImplHelper_> (*
this);
183 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
184 bool BidirectionalIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::AtStart ()
const
186 return this->fIterator.AtStart ();
188 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS,
typename BASE_IREP>
189 T BidirectionalIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS, BASE_IREP>::Back ()
191 Require (not this->fIterator.AtStart ());
192 this->ValidateChangeCount ();
194 return *this->fIterator;
202 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS>
203 auto RandomAccessIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS>::Clone () const -> unique_ptr<typename Iterator<T>::IRep>
205 this->ValidateChangeCount ();
206 return make_unique<RandomAccessIteratorImplHelper_> (*
this);
208 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS>
209 void RandomAccessIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS>::Advance (ptrdiff_t i)
211 this->ValidateChangeCount ();
212 this->fIterator += i;
214 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS>
215 ptrdiff_t RandomAccessIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS>::Difference (
const typename Traversal::RandomAccessIterator<T>::IRep* rhs)
const
217 this->ValidateChangeCount ();
218 if (rhs ==
nullptr) {
221 return this->fIterator -
typename TRAITS::DataStructureIteratorT{};
223 using ActualIterImplType_ = RandomAccessIteratorImplHelper_;
224 const ActualIterImplType_* rrhs = Debug::UncheckedDynamicCast<const ActualIterImplType_*> (rhs);
225 return this->fIterator - rrhs->fIterator;
227 template <
typename T,
typename DATASTRUCTURE_CONTAINER,
typename TRAITS>
228 const T* RandomAccessIteratorImplHelper_<T, DATASTRUCTURE_CONTAINER, TRAITS>::PeekAtElement (ptrdiff_t i)
const
230 this->ValidateChangeCount ();
231 return &this->fIterator[i];
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
#define AssertNotReached()
like IteratorImplHelper_ but for bidirectional iterators.
nonvirtual void UpdateChangeCount()
nonvirtual void ValidateChangeCount() const
An Iterator<T> is a copyable object which allows traversing the contents of some container.