Stroika Library 3.0d24
 
Loading...
Searching...
No Matches
KeyedCollection_Array.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/Containers/DataStructures/Array.h"
5#include "Stroika/Foundation/Containers/Private/IteratorImplHelper.h"
8
10
11 /*
12 */
13 template <typename T, typename KEY_TYPE, typename TRAITS>
14 template <qCompilerAndStdLib_ConstraintDiffersInTemplateRedeclaration_BWA (IEqualsComparer<KEY_TYPE>) KEY_EQUALS_COMPARER>
15 class KeyedCollection_Array<T, KEY_TYPE, TRAITS>::Rep_ : public Private::ArrayBasedContainerRepImpl<Rep_<KEY_EQUALS_COMPARER>, IImplRepBase_>,
16 public Memory::UseBlockAllocationIfAppropriate<Rep_<KEY_EQUALS_COMPARER>> {
17 private:
18 using inherited = Private::ArrayBasedContainerRepImpl<Rep_<KEY_EQUALS_COMPARER>, IImplRepBase_>;
19
20 private:
21 qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS const KeyExtractorType fKeyExtractor_;
22 qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS const KEY_EQUALS_COMPARER fKeyComparer_;
23
24 public:
25 Rep_ (const KeyExtractorType& keyExtractor, const KEY_EQUALS_COMPARER& keyComparer)
26 : fKeyExtractor_{keyExtractor}
27 , fKeyComparer_{keyComparer}
28 {
29 }
30 Rep_ (const Rep_& from) = default;
31
32 public:
33 nonvirtual Rep_& operator= (const Rep_&) = delete;
34
35 // Iterable<T>::_IRep overrides
36 public:
37 virtual shared_ptr<typename Iterable<T>::_IRep> Clone () const override
38 {
40 return Memory::MakeSharedPtr<Rep_> (*this);
41 }
42 virtual Iterator<value_type> MakeIterator () const override
43 {
45 return Iterator<value_type>{make_unique<IteratorRep_> (&fData_, &fChangeCounts_)};
46 }
47 // MakeIterator () walks fData_ from 0, so storage order IS iteration order.
48 virtual optional<span<const value_type>> PeekContiguousStorage () const override
49 {
51 return span<const value_type>{fData_.data (), fData_.size ()};
52 }
53 virtual size_t size () const override
54 {
56 return fData_.size ();
57 }
58 virtual bool empty () const override
59 {
61 return fData_.empty ();
62 }
63 virtual void Apply (const function<void (ArgByValueType<value_type> item)>& doToElement, [[maybe_unused]] Execution::SequencePolicy seq) const override
64 {
66 fData_.Apply (doToElement);
67 }
68 virtual Iterator<value_type> Find ([[maybe_unused]] bool findFirst, const function<bool (ArgByValueType<value_type> item)>& that,
69 [[maybe_unused]] Execution::SequencePolicy seq) const override
70 {
72 if (auto i = fData_.Find (that)) {
73 return Iterator<value_type>{make_unique<IteratorRep_> (&fChangeCounts_, i)};
74 }
75 return nullptr;
76 }
77
78 // KeyedCollection<T, KEY_TYPE, TRAITS>::_IRep overrides
79 public:
80 virtual KeyExtractorType GetKeyExtractor () const override
81 {
83 return fKeyExtractor_;
84 }
85 virtual KeyEqualityComparerType GetKeyEqualityComparer () const override
86 {
88 return fKeyComparer_;
89 }
90 virtual shared_ptr<typename KeyedCollection<T, KEY_TYPE, TRAITS>::_IRep> CloneEmpty () const override
91 {
93 return Memory::MakeSharedPtr<Rep_> (this->fKeyExtractor_, this->fKeyComparer_); // lose data but keep compare functions
94 }
95 virtual shared_ptr<typename KeyedCollection<T, KEY_TYPE, TRAITS>::_IRep> CloneAndPatchIterator (Iterator<value_type>* i) const override
96 {
99 auto result = Memory::MakeSharedPtr<Rep_> (*this);
100 auto& mir = Debug::UncheckedDynamicCast<const IteratorRep_&> (i->ConstGetRep ());
101 result->fData_.MoveIteratorHereAfterClone (&mir.fIterator, &fData_);
102 i->Refresh (); // reflect updated rep
103 return result;
104 }
105 virtual bool Lookup (ArgByValueType<KeyType> key, optional<value_type>* item) const override
106 {
108 if (auto i = this->Find (
109 /*findFirst*/ true, [this, &key] (ArgByValueType<T> item) { return fKeyComparer_ (fKeyExtractor_ (item), key); }, Execution::SequencePolicy::eSeq)) {
110 if (item != nullptr) {
111 *item = *i;
112 }
113 return true;
114 }
115 return false;
116 }
117 virtual bool Add (ArgByValueType<value_type> item) override
118 {
120 KEY_TYPE key{fKeyExtractor_ (item)};
121 if (auto i = this->Find (
122 /*findFirst*/ true, [this, &key] (ArgByValueType<T> item) { return fKeyComparer_ (fKeyExtractor_ (item), key); }, Execution::SequencePolicy::eSeq)) {
123 const IteratorRep_& iteratorRep = Debug::UncheckedDynamicCast<const IteratorRep_&> (i.ConstGetRep ());
124 fData_.SetAt (iteratorRep.fIterator, item);
125 fChangeCounts_.PerformedChange ();
126 return false;
127 }
128 else {
129 fData_.push_back (item); // order meaningless for collection, and append cheaper on array
130 fChangeCounts_.PerformedChange ();
131 return true;
132 }
133 }
134 virtual void Remove (const Iterator<value_type>& i, Iterator<value_type>* nextI) override
135 {
137 const IteratorRep_& iteratorRep = Debug::UncheckedDynamicCast<const IteratorRep_&> (i.ConstGetRep ());
138 if (nextI == nullptr) {
139 fData_.Remove (iteratorRep.fIterator);
140 fChangeCounts_.PerformedChange ();
141 }
142 else {
143 auto retI = fData_.erase (iteratorRep.fIterator);
144 fChangeCounts_.PerformedChange ();
145 *nextI = Iterator<value_type>{make_unique<IteratorRep_> (&fChangeCounts_, retI)};
146 }
147 }
148 virtual bool RemoveIf (ArgByValueType<KEY_TYPE> key) override
149 {
151 if (auto i = this->Find (
152 /*findFirst*/ true, [this, &key] (ArgByValueType<T> item) { return fKeyComparer_ (fKeyExtractor_ (item), key); }, Execution::SequencePolicy::eSeq)) {
153 Remove (i, nullptr);
154 return true;
155 }
156 return false;
157 }
158
159 private:
160 using DataStructureImplType_ = DataStructures::Array<value_type>;
161 using IteratorRep_ = typename Private::IteratorImplHelper_<value_type, DataStructureImplType_>;
162
163 private:
164 DataStructureImplType_ fData_;
165 qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE Private::ContainerDebugChangeCounts_ fChangeCounts_;
166
167 private:
168 friend inherited;
169 };
170
171 /*
172 ********************************************************************************
173 ***************************** KeyedCollection_Array<T> *************************
174 ********************************************************************************
175 */
176 template <typename T, typename KEY_TYPE, typename TRAITS>
177 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
180 : KeyedCollection_Array{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
181 {
182 AssertRepValidType_ ();
183 }
184 template <typename T, typename KEY_TYPE, typename TRAITS>
185 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
186 inline KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (const KeyExtractorType& keyExtractor, KEY_EQUALS_COMPARER&& keyComparer)
187 : inherited{Memory::MakeSharedPtr<Rep_<KEY_EQUALS_COMPARER>> (keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer))}
188 {
189 AssertRepValidType_ ();
190 }
191#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
192 template <typename T, typename KEY_TYPE, typename TRAITS>
193 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
195 not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, KeyedCollection_Array<T, KEY_TYPE, TRAITS>>)
197 : KeyedCollection_Array{KeyExtractorType{}, equal_to<KEY_TYPE>{}}
198 {
199 this->AddAll (src);
200 AssertRepValidType_ ();
201 }
202#endif
203 template <typename T, typename KEY_TYPE, typename TRAITS>
204 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
205 inline KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (KEY_EQUALS_COMPARER&& keyComparer, ITERABLE_OF_ADDABLE&& src)
206 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
207 : KeyedCollection_Array{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
208 {
209 this->AddAll (src);
210 AssertRepValidType_ ();
211 }
212 template <typename T, typename KEY_TYPE, typename TRAITS>
213 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER, IIterableOfTo<T> ITERABLE_OF_ADDABLE>
214 inline KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (const KeyExtractorType& keyExtractor,
215 KEY_EQUALS_COMPARER&& keyComparer, ITERABLE_OF_ADDABLE&& src)
216 : KeyedCollection_Array{keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer)}
217 {
218 this->AddAll (src);
219 AssertRepValidType_ ();
220 }
221 template <typename T, typename KEY_TYPE, typename TRAITS>
222 template <IInputIterator<T> ITERATOR_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
223 KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
224 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
225 : KeyedCollection_Array{KeyExtractorType{}, KEY_EQUALS_COMPARER{}}
226 {
227 this->AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE> (end));
228 AssertRepValidType_ ();
229 }
230 template <typename T, typename KEY_TYPE, typename TRAITS>
231 template <IInputIterator<T> ITERATOR_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
232 KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (KEY_EQUALS_COMPARER&& keyComparer, ITERATOR_OF_ADDABLE&& start,
233 ITERATOR_OF_ADDABLE&& end)
234 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
235 : KeyedCollection_Array{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
236 {
237 this->AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE> (end));
238 AssertRepValidType_ ();
239 }
240 template <typename T, typename KEY_TYPE, typename TRAITS>
241 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER, IInputIterator<T> ITERATOR_OF_ADDABLE>
242 KeyedCollection_Array<T, KEY_TYPE, TRAITS>::KeyedCollection_Array (const KeyExtractorType& keyExtractor, KEY_EQUALS_COMPARER&& keyComparer,
243 ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
244 : KeyedCollection_Array{keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer)}
245 {
246 this->AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE> (end));
247 AssertRepValidType_ ();
248 }
249 template <typename T, typename KEY_TYPE, typename TRAITS>
250 inline void KeyedCollection_Array<T, KEY_TYPE, TRAITS>::AssertRepValidType_ () const
251 {
253 typename inherited::template _SafeReadRepAccessor<IImplRepBase_> tmp{this}; // for side-effect of AssertMemeber
254 }
255 }
256
257}
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:49
#define RequireNotNull(p)
Definition Assertions.h:348
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS
qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS - used for the attribute [[no_unique_address]]
Definition StdCompat.h:433
#define qStroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
Definition StdCompat.h:443
KeyedCollection_Array<T> is an Array-based concrete implementation of the KeyedCollection<T> containe...
KeyedCollection_Array(KEY_EQUALS_COMPARER &&keyComparer=KEY_EQUALS_COMPARER{})
unique_lock< AssertExternallySynchronizedChecker > WriteContext
Instantiate AssertExternallySynchronizedChecker::WriteContext to designate an area of code where prot...
shared_lock< const AssertExternallySynchronizedChecker > ReadContext
Instantiate AssertExternallySynchronizedChecker::ReadContext to designate an area of code where prote...
SequencePolicy
equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy,...
@ eSeq
default case - not parallelized