6#include "Stroika/Foundation/Common/Concepts.h"
19 requires (IEqualsComparer<equal_to<T>, T>)
22 _AssertRepValidType ();
25 template <IEqualsComparer<T> EQUALS_COMPARER>
26 inline Set<T>::Set (EQUALS_COMPARER&& equalsComparer)
27 : inherited{Factory::Set_Factory<T, remove_cvref_t<EQUALS_COMPARER>>::Default () (forward<EQUALS_COMPARER> (equalsComparer))}
29 _AssertRepValidType ();
32 inline Set<T>::Set (
const initializer_list<value_type>& src)
33 requires (IEqualsComparer<equal_to<T>, T>)
37 _AssertRepValidType ();
40 template <IEqualsComparer<T> EQUALS_COMPARER>
41 inline Set<T>::Set (EQUALS_COMPARER&& equalsComparer,
const initializer_list<value_type>& src)
42 : Set{forward<EQUALS_COMPARER> (equalsComparer)}
45 _AssertRepValidType ();
47#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
49 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
50 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, Set<T>>)
54 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
55 _AssertRepValidType ();
59 template <IEqualsComparer<T> EQUALS_COMPARER, IIterableOfTo<T> ITERABLE_OF_ADDABLE>
60 inline Set<T>::Set (EQUALS_COMPARER&& equalsComparer, ITERABLE_OF_ADDABLE&& src)
61 : Set{forward<EQUALS_COMPARER> (equalsComparer)}
63 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
64 _AssertRepValidType ();
67 inline Set<T>::Set (
const shared_ptr<_IRep>& src) noexcept
70 _AssertRepValidType ();
73 inline Set<T>::Set (shared_ptr<_IRep>&& src) noexcept
76 _AssertRepValidType ();
79 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
80 inline Set<T>::Set (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
81 requires (IEqualsComparer<equal_to<T>, T>)
84 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
85 _AssertRepValidType ();
88 template <IEqualsComparer<T> EQUALS_COMPARER, IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
89 inline Set<T>::Set (EQUALS_COMPARER&& equalsComparer, ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
90 : Set{forward<EQUALS_COMPARER> (equalsComparer)}
92 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (
end));
93 _AssertRepValidType ();
98 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetElementEqualsComparer ();
100 template <
typename T>
103 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().
Lookup (item,
nullptr,
nullptr);
105 template <
typename T>
108 return Contains (item);
110 template <
typename T>
113 return items.
All ([&] (ArgByValueType<T> i) {
return this->Contains (i); });
115 template <
typename T>
118 return items.
Any ([&] (ArgByValueType<T> i) {
return this->Contains (i); });
120 template <
typename T>
123 for (
const auto& i : *
this) {
124 if (not superset.Contains (i)) {
130 template <
typename T>
131 inline auto Set<T>::Lookup (ArgByValueType<value_type> item)
const -> optional<value_type>
133 optional<value_type> r;
134 _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (item, &r,
nullptr);
137 template <
typename T>
140 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (item);
142 template <
typename T>
150 if (Contains (item)) {
158 template <
typename T>
159 template <IInputIterator<T> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
160 void Set<T>::AddAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
162 _SafeReadWriteRepAccessor<_IRep> tmp{
this};
163 for (
auto i = forward<ITERATOR_OF_ADDABLE> (start); i != forward<ITERATOR_OF_ADDABLE2> (end); ++i) {
164 tmp._GetWriteableRep ().Add (*i);
167 template <
typename T>
168 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
175 AddAll (std::begin (copy), std::end (copy));
179 AddAll (std::begin (items), std::end (items));
181 template <
typename T>
184 Verify (_SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveIf (item));
186 template <
typename T>
189 Require (not i.
Done ());
190 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
191 writerRep->Remove (patchedIterator, nextI);
193 template <
typename T>
196 return _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveIf (item);
198 template <
typename T>
199 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
200 inline size_t Set<T>::RemoveAll (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end)
203 for (
auto i = forward<ITERATOR_OF_ADDABLE> (start); i != end; ++i) {
209 template <
typename T>
210 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
211 inline size_t Set<T>::RemoveAll (
const ITERABLE_OF_ADDABLE& s)
213 return RemoveAll (std::begin (s), std::end (s));
215 template <
typename T>
218 _SafeReadRepAccessor<_IRep> tmp{
this};
219 if (not tmp._ConstGetRep ().empty ()) {
220 this->_fRep = tmp._ConstGetRep ().
CloneEmpty ();
223 template <
typename T>
224 template <predicate<T> PREDICATE>
228 for (
Iterator<T> i = this->begin (); i != this->end ();) {
239 template <
typename T>
240 template <
typename RESULT_CONTAINER, invocable<T> ELEMENT_MAPPER>
241 inline RESULT_CONTAINER
Set<T>::Map (ELEMENT_MAPPER&& elementMapper)
const
242 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>,
typename RESULT_CONTAINER::value_type> or
243 convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>)
245 if constexpr (same_as<RESULT_CONTAINER, Set>) {
247 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper),
248 RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
251 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper));
254 template <
typename T>
255 template <derived_from<Iterable<T>> RESULT_CONTAINER, predicate<T> INCLUDE_PREDICATE>
256 inline RESULT_CONTAINER
Set<T>::Where (INCLUDE_PREDICATE&& includeIfTrue)
const
258 if constexpr (same_as<RESULT_CONTAINER, Set>) {
260 return inherited::template Where<RESULT_CONTAINER> (
261 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
264 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue));
267 template <
typename T>
270 for (
const auto& i : rhs) {
277 template <
typename T>
280 return lhs.Intersects (rhs);
282 template <
typename T>
285 return rhs.Intersects (lhs);
287 template <
typename T>
299 template <
typename T>
303 Set result{this->CloneEmpty ()};
307 for (
const auto& i : rhs) {
314 template <
typename T>
317 return lhs.Intersection (rhs);
319 template <
typename T>
320 inline Set<T> Set<T>::Intersection (
const Iterable<T>& lhs,
const Set& rhs)
322 return rhs.Intersection (lhs);
324 template <
typename T>
325 inline Set<T> Set<T>::Intersection (
const Set& lhs,
const Set& rhs)
330 if (lhs.size () < rhs.size ()) {
331 return rhs.Intersection (
static_cast<const Iterable<T>&
> (lhs));
334 return lhs.Intersection (
static_cast<const Iterable<T>&
> (rhs));
337 template <
typename T>
344 template <
typename T>
351 template <
typename T>
352 inline Set<T> Set<T>::Union (
const Set& lhs,
const Iterable<value_type>& rhs)
354 return lhs.Union (rhs);
356 template <
typename T>
357 inline Set<T> Set<T>::Union (
const Iterable<value_type>& lhs,
const Set& rhs)
360 return rhs.Union (lhs);
362 template <
typename T>
363 inline Set<T> Set<T>::Union (
const Set& lhs,
const Set& rhs)
368 if (lhs.size () < rhs.size ()) {
369 return rhs.Union (
static_cast<const Iterable<T>&
> (lhs));
372 return lhs.Union (
static_cast<const Iterable<T>&
> (rhs));
375 template <
typename T>
376 Set<T> Set<T>::Difference (
const Set& rhs)
const
379 Set result{this->CloneEmpty ()};
386 for (
const auto& i : *this) {
387 if (not rhs.Contains (i)) {
393 template <
typename T>
394 Set<T> Set<T>::Difference (
const Iterable<value_type>& rhs)
const
410 for (
const auto& i : rhs) {
415 template <
typename T>
422 Set<T> result = *
this;
426 template <
typename T>
432 template <
typename T>
438 template <
typename T>
444 template <
typename T>
450 template <
typename T>
453 *
this = Intersection (items);
456 template <
typename T>
461 template <
typename T>
465 _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (item,
nullptr, &r);
468 template <
typename T>
471 auto i = AddIf (item);
472 return make_pair (this->find (item), i);
474 template <
typename T>
477 return this->insert (item);
479 template <
typename T>
480 template <
class InputIt>
483 AddAll (first, last);
485 template <
typename T>
490 template <
typename T>
495 template <
typename T>
499 this->Remove (i, &nextI);
502 template <
typename T>
505 return Set{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().
CloneEmpty ()};
507 template <
typename T>
510 Require (not i.
Done ());
511 using element_type =
typename inherited::_SharedByValueRepType::element_type;
513 element_type* writableRep = this->_fRep.rwget ([&] (
const element_type& prevRepPtr) ->
typename inherited::_SharedByValueRepType::shared_ptr_type {
514 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
517 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
519 template <
typename T>
523 [[maybe_unused]] _SafeReadRepAccessor<_IRep> ignored{
this};
526 template <
typename T>
531 template <
typename T>
534 return EqualsComparer{}(*
this, rhs);
542 template <
typename T>
547 constexpr bool kCanUseGetLengthAsOptimizationCheck_ =
false;
551 if (kCanUseGetLengthAsOptimizationCheck_) {
557 [[maybe_unused]]
size_t rhsSize{};
559 if (not
Lookup (*i,
nullptr,
nullptr)) {
564 if (not kCanUseGetLengthAsOptimizationCheck_) {
565 return rhsSize == this->
size ();
575 template <
typename T>
578 bool result = _SafeReadRepAccessor<_IRep>{&lhs}._ConstGetRep ().Equals (_SafeReadRepAccessor<_IRep>{&rhs}._ConstGetRep ());
579 Ensure (result == _SafeReadRepAccessor<_IRep>{&rhs}._ConstGetRep ().Equals (_SafeReadRepAccessor<_IRep>{&lhs}._ConstGetRep ()));
582 template <
typename T>
583 inline bool Set<T>::EqualsComparer::operator() (
const Set& lhs,
const Iterable<value_type>& rhs)
const
585 return _SafeReadRepAccessor<_IRep>{&lhs}._ConstGetRep ().Equals (_SafeReadRepAccessor<
typename Iterable<T>::_IRep>{&rhs}._ConstGetRep ());
587 template <
typename T>
590 return _SafeReadRepAccessor<_IRep>{&rhs}._ConstGetRep ().Equals (_SafeReadRepAccessor<
typename Iterable<T>::_IRep>{&lhs}._ConstGetRep ());
598 template <
typename T>
601 return lhs.Union (rhs);
603 template <
typename T>
604 inline Set<T>
operator+ (
const Set<T>& lhs,
const T& rhs)
606 return lhs.Union (rhs);
608 template <
typename T>
611 return lhs.Difference (rhs);
613 template <
typename T>
614 inline Set<T>
operator- (
const Set<T>& lhs,
const T& rhs)
616 return lhs.Difference (rhs);
618 template <
typename T>
621 return lhs.Intersection (rhs);
623 template <
typename T>
624 inline Set<T>
operator^ (
const Iterable<T>& lhs,
const Set<T>& rhs)
626 return rhs.Intersection (lhs);
628 template <
typename T>
629 inline Set<T>
operator^ (
const Set<T>& lhs,
const Set<T>& rhs)
631 return lhs.Intersection (rhs);
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireExpression(c)
nonvirtual bool _Equals_Reference_Implementation(const typename Iterable< value_type >::_IRep &rhs) const
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.
nonvirtual Set & operator^=(const Iterable< value_type > &items)
nonvirtual bool contains(ArgByValueType< value_type > item) const
nonvirtual bool ContainsAny(const Iterable< value_type > &items) const
nonvirtual Iterator< value_type > find(ArgByValueType< value_type > item) const
nonvirtual optional< value_type > Lookup(ArgByValueType< value_type > item) const
nonvirtual ElementEqualityComparerType GetElementEqualsComparer() const
nonvirtual bool AddIf(ArgByValueType< value_type > item)
nonvirtual bool Intersects(const Iterable< value_type > &rhs) const
return true iff the Intersection () is non-empty
nonvirtual bool IsSubsetOf(const Set &superset) const
nonvirtual Set CloneEmpty() const
for return Set<T> { s->GetEqualsComparer(); } - except more efficient - clones settings/dynamic subty...
nonvirtual void Remove(ArgByValueType< value_type > item)
Remove the item (given by value or iterator pointing to it) from the contain. The item MUST exist.
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Set, and improve that case to ...
nonvirtual RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
nonvirtual Set & operator+=(ArgByValueType< value_type > item)
nonvirtual bool operator==(const Set &rhs) const
nonvirtual bool ContainsAll(const Iterable< value_type > &items) const
nonvirtual bool RemoveIf(ArgByValueType< value_type > item)
typename inherited::value_type value_type
nonvirtual void erase(ArgByValueType< value_type > item)
STL-ish alias for Remove ().
nonvirtual Set & operator-=(ArgByValueType< value_type > item)
nonvirtual pair< const_iterator, bool > insert(ArgByValueType< value_type > item)
nonvirtual void Add(ArgByValueType< value_type > item)
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 void AddAll(ITERATOR_OF_ADDABLE &&start, ITERATOR_OF_ADDABLE2 &&end)
Implementation detail for iterator implementors.
virtual Iterator< value_type > MakeIterator() const =0
virtual size_t size() const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
nonvirtual bool Any() const
Any() same as not empty (); Any (includeIfTrue) returns true iff includeIfTrue returns true on any va...
nonvirtual bool All(const function< bool(ArgByValueType< T >)> &testEachElt) const
return true iff argument predicate returns true for each element of the iterable
nonvirtual size_t size() const
Returns the number of items contained.
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....
nonvirtual bool Done() const
Done () means there is nothing left in this iterator (a synonym for (it == container....
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.
Set< T > operator^(const Set< T > &lhs, const Iterable< T > &rhs)
Collection< T > operator+(const Iterable< T > &lhs, const Collection< T > &rhs)
Set< T > operator-(const Set< T > &lhs, const Iterable< T > &rhs)
Compare Set<>s or Iterable<>s for equality.