Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
KeyedCollection.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
5/*
6 ********************************************************************************
7 ***************************** Implementation Details ***************************
8 ********************************************************************************
9 */
13
15
16 /*
17 ********************************************************************************
18 ******************** KeyedCollection<T, KEY_TYPE, TRAITS> **********************
19 ********************************************************************************
20 */
21 template <typename T, typename KEY_TYPE, typename TRAITS>
22 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
23 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (KEY_EQUALS_COMPARER&& keyComparer)
25 : KeyedCollection{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
26 {
27 _AssertRepValidType ();
28 }
29 template <typename T, typename KEY_TYPE, typename TRAITS>
30 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
31 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const KeyExtractorType& keyExtractor, KEY_EQUALS_COMPARER&& keyComparer)
32 : inherited{Factory::KeyedCollection_Factory<T, KEY_TYPE, TRAITS, remove_cvref_t<KEY_EQUALS_COMPARER>>::Default () (
33 keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer))}
34 {
35 _AssertRepValidType ();
36 }
37 template <typename T, typename KEY_TYPE, typename TRAITS>
38 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const initializer_list<value_type>& src)
39 : KeyedCollection{}
40 {
41 AddAll (src);
42 }
43#if !qCompilerAndStdLib_template_Requires_templateDeclarationMatchesOutOfLine2_Buggy
44 template <typename T, typename KEY_TYPE, typename TRAITS>
45 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
46 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (ITERABLE_OF_ADDABLE&& src)
47 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS> and
48 not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, KeyedCollection<T, KEY_TYPE, TRAITS>>)
49 : KeyedCollection{}
50 {
51 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
52 _AssertRepValidType ();
53 }
54#endif
55#if !qCompilerAndStdLib_template_Requires_templateDeclarationMatchesOutOfLine2_Buggy
56 template <typename T, typename KEY_TYPE, typename TRAITS>
57 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
58 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (KEY_EQUALS_COMPARER&& keyComparer, ITERABLE_OF_ADDABLE&& src)
59 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS> and
60 not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, KeyedCollection<T, KEY_TYPE, TRAITS>>)
61 : KeyedCollection{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
62 {
63 AddAll (src);
64 _AssertRepValidType ();
65 }
66#endif
67 template <typename T, typename KEY_TYPE, typename TRAITS>
68 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER, IIterableOfTo<T> ITERABLE_OF_ADDABLE>
69 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const KeyExtractorType& keyExtractor, KEY_EQUALS_COMPARER&& keyComparer,
70 ITERABLE_OF_ADDABLE&& src)
71 : KeyedCollection{keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer)}
72 {
73 AddAll (src);
74 _AssertRepValidType ();
75 }
76 template <typename T, typename KEY_TYPE, typename TRAITS>
77 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
78 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const KeyExtractorType& keyExtractor, ITERABLE_OF_ADDABLE&& src)
79 requires (IEqualsComparer<KEY_TYPE, equal_to<KEY_TYPE>>)
80 : KeyedCollection{keyExtractor, equal_to<KEY_TYPE>{}}
81 {
82 AddAll (src);
83 _AssertRepValidType ();
84 }
85 template <typename T, typename KEY_TYPE, typename TRAITS>
86 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
87 KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
88 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
89 : KeyedCollection{KeyExtractorType{}, KEY_EQUALS_COMPARER{}}
90 {
91 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
92 _AssertRepValidType ();
93 }
94 template <typename T, typename KEY_TYPE, typename TRAITS>
95 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2, IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER>
96 KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (KEY_EQUALS_COMPARER&& keyComparer, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
97 requires (IKeyedCollection_ExtractorCanBeDefaulted<T, KEY_TYPE, TRAITS>)
98 : KeyedCollection{KeyExtractorType{}, forward<KEY_EQUALS_COMPARER> (keyComparer)}
99 {
100 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
101 _AssertRepValidType ();
102 }
103 template <typename T, typename KEY_TYPE, typename TRAITS>
104 template <IEqualsComparer<KEY_TYPE> KEY_EQUALS_COMPARER, IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
105 KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const KeyExtractorType& keyExtractor, KEY_EQUALS_COMPARER&& keyComparer,
106 ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
107 : KeyedCollection{keyExtractor, forward<KEY_EQUALS_COMPARER> (keyComparer)}
108 {
109 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
110 _AssertRepValidType ();
111 }
112 template <typename T, typename KEY_TYPE, typename TRAITS>
113 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (const shared_ptr<_IRep>& rep) noexcept
114 : inherited{(RequireExpression (rep != nullptr), rep)}
115 {
116 _AssertRepValidType ();
117 }
118 template <typename T, typename KEY_TYPE, typename TRAITS>
119 inline KeyedCollection<T, KEY_TYPE, TRAITS>::KeyedCollection (shared_ptr<_IRep>&& rep) noexcept
120 : inherited{(RequireExpression (rep != nullptr), move (rep))}
121 {
122 _AssertRepValidType ();
123 }
124 template <typename T, typename KEY_TYPE, typename TRAITS>
126 {
127 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().GetKeyExtractor ();
128 }
129 template <typename T, typename KEY_TYPE, typename TRAITS>
131 {
132 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().GetKeyEqualityComparer ();
133 }
134 template <typename T, typename KEY_TYPE, typename TRAITS>
136 {
137 return this->template Map<Iterable<KEY_TYPE>> ([keyExtractor = this->GetKeyExtractor ()] (const T& t) { return keyExtractor (t); });
138 }
139 template <typename T, typename KEY_TYPE, typename TRAITS>
140 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Contains (ArgByValueType<KEY_TYPE> key) const
141 {
142 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, nullptr);
143 }
144 template <typename T, typename KEY_TYPE, typename TRAITS>
145 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Contains (ArgByValueType<value_type> elt) const
146 {
147 _SafeReadRepAccessor<_IRep> r{this};
148 return r._ConstGetRep ().Lookup (r._ConstGetRep ().GetKeyExtractor () (elt), nullptr);
149 }
150 template <typename T, typename KEY_TYPE, typename TRAITS>
151 inline auto KeyedCollection<T, KEY_TYPE, TRAITS>::Lookup (ArgByValueType<KeyType> key) const -> optional<value_type>
152 {
153 optional<T> r;
154 [[maybe_unused]] bool result = _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, &r);
155 Ensure (result == r.has_value ());
156 return r;
157 }
158 template <typename T, typename KEY_TYPE, typename TRAITS>
159 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Lookup (ArgByValueType<KeyType> key, optional<value_type>* item) const
160 {
161 if (item == nullptr) {
162 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, nullptr);
163 }
164 else {
165 optional<value_type> tmp;
166 if (_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, &tmp)) {
167 *item = *tmp;
168 return true;
169 }
170 return false;
171 }
172 }
173 template <typename T, typename KEY_TYPE, typename TRAITS>
174 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Lookup (ArgByValueType<KeyType> key, value_type* item) const
175 {
176 if (item == nullptr) {
177 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, nullptr);
178 }
179 else {
180 optional<value_type> tmp;
181 if (_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, &tmp)) {
182 *item = *tmp;
183 return true;
184 }
185 return false;
186 }
187 }
188 template <typename T, typename KEY_TYPE, typename TRAITS>
189 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Lookup (ArgByValueType<KeyType> key, nullptr_t) const
190 {
191 return _SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().Lookup (key, nullptr);
192 }
193 template <typename T, typename KEY_TYPE, typename TRAITS>
194 template <typename THROW_IF_MISSING>
195 inline auto KeyedCollection<T, KEY_TYPE, TRAITS>::LookupChecked (ArgByValueType<KeyType> key, THROW_IF_MISSING&& throwIfMissing) const -> value_type
196 {
197 if (optional<value_type> r{Lookup (key)}) [[likely]] {
198 return *r;
199 }
200 Execution::Throw (forward<THROW_IF_MISSING> (throwIfMissing));
201 }
202 template <typename T, typename KEY_TYPE, typename TRAITS>
203 inline auto KeyedCollection<T, KEY_TYPE, TRAITS>::LookupValue (ArgByValueType<KeyType> key, ArgByValueType<value_type> defaultValue) const -> value_type
204 {
205 optional<value_type> r{Lookup (key)};
206 return r.has_value () ? *r : defaultValue;
207 }
208 template <typename T, typename KEY_TYPE, typename TRAITS>
209 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::Add (ArgByValueType<value_type> t)
210 {
211 return _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().Add (t);
212 }
213 template <typename T, typename KEY_TYPE, typename TRAITS>
214 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
215 unsigned int KeyedCollection<T, KEY_TYPE, TRAITS>::AddAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
216 {
217 unsigned int cntAdded{};
218 _SafeReadWriteRepAccessor<_IRep> r{this};
219 for (auto i = forward<ITERATOR_OF_ADDABLE> (start); i != forward<ITERATOR_OF_ADDABLE2> (end); ++i) {
220 if (r._GetWriteableRep ().Add (*i)) {
221 ++cntAdded;
222 }
223 }
224 return cntAdded;
225 }
226 template <typename T, typename KEY_TYPE, typename TRAITS>
227 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
228 inline unsigned int KeyedCollection<T, KEY_TYPE, TRAITS>::AddAll (ITERABLE_OF_ADDABLE&& items)
229 {
230 if constexpr (same_as<remove_cvref_t<ITERABLE_OF_ADDABLE>, KeyedCollection>) {
231 // avoid trouble with a.AddAll(a);
232 if (this != &items) {
233 return AddAll (std::begin (items), std::end (items));
234 }
235 return 0;
236 }
237 else {
238 return AddAll (std::begin (items), std::end (items));
239 }
240 }
241 template <typename T, typename KEY_TYPE, typename TRAITS>
242 inline void KeyedCollection<T, KEY_TYPE, TRAITS>::Remove (ArgByValueType<KeyType> key)
243 {
244 Verify (_SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().RemoveIf (key));
245 }
246 template <typename T, typename KEY_TYPE, typename TRAITS>
247 inline void KeyedCollection<T, KEY_TYPE, TRAITS>::Remove (ArgByValueType<value_type> elt)
248 {
249 _SafeReadWriteRepAccessor<_IRep> writeAccessor{this};
250 Verify (writeAccessor._GetWriteableRep ().RemoveIf (writeAccessor._ConstGetRep ().GetKeyExtractor () (elt)));
251 }
252 template <typename T, typename KEY_TYPE, typename TRAITS>
254 {
255 Require (not i.Done ());
256 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
257 writerRep->Remove (patchedIterator, nextI);
258 }
259 template <typename T, typename KEY_TYPE, typename TRAITS>
260 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveIf (ArgByValueType<KeyType> key)
261 {
262 return _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ().RemoveIf (key);
263 }
264 template <typename T, typename KEY_TYPE, typename TRAITS>
265 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveIf (ArgByValueType<value_type> elt)
266 {
267 _SafeReadWriteRepAccessor<_IRep> r{this};
268 return r._GetWriteableRep ().Remove (r._ConstGetRep ().GetKeyExtractor () (elt));
269 }
270 template <typename T, typename KEY_TYPE, typename TRAITS>
271 inline void KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveAll ()
272 {
273 _SafeReadRepAccessor<_IRep> tmp{this}; // important to use READ not WRITE accessor, because write accessor would have already cloned the data
274 if (not tmp._ConstGetRep ().empty ()) {
275 this->_fRep = tmp._ConstGetRep ().CloneEmpty ();
276 }
277 }
278 template <typename T, typename KEY_TYPE, typename TRAITS>
279 template <predicate<T> PREDICATE>
280 size_t KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveAll (PREDICATE&& p)
281 {
282 size_t nRemoved{};
283 for (Iterator<T> i = this->begin (); i != this->end ();) {
284 if (p (*i)) {
285 Remove (i, &i);
286 ++nRemoved;
287 }
288 else {
289 ++i;
290 }
291 }
292 return nRemoved;
293 }
294 template <typename T, typename KEY_TYPE, typename TRAITS>
295 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
296 inline size_t KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveAll (const ITERABLE_OF_ADDABLE& items)
297 {
298 size_t cnt{};
299 for (const auto& i : items) {
300 Remove (i.first);
301 ++cnt;
302 }
303 return cnt;
304 }
305 template <typename T, typename KEY_TYPE, typename TRAITS>
306 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
307 inline size_t KeyedCollection<T, KEY_TYPE, TRAITS>::RemoveAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
308 {
309 size_t cnt{};
310 for (auto i = forward<ITERATOR_OF_ADDABLE> (start); i != end; ++i) {
311 Remove (i->first);
312 ++cnt;
313 }
314 return cnt;
315 }
316 template <typename T, typename KEY_TYPE, typename TRAITS>
317 template <typename RESULT_CONTAINER, invocable<T> ELEMENT_MAPPER>
318 inline RESULT_CONTAINER KeyedCollection<T, KEY_TYPE, TRAITS>::Map (ELEMENT_MAPPER&& elementMapper) const
319 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, typename RESULT_CONTAINER::value_type> or
320 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>)
321 {
322 if constexpr (same_as<RESULT_CONTAINER, KeyedCollection>) {
323 // clone the rep so we retain the this' intrinsic properties (besides data, eg extractor, ordering, reptype)
324 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper),
325 RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().CloneEmpty ()});
326 }
327 else {
328 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper)); // default Iterable<> interpretation
329 }
330 }
331 template <typename T, typename KEY_TYPE, typename TRAITS>
332 template <derived_from<Iterable<T>> RESULT_CONTAINER, predicate<T> INCLUDE_PREDICATE>
333 inline auto KeyedCollection<T, KEY_TYPE, TRAITS>::Where (INCLUDE_PREDICATE&& includeIfTrue) const -> RESULT_CONTAINER
334 {
335 if constexpr (same_as<RESULT_CONTAINER, KeyedCollection>) {
336 // clone the rep so we retain the this' intrindic properties (besides data, eg extractor, ordering, reptype)
337 return inherited::template Where<RESULT_CONTAINER> (
338 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{this}._ConstGetRep ().CloneEmpty ()});
339 }
340 else {
341 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue)); // default Iterable<> interpretation
343 }
344 template <typename T, typename KEY_TYPE, typename TRAITS>
346 {
347 return EqualsComparer{}(*this, rhs);
348 }
349 template <typename T, typename KEY_TYPE, typename TRAITS>
351 {
352 return EqualsComparer{}(*this, rhs);
353 }
354 template <typename T, typename KEY_TYPE, typename TRAITS>
356 {
357 Add (item);
358 return *this;
359 }
360 template <typename T, typename KEY_TYPE, typename TRAITS>
362 {
363 AddAll (items);
364 return *this;
365 }
366 template <typename T, typename KEY_TYPE, typename TRAITS>
369 Remove (item);
370 return *this;
371 }
372 template <typename T, typename KEY_TYPE, typename TRAITS>
374 {
375 RemoveAll (items);
376 return *this;
377 }
378 template <typename T, typename KEY_TYPE, typename TRAITS>
380 {
381 RemoveAll ();
382 }
383 template <typename T, typename KEY_TYPE, typename TRAITS>
384 inline void KeyedCollection<T, KEY_TYPE, TRAITS>::erase (ArgByValueType<value_type> item)
385 {
386 this->Remove (item);
387 }
388 template <typename T, typename KEY_TYPE, typename TRAITS>
390 {
391 Iterator<T> nextI{nullptr};
392 this->Remove (i, &nextI);
393 return nextI;
394 }
395 template <typename T, typename KEY_TYPE, typename TRAITS>
397 -> tuple<_IRep*, Iterator<value_type>>
398 {
399 Require (not i.Done ());
400 using element_type = typename inherited::_SharedByValueRepType::element_type;
401 Iterator<value_type> patchedIterator = i;
402 element_type* writableRep = this->_fRep.rwget ([&] (const element_type& prevRepPtr) -> typename inherited::_SharedByValueRepType::shared_ptr_type {
403 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
404 });
405 AssertNotNull (writableRep);
406 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
407 }
408 template <typename T, typename KEY_TYPE, typename TRAITS>
410 {
412 [[maybe_unused]] _SafeReadRepAccessor<_IRep> ignored{this};
413 }
414 }
415
416 /*
417 ********************************************************************************
418 ********** KeyedCollection<T, KEY_TYPE, TRAITS>::EqualsComparer ****************
419 ********************************************************************************
420 */
421 template <typename T, typename KEY_TYPE, typename TRAITS>
422 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::EqualsComparer::operator() (const KeyedCollection& lhs, const KeyedCollection& rhs) const
423 {
424 return operator() (lhs, static_cast<const Iterable<T>&> (rhs)); // use common-code
425 }
426 template <typename T, typename KEY_TYPE, typename TRAITS>
427 bool KeyedCollection<T, KEY_TYPE, TRAITS>::EqualsComparer::operator() (const KeyedCollection& lhs, const Iterable<value_type>& rhs) const
428 {
429 _SafeReadRepAccessor<_IRep> lhsR{&lhs};
430 _SafeReadRepAccessor<_IRep> rhsR{&rhs};
431 if (&lhsR._ConstGetRep () == &rhsR._ConstGetRep ()) {
432 // not such an unlikely test result since we use lazy copy, but this test is only an optimization and not logically required
433 return true;
434 }
435 // Check length, so we don't need to check both iterators for end/done
436 if (lhsR._ConstGetRep ().size () != rhsR._ConstGetRep ().size ()) {
437 return false;
438 }
439
440 /*
441 * Order is meaningless for KeyedCollection<>, so treat like set. Iterate over Iterable<T> on rhs, and check for contains
442 * on LHS (known to have relatively fast lookup).
443 *
444 * Leverage fact we know by this point the two iterables have the same length.
445 */
446 for (const auto& ri : rhs) {
447 if (not lhs.Contains (ri)) {
448 return false;
449 }
450 }
451 return true;
452 }
453 template <typename T, typename KEY_TYPE, typename TRAITS>
454 inline bool KeyedCollection<T, KEY_TYPE, TRAITS>::EqualsComparer::operator() (const Iterable<value_type>& lhs, const KeyedCollection& rhs) const
455 {
456 return operator() (rhs, lhs); // use commutativity of ==
457 }
458
459}
#define AssertNotNull(p)
Definition Assertions.h:333
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:48
#define RequireExpression(c)
Definition Assertions.h:267
#define Verify(c)
Definition Assertions.h:419
a cross between Mapping<KEY, T> and Collection<T> and Set<T>
nonvirtual KeyedCollection & operator+=(ArgByValueType< value_type > item)
nonvirtual bool operator==(const KeyedCollection &rhs) const
nonvirtual value_type LookupValue(ArgByValueType< KeyType > key, ArgByValueType< value_type > defaultValue=value_type{}) const
nonvirtual void erase(ArgByValueType< value_type > item)
nonvirtual bool Add(ArgByValueType< value_type > item)
nonvirtual KeyedCollection & operator-=(ArgByValueType< value_type > item)
nonvirtual bool Contains(ArgByValueType< KeyType > item) const
nonvirtual KeyExtractorType GetKeyExtractor() const
nonvirtual bool RemoveIf(ArgByValueType< KeyType > item)
nonvirtual RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
KeyedCollection(KEY_EQUALS_COMPARER &&keyComparer=KEY_EQUALS_COMPARER{})
nonvirtual KeyEqualityComparerType GetKeyEqualityComparer() const
typename TRAITS::KeyExtractorType KeyExtractorType
nonvirtual void Remove(const Iterator< value_type > &i, const Iterator< value_type > *nextI=nullptr)
Remove the argument value (which must exist) from the KeyedCollection.
nonvirtual tuple< _IRep *, Iterator< value_type > > _GetWritableRepAndPatchAssociatedIterator(const Iterator< value_type > &i)
Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRe...
nonvirtual unsigned int AddAll(ITERATOR_OF_ADDABLE &&start, ITERATOR_OF_ADDABLE2 &&end)
nonvirtual optional< value_type > Lookup(ArgByValueType< KeyType > key) const
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to KeyedCollection,...
nonvirtual value_type LookupChecked(ArgByValueType< KeyType > key, THROW_IF_MISSING &&throwIfMissing) const
nonvirtual Iterable< KeyType > Keys() const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225
nonvirtual bool Done() const
Done () means there is nothing left in this iterator (a synonym for (it == container....
Definition Iterator.inl:147
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43