Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Set.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Containers_Set_h_
5#define _Stroika_Foundation_Containers_Set_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include "Stroika/Foundation/Common/Common.h"
11#include "Stroika/Foundation/Common/Concepts.h"
12#include "Stroika/Foundation/Containers/Common.h"
15
16/**
17 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
18 *
19 * TODO:
20 * @todo Implement more backends
21 * > Set_BitString
22 * > Set_Array
23 * > Set_HashTable
24 * > Set_RedBlackTree
25 * > Set_stlunordered_set (really is hashset)
26 * > Set_Treap
27 *
28 * @todo Consider if Union/Difference etc methods should delegate to virtual reps? Or other better
29 * performance approaches? One closely related issue is the backend type returned. Now we use
30 * default but maybe should use left or right side type?
31 *
32 * @todo http://stroika-bugs.sophists.com/browse/STK-754 - Add (REP METHOD) should return bool if really added (if size changed) to make a few things
33 * like addif cheaper. But think through carefully semantics of object - we actually change what is there, but it maybe just padding
34 * something - so DOES have affect but doesnt change if its present or not.
35 */
36
38
40 using Common::IEqualsComparer;
41 using Traversal::IInputIterator;
42 using Traversal::IIterableOfTo;
43 using Traversal::Iterable;
44 using Traversal::Iterator;
45
46 /**
47 * \brief Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
48 *
49 * The Set class is based on SmallTalk-80, The Language & Its Implementation,
50 * page 148.
51 *
52 * The basic idea here is that you cannot have multiple copies of the same
53 * thing into the set (like a mathematical set).
54 *
55 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety">C++-Standard-Thread-Safety</a>
56 *
57 * \em vs std::set<T>:
58 * Stroika's Set<T> is like std::set<T>, except that
59 * o you can separately select different algorithms (besides red-black tree) and not change the API used (Set<T>).
60 * o You don't need to have a less<T> method defined. You just need to provide some mechanism (either operator== or argument to constructor)
61 * saying how to compare elements for equality
62 * o If you have a less<T> already defined, like std::set<T>, this will be used by default to construct a tree-based set.
63 * o Sets can also be implemented by hash-tables, etc.
64 *
65 * \em Concrete Implementations:
66 * o @see Concrete::Set_Array<>
67 * o @see Concrete::Set_LinkedList<>
68 * o @see Concrete::SortedSet_stdset<>
69 * o @see Concrete::SortedSet_SkipList<>
70 *
71 * \em Factory:
72 * @see Set_Factory<> to see default implementations.
73 *
74 * \note See also: KeyedCollection<> - like Set<>, but for case where object has extra attributes to be preserved (Add)
75 *
76 * \note <a href="ReadMe.md#Container Element comparisons">Container Element comparisons</a>:
77 * See about ElementInOrderComparerType, ElementThreeWayComparerType and GetElementThreeWayComparer etc
78 *
79 * \em Design Note:
80 * Included <set> and have explicit CTOR for set<> so that Stroika Set can be used more interoperably
81 * with set<> - and used without an explicit CTOR. Use Explicit CTOR to avoid accidental conversions. But
82 * if you declare an API with Set<T> arguments, its important STL sources passing in set<T> work transparently.
83 *
84 * Similarly for std::initializer_list.
85 *
86 * \note See <a href="./ReadMe.md">ReadMe.md</a> for common features of all Stroika containers (especially
87 * constructors, iterators, etc)
88 *
89 * \note Note About Update method
90 * We intentionally omit the Update () method since update given an iterator would do the same thing
91 * as Container::Add(). We COULD enhance Add () to take an optional hint parameter in a future version of Stroika.
92 *
93 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
94 * o static_assert (equality_comparable<Set<T>)
95 *
96 * o ordering (<,<=> etc) not provided, because a set has no intrinsic ordering between the set elements
97 * o when comparing a Set to any Iterable<> - this is treated as 'set' equality comparison
98 *
99 * It remains questionable whether or not we should have overloads for comparing Set<> and Iterable<>. When
100 * also done with other containers like Sequence, this could produce ambiguity. (like comparing Set with Sequence).
101 * But that's probably OK, because when we have ambiguity, we can always explicitly resolve it. So keep these
102 * overloads which are pretty convenient.
103 */
104 template <typename T>
105 class [[nodiscard]] Set : public Iterable<T> {
106 private:
107 using inherited = Iterable<T>;
108
109 protected:
110 class _IRep;
111
112 public:
113 /**
114 * Use this typedef in templates to recover the basic functional container pattern of concrete types.
115 */
117
118 public:
119 /**
120 * @see inherited::value_type
121 */
123
124 public:
125 /**
126 * @see inherited::const_iterator
127 */
129
130 public:
131 /**
132 * This is the type returned by GetElementEqualsComparer () and CAN be used as the argument to a Set<> as EqualityComparer, but
133 * we allow any template in the Set<> CTOR for an equalityComparer that follows the IEqualsComparer () concept.
134 *
135 * \note @see also EqualsComparer{} to compare entire Set<>s
136 */
137 using ElementEqualityComparerType = Common::ComparisonRelationDeclaration<Common::ComparisonRelationType::eEquals, function<bool (T, T)>>;
138
139 public:
140 /**
141 * For the CTOR overload with ITERABLE_OF_ADDABLE, its anything that supports c.begin(), c.end () to find
142 * all the elements.
143 *
144 * All constructors either copy their source comparer (copy/move CTOR), or use the provided argument comparer
145 * (which in turn defaults to equal_to<T>).
146 *
147 * \note For efficiency sake, the base constructor takes a templated EQUALS_COMPARER (avoiding translation to function<bool(T,T)>>
148 * so the REP can see the actual type, but the container API itself erases this specific type using std::function.
149 *
150 * \note <a href="ReadMe.md#Container Constructors">See general information about container constructors that applies here</a>
151 *
152 * \pre IEqualsComparer<EQUALS_COMPARER> () - for constructors with that type parameter
153 *
154 * \par Example Usage
155 * \code
156 * Collection<int> c;
157 * std::vector<int> v;
158 *
159 * Set<int> s1 = {1, 2, 3};
160 * Set<int> s2 = s1;
161 * Set<int> s3{ s1 };
162 * Set<int> s4{ s1.begin (), s1.end () };
163 * Set<int> s5{ c };
164 * Set<int> s6{ v };
165 * Set<int> s7{ v.begin (), v.end () };
166 * Set<int> s8{ move (s1) };
167 * Set<int> s9{ 1, 2, 3 };
168 * Set<int> s10{ Common::DeclareEqualsComparer ([](int l, int r) { return l == r; }), c };
169 * \endcode
170 */
171 Set ()
172 requires (IEqualsComparer<equal_to<T>, T>);
173 template <IEqualsComparer<T> EQUALS_COMPARER>
174 explicit Set (EQUALS_COMPARER&& equalsComparer);
175 Set (Set&&) noexcept = default;
176 Set (const Set&) noexcept = default;
177 Set (const initializer_list<value_type>& src)
178 requires (IEqualsComparer<equal_to<T>, T>);
179 template <IEqualsComparer<T> EQUALS_COMPARER>
180 Set (EQUALS_COMPARER&& equalsComparer, const initializer_list<value_type>& src);
181 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
182 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, Set<T>>)
183 explicit Set (ITERABLE_OF_ADDABLE&& src)
184#if qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
185 : Set{}
186 {
187 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
188 _AssertRepValidType ();
189 }
190#endif
191 ;
192 template <IEqualsComparer<T> EQUALS_COMPARER, IIterableOfTo<T> ITERABLE_OF_ADDABLE>
193 Set (EQUALS_COMPARER&& equalsComparer, ITERABLE_OF_ADDABLE&& src);
194 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
195 Set (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
196 requires (IEqualsComparer<equal_to<T>, T>);
197 template <IEqualsComparer<T> EQUALS_COMPARER, IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
198 Set (EQUALS_COMPARER&& equalsComparer, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end);
199
200 protected:
201 explicit Set (shared_ptr<_IRep>&& rep) noexcept;
202 explicit Set (const shared_ptr<_IRep>& rep) noexcept;
203
204 public:
205 /**
206 */
207 nonvirtual Set& operator= (Set&&) noexcept = default;
208 nonvirtual Set& operator= (const Set&) = default;
209
210 public:
211 /**
212 * Return the function used to compare if two elements are equal
213 *
214 * \note @see also EqualsComparer{} to compare whole Set<>s
215 */
216 nonvirtual ElementEqualityComparerType GetElementEqualsComparer () const;
217
218 public:
219 /**
220 */
221 nonvirtual bool Contains (ArgByValueType<value_type> item) const;
222
223 public:
224 /**
225 * Mimic stl::set name
226 */
227 nonvirtual bool contains (ArgByValueType<value_type> item) const;
228
229 public:
230 /**
231 * return true iff for all item in 'items' this->Contains(item) returns true (so this is superset of items)
232 */
233 nonvirtual bool ContainsAll (const Iterable<value_type>& items) const;
234
235 public:
236 /**
237 * return true iff for any item in 'items' this->Contains(item) returns true
238 */
239 nonvirtual bool ContainsAny (const Iterable<value_type>& items) const;
240
241 public:
242 /**
243 * Checks if each element of this set is contained in the argument set. This is NOT proper subset, but
244 * allows for equality.
245 */
246 nonvirtual bool IsSubsetOf (const Set& superset) const;
247
248 public:
249 /**
250 * Like Contains - but a Set<> can use a comparison that only examines a part of T,
251 * making it useful to be able to return the rest of T.
252 */
253 nonvirtual optional<value_type> Lookup (ArgByValueType<value_type> item) const;
254
255 public:
256 /**
257 * Add when T is already present has may have no effect (logically has no effect) on the
258 * container (not an error or exception).
259 *
260 * So for a user-defined type T (or any type where the caller specifies the compare function)
261 * it is left undefined whether or not the new (not included) attributes associated with the added
262 * item make it into the Set.
263 *
264 * If you really want an association list (Mapping) from one thing to another, use that.
265 *
266 * If you really want a 'set' where the object has a bunch of extra attributes, but compares 'equal', and you want
267 * to preserve those extra attributes, use KeyedCollection<T>.
268 *
269 * \note mutates container
270 */
271 nonvirtual void Add (ArgByValueType<value_type> item);
272
273 public:
274 /**
275 * Add item if not already present, and return true if added, and false if already present.
276 * Note - we chose to return true in the case of addition because this is the case most likely
277 * when a caller would want to take action.
278 *
279 * \par Example Usage
280 * \code
281 * if (s.AddIf (n)) {
282 * write_to_disk (n);
283 * }
284 * \endcode
285 *
286 * \note mutates container
287 */
288 nonvirtual bool AddIf (ArgByValueType<value_type> item);
289
290 public:
291 /**
292 * @aliases .net AddRange ()
293 *
294 * \note mutates container
295 */
296 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
297 nonvirtual void AddAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end);
298 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
299 nonvirtual void AddAll (ITERABLE_OF_ADDABLE&& items);
300
301 public:
302 /**
303 * \brief Remove the item (given by value or iterator pointing to it) from the contain. The item MUST exist.
304 *
305 * \pre argument (i or item) is present in the Set.
306 *
307 * @see RemoveIf () to remove without the requirement that the value exist in the Set
308 *
309 * \param nextI - if provided (not null) - will be filled in with the next value after where iterator i is pointing - since i is invalidated by changing the container)
310 *
311 * \note mutates container
312 */
313 nonvirtual void Remove (ArgByValueType<value_type> item);
314 nonvirtual void Remove (const Iterator<value_type>& i, Iterator<value_type>* nextI = nullptr);
315
316 public:
317 /**
318 * RemoveIf item if present. Whether present or not it does the same thing and
319 * assures the item is no longer present, but returns true iff the call made a change (removed
320 * the item).
321 *
322 * Note - we chose to return true in the case of removal because this is the case most likely
323 * when a caller would want to take action.
324 *
325 * \par Example Usage
326 * \code
327 * if (s.RemoveIf (n)) {
328 * write_to_disk(n);
329 * }
330 * \endcode
331 *
332 * @see Remove ()
333 *
334 * \note mutates container
335 */
336 nonvirtual bool RemoveIf (ArgByValueType<value_type> item);
337
338 public:
339 /**
340 * \brief RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items.
341 *
342 * The no-arg overload removes all (quickly).
343 *
344 * The overloads that remove some subset of the items returns the number of items so removed.
345 *
346 * \note mutates container
347 */
348 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
349 nonvirtual size_t RemoveAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end);
350 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
351 nonvirtual size_t RemoveAll (const ITERABLE_OF_ADDABLE& s);
352 nonvirtual void RemoveAll ();
353 template <predicate<T> PREDICATE>
354 nonvirtual size_t RemoveAll (PREDICATE&& p);
355
356 public:
357 /**
358 * \brief 'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Set, and improve that case to clone properties from this rep (such is rep type, ordering, etc).
359 */
360 template <typename RESULT_CONTAINER = Set<T>, invocable<T> ELEMENT_MAPPER>
361 nonvirtual RESULT_CONTAINER Map (ELEMENT_MAPPER&& elementMapper) const
362 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, typename RESULT_CONTAINER::value_type> or
363 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>);
364
365 public:
366 /**
367 * Apply the function function to each element, and return all the ones for which it was true.
368 *
369 * \note Alias - this could have been called 'Subset' - as it constructs a subset.
370 *
371 * \note if the RESULT_CONTAINER (as is default) inherits from Set<T>, the ordering relation is maintained in the resulting container
372 *
373 * @see Iterable<T>::Where
374 *
375 * \par Example Usage
376 * \code
377 * Set<int> s{ 1, 2, 3, 4, 5 };
378 * EXPECT_TRUE ((s.Where ([](int i) {return Math::IsPrime (i); }) == Set<int>{ 2, 3, 5 }));
379 * \endcode
380 */
381 template <derived_from<Iterable<T>> RESULT_CONTAINER = Set<T>, predicate<T> INCLUDE_PREDICATE>
382 nonvirtual RESULT_CONTAINER Where (INCLUDE_PREDICATE&& includeIfTrue) const;
383
384 public:
385 struct EqualsComparer;
386
387 public:
388 /**
389 * simply indirect to @Set<>::EqualsComparer (always defined because Set<> knows how to compare T items.
390 *
391 * \par Example Usage
392 * \code
393 * EXPECT_EQ (Set<int>{1,2,3}, Set<int>{3,2,1}); // order doesn't matter for set equality
394 * \endcode
395 */
396 nonvirtual bool operator== (const Set& rhs) const;
397 nonvirtual bool operator== (const Iterable<value_type>& rhs) const;
398
399 public:
400 /**
401 * \brief return true iff the Intersection () is non-empty
402 *
403 * Returns true iff the two specified containers contain at least one element in common.
404 */
405 nonvirtual bool Intersects (const Iterable<value_type>& rhs) const;
406 static bool Intersects (const Set& lhs, const Iterable<value_type>& rhs);
407 static bool Intersects (const Iterable<value_type>& lhs, const Set& rhs);
408 static bool Intersects (const Set& lhs, const Set& rhs);
409
410 public:
411 /**
412 */
413 nonvirtual Set Intersection (const Iterable<value_type>& rhs) const;
414 static Set Intersection (const Set& lhs, const Iterable<value_type>& rhs);
415 static Set Intersection (const Iterable<T>& lhs, const Set& rhs);
416 static Set Intersection (const Set& lhs, const Set& rhs);
417
418 public:
419 /**
420 */
421 nonvirtual Set Union (const Iterable<value_type>& rhs) const;
422 nonvirtual Set Union (ArgByValueType<value_type> rhs) const;
423 static Set Union (const Set& lhs, const Iterable<value_type>& rhs);
424 static Set Union (const Iterable<value_type>& lhs, const Set& rhs);
425 static Set Union (const Set& lhs, const Set& rhs);
426
427 public:
428 /**
429 */
430 nonvirtual Set Difference (const Set& rhs) const;
431 nonvirtual Set Difference (const Iterable<value_type>& rhs) const;
432 nonvirtual Set Difference (ArgByValueType<value_type> rhs) const;
433
434 public:
435 /**
436 * Synonym for Add/AddAll.
437 *
438 * Design note use AddAll/RemoveAll() for CONTAINER variant - since can easily lead to ambiguity/confusion
439 *
440 * \note mutates container
441 */
442 nonvirtual Set& operator+= (ArgByValueType<value_type> item);
443 nonvirtual Set& operator+= (const Iterable<value_type>& items);
444
445 public:
446 /**
447 * Synonym for RemoveIf/RemoveAll.
448 *
449 * Design note use AddAll/RemoveAll() for CONTAINER variant - since can easily lead to ambiguity/confusion
450 *
451 * \note mutates container
452 */
453 nonvirtual Set& operator-= (ArgByValueType<value_type> item);
454 nonvirtual Set& operator-= (const Iterable<value_type>& items);
455
456 public:
457 /**
458 * Synonym for *this = *this ^ Set<T> {items }
459 *
460 * \note mutates container
461 */
462 nonvirtual Set& operator^= (const Iterable<value_type>& items);
463
464 public:
465 /**
466 * @aliases RemoveAll ().
467 *
468 * \note mutates container
469 */
470 nonvirtual void clear ();
471
472 public:
473 /**
474 * Note the return value of this find function is an Iterator, when it could have been as easily an optional<T>. Reason
475 * to return an iterator is so that it can be fed back into a Remove (iterator) call which allows more efficient removeal.
476 */
477 nonvirtual Iterator<value_type> find (ArgByValueType<value_type> item) const;
478
479 public:
480 /**
481 * @aliases Add ().
482 *
483 * \see https://en.cppreference.com/w/cpp/container/set/insert
484 *
485 * \note mutates container
486 *
487 * \note because of different way iterators handled in Stroika containers, this is more costly than Add () or AddIf, but provided to facilitate
488 * converting code that was written for the STL API.
489 */
490 nonvirtual pair<const_iterator, bool> insert (ArgByValueType<value_type> item);
491 nonvirtual pair<const_iterator, bool> insert (const_iterator ignored, ArgByValueType<value_type> item);
492 template <class InputIt>
493 nonvirtual void insert (InputIt first, InputIt last);
494 nonvirtual void insert (initializer_list<T> ilist);
495
496 public:
497 /**
498 * \brief STL-ish alias for Remove ().
499 *
500 * \note mutates container
501 */
502 nonvirtual void erase (ArgByValueType<value_type> item);
503 nonvirtual Iterator<value_type> erase (const Iterator<value_type>& i);
504
505 public:
506 /**
507 * \brief for return Set<T> { s->GetEqualsComparer(); } - except more efficient - clones settings/dynamic subtype but not data for the Set
508 */
509 nonvirtual Set CloneEmpty () const;
510
511 protected:
512 /**
513 * \brief Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ())
514 * but where we also handle the cloning/patching of the associated iterator
515 *
516 * When you have a non-const operation (such as Remove) with an argument of an Iterator<>, then due to COW,
517 * you may end up cloning the container rep, and yet the Iterator<> contains a pointer to the earlier rep (and so maybe unusable).
518 *
519 * Prior to Stroika 2.1b14, this was handled elegantly, and automatically, by the iterator patching mechanism. But that was deprecated (due to cost, and
520 * rarity of use), in favor of this more restricted feature, where we just patch the iterators on an as-needed basis.
521 *
522 * \todo @todo - could be smarter about moves and avoid some copies here - I think, and this maybe performance sensitive enough to look into that... (esp for COMMON case where no COW needed)
523 */
524 nonvirtual tuple<_IRep*, Iterator<value_type>> _GetWritableRepAndPatchAssociatedIterator (const Iterator<value_type>& i);
525
526 protected:
527 /**
528 */
529 template <typename T2>
530 using _SafeReadRepAccessor = typename inherited::template _SafeReadRepAccessor<T2>;
531
532 protected:
533 /**
534 */
535 template <typename T2>
536 using _SafeReadWriteRepAccessor = typename inherited::template _SafeReadWriteRepAccessor<T2>;
537
538 protected:
539 nonvirtual void _AssertRepValidType () const;
540 };
541
542 /**
543 * \brief Implementation detail for Set<T> implementors.
544 *
545 * Protected abstract interface to support concrete implementations of
546 * the Set<T> container API.
547 */
548 template <typename T>
549 class Set<T>::_IRep : public Iterable<T>::_IRep {
550 private:
551 using inherited = typename Iterable<T>::_IRep;
552
553 protected:
554 _IRep () = default;
555
556 public:
557 virtual ~_IRep () = default;
558
559 public:
560 virtual ElementEqualityComparerType GetElementEqualsComparer () const = 0;
561 virtual shared_ptr<_IRep> CloneEmpty () const = 0;
562 virtual shared_ptr<_IRep> CloneAndPatchIterator (Iterator<value_type>* i) const = 0;
563 virtual bool Equals (const typename Iterable<value_type>::_IRep& rhs) const = 0;
564 /**
565 * Return true iff item found.
566 * ONLY IF returns true, and arg oResult is non-null, *oResult set to found item.
567 * ONLY IF returns true, and arg iResult is non-null, *iResult set to found item.
568 */
569 virtual bool Lookup (ArgByValueType<value_type> item, optional<value_type>* oResult, Iterator<value_type>* iResult) const = 0;
570 virtual void Add (ArgByValueType<value_type> item) = 0;
571 /**
572 * Return true iff item found. Either way assure it doesn't exist
573 */
574 virtual bool RemoveIf (ArgByValueType<value_type> item) = 0;
575 virtual void Remove (const Iterator<value_type>& i, Iterator<value_type>* nextI) = 0;
576
577 /*
578 * Reference Implementations (often not used except for ensures, but can be used for
579 * quickie backends).
580 *
581 * Importantly, these are all non-virtual so not actually pulled in or even compiled unless
582 * the subclass refers to the method in a subclass virtual override.
583 */
584 protected:
585 /**
586 * \note - this doesn't require a Compare function argument because it indirects to 'Contains'
587 */
588 nonvirtual bool _Equals_Reference_Implementation (const typename Iterable<value_type>::_IRep& rhs) const;
589 };
590
591 /**
592 * \brief Compare Set<>s or Iterable<>s for equality.
593 *
594 * Two Sets are considered equal if they contain the same elements (by comparing them with EqualsCompareFunctionType (defaults to operator==)).
595 * Note, if two equalsComparer functions are provided, they must produce the same result comparing elements.
596 *
597 * \pre lhs and rhs arguments must have the same (or equivalent) EqualsComparers.
598 *
599 * EqualsComparer is commutative ().
600 *
601 * @todo - document computational complexity
602 *
603 * \note This EqualsComparer template is defined even though not needed to provide alternate element comparer to provide extra overloads for
604 * operator()()
605 *
606 * \note If any argument is an Iterable, it is treated/compared as if it was a set (aka Iterable<T>::SetEquals)
607 *
608 * \note Not to be confused with ElementEqualityComparerType and GetElementEqualsComparer () which compares ELEMENTS of Set<T> for equality.
609 */
610 template <typename T>
611 struct Set<T>::EqualsComparer : Common::ComparisonRelationDeclarationBase<Common::ComparisonRelationType::eEquals> {
612 nonvirtual bool operator() (const Set& lhs, const Set& rhs) const;
613 nonvirtual bool operator() (const Set& lhs, const Iterable<value_type>& rhs) const;
614 nonvirtual bool operator() (const Iterable<value_type>& lhs, const Set& rhs) const;
615 };
616
617 /**
618 * @aliases Set<>::Union
619 */
620 template <typename T>
621 Set<T> operator+ (const Set<T>& lhs, const Iterable<T>& rhs);
622 template <typename T>
623 Set<T> operator+ (const Set<T>& lhs, const T& rhs);
624
625 /**
626 * @aliases Set<>::Difference.
627 */
628 template <typename T>
629 Set<T> operator- (const Set<T>& lhs, const Iterable<T>& rhs);
630
631 /**
632 * @aliases Set<>::Intersection.
633 */
634 template <typename T>
635 Set<T> operator^ (const Set<T>& lhs, const Iterable<T>& rhs);
636 template <typename T>
637 Set<T> operator^ (const Iterable<T>& lhs, const Set<T>& rhs);
638 template <typename T>
639 Set<T> operator^ (const Set<T>& lhs, const Set<T>& rhs);
640
641}
642
643/*
644 ********************************************************************************
645 ******************************* Implementation Details *************************
646 ********************************************************************************
647 */
648#include "Set.inl"
649
650#endif /*_Stroika_Foundation_Containers_Set_h_ */
Implementation detail for Set<T> implementors.
Definition Set.h:549
virtual bool RemoveIf(ArgByValueType< value_type > item)=0
virtual bool Lookup(ArgByValueType< value_type > item, optional< value_type > *oResult, Iterator< value_type > *iResult) const =0
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
typename inherited::const_iterator const_iterator
Definition Set.h:128
typename inherited::value_type value_type
Definition Set.h:122
Implementation detail for iterator implementors.
Definition Iterable.h:1569
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
T value_type
value_type is an alias for the type iterated over - like vector<T>::value_type
Definition Iterable.h:248
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32
Compare Set<>s or Iterable<>s for equality.
Definition Set.h:611