16 template <
typename T,
typename TRAITS>
17 bool MultiSet<T, TRAITS>::_IRep::_Equals_Reference_Implementation (
const _IRep& rhs)
const
22 if (this->size () != rhs.size ()) {
25 for (
auto i = this->MakeIterator (); not i.Done (); ++i) {
26 if (i->fCount != rhs.OccurrencesOf (i->fValue)) {
38 template <
typename T,
typename TRAITS>
40 requires (IEqualsComparer<equal_to<T>, T>)
43 _AssertRepValidType ();
45 template <
typename T,
typename TRAITS>
46 template <IEqualsComparer<T> EQUALS_COMPARER>
47 inline MultiSet<T, TRAITS>::MultiSet (EQUALS_COMPARER&& equalsComparer)
48 : inherited{Factory::MultiSet_Factory<T, TRAITS, remove_cvref_t<EQUALS_COMPARER>>::Default () (forward<EQUALS_COMPARER> (equalsComparer))}
50 _AssertRepValidType ();
52#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
53 template <
typename T,
typename TRAITS>
54 template <IIterableOfTo<
typename TRAITS::CountedValueType> ITERABLE_OF_ADDABLE>
56 requires (IEqualsComparer<equal_to<T>, T> and not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, MultiSet<T, TRAITS>>)
59 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
60 _AssertRepValidType ();
63 template <
typename T,
typename TRAITS>
64 template <IEqualsComparer<T> EQUALS_COMPARER, IIterableOfTo<
typename TRAITS::CountedValueType> ITERABLE_OF_ADDABLE>
66 : MultiSet{forward<EQUALS_COMPARER> (equalsComparer)}
68 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
69 _AssertRepValidType ();
71 template <
typename T,
typename TRAITS>
75 _AssertRepValidType ();
77 template <
typename T,
typename TRAITS>
81 _AssertRepValidType ();
83 template <
typename T,
typename TRAITS>
85 requires (IEqualsComparer<equal_to<T>, T>)
89 _AssertRepValidType ();
91 template <
typename T,
typename TRAITS>
92 template <IEqualsComparer<T> EQUALS_COMPARER>
94 : MultiSet{forward<EQUALS_COMPARER> (equalsComparer)}
97 _AssertRepValidType ();
99 template <
typename T,
typename TRAITS>
104 _AssertRepValidType ();
106 template <
typename T,
typename TRAITS>
107 template <IEqualsComparer<T> EQUALS_COMPARER>
109 : MultiSet{forward<EQUALS_COMPARER> (equalsComparer)}
112 _AssertRepValidType ();
114 template <
typename T,
typename TRAITS>
115 template <IInputIterator<
typename TRAITS::CountedValueType> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
117 requires (IEqualsComparer<equal_to<T>, T>)
120 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
121 _AssertRepValidType ();
123 template <
typename T,
typename TRAITS>
124 template <IEqualsComparer<T> EQUALS_COMPARER, IInputIterator<
typename TRAITS::CountedValueType> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
126 : MultiSet{forward<EQUALS_COMPARER> (equalsComparer)}
128 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (
end));
129 _AssertRepValidType ();
131 template <
typename T,
typename TRAITS>
140 template <
typename T,
typename TRAITS>
144 this->Remove (i, &result);
147 template <
typename T,
typename TRAITS>
152 template <
typename T,
typename TRAITS>
160 size_t fIthAdvanceOfIterator{0};
161 size_t fIthOfCurrentIterator{0};
162 Context_ (
const Context_& rhs)
163 : fOriginalMultiset{rhs.fOriginalMultiset}
164 , fCurrentIteratorOverOrig{fOriginalMultiset.
MakeIterator ()}
165 , fIthAdvanceOfIterator{rhs.fIthAdvanceOfIterator}
166 , fIthOfCurrentIterator{rhs.fIthOfCurrentIterator}
168 std::advance (fCurrentIteratorOverOrig, fIthAdvanceOfIterator);
171 : fOriginalMultiset{ms}
172 , fCurrentIteratorOverOrig{fOriginalMultiset.
MakeIterator ()}
175 Context_& operator= (Context_&) =
delete;
177 function<optional<T> ()> getNext = [context = Context_{*
this}] ()
mutable -> optional<T> {
179 if (context.fCurrentIteratorOverOrig) {
180 if (context.fIthOfCurrentIterator < context.fCurrentIteratorOverOrig->fCount) {
181 ++context.fIthOfCurrentIterator;
182 return context.fCurrentIteratorOverOrig->fValue;
185 ++context.fCurrentIteratorOverOrig;
186 ++context.fIthAdvanceOfIterator;
187 context.fIthOfCurrentIterator = 0;
193 return Traversal::CreateGenerator (getNext);
195 template <
typename T,
typename TRAITS>
198 return this->
template Map<Iterable<T>> ([] (
const typename TRAITS::CountedValueType& cv) {
return cv.fValue; });
200 template <
typename T,
typename TRAITS>
203 return this->inherited::Top ([] (
const typename TRAITS::CountedValueType& lhs,
const typename TRAITS::CountedValueType& rhs) {
204 return lhs.fCount > rhs.fCount;
207 template <
typename T,
typename TRAITS>
210 return this->inherited::Top (n, [] (
const typename TRAITS::CountedValueType& lhs,
const typename TRAITS::CountedValueType& rhs) {
211 return lhs.fCount > rhs.fCount;
214 template <
typename T,
typename TRAITS>
217 return Top ().template Map<Iterable<T>> ([] (
const typename TRAITS::CountedValueType& cv) {
return cv.fValue; });
219 template <
typename T,
typename TRAITS>
222 return Top (n).template Map<Iterable<T>> ([] (
const typename TRAITS::CountedValueType& cv) {
return cv.fValue; });
224 template <
typename T,
typename TRAITS>
227 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetElementEqualsComparer ();
229 template <
typename T,
typename TRAITS>
232 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Contains (item);
234 template <
typename T,
typename TRAITS>
237 _SafeReadRepAccessor<_IRep> tmp{
this};
238 if (not tmp._ConstGetRep ().empty ()) {
239 this->_fRep = tmp._ConstGetRep ().CloneEmpty ();
242 template <
typename T,
typename TRAITS>
245 return RemoveIf (item, OccurrencesOf (item));
247 template <
typename T,
typename TRAITS>
250 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (item, 1);
252 template <
typename T,
typename TRAITS>
255 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (item, count);
257 template <
typename T,
typename TRAITS>
260 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (item.fValue, item.fCount);
262 template <
typename T,
typename TRAITS>
263 template <IInputIterator<
typename TRAITS::CountedValueType> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
266 for (ITERATOR_OF_ADDABLE i = forward<ITERATOR_OF_ADDABLE> (start); i != forward<ITERATOR_OF_ADDABLE2> (end); ++i) {
270 template <
typename T,
typename TRAITS>
271 template <IIterableOfTo<
typename TRAITS::CountedValueType> ITERABLE_OF_ADDABLE>
275 if constexpr (std::is_convertible_v<remove_cvref_t<ITERABLE_OF_ADDABLE>*,
const MultiSet<T, TRAITS>*>) {
276 if (
static_cast<const Iterable<value_type>*
> (
this) ==
static_cast<const Iterable<value_type>*
> (&items)) [[unlikely]] {
278 using VEC_ELT_T =
typename remove_cvref_t<ITERABLE_OF_ADDABLE>::value_type;
279 using ELTS_IT_T =
decltype (items.begin ());
280 vector<VEC_ELT_T> copy{std::begin (items), ELTS_IT_T{std::end (items)}};
281 for (
const auto& i : copy) {
287 for (
const auto& i : items) {
291 template <
typename T,
typename TRAITS>
294 Verify (_SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveIf (item, count) == count);
296 template <
typename T,
typename TRAITS>
299 Require (not i.
Done ());
300 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
301 writerRep->Remove (patchedIterator, nextI);
303 template <
typename T,
typename TRAITS>
306 return _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveIf (item, count);
308 template <
typename T,
typename TRAITS>
311 Require (not i.
Done ());
312 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
313 writerRep->UpdateCount (patchedIterator, newCount, nextI);
315 template <
typename T,
typename TRAITS>
318 CounterType cnt = OccurrencesOf (i);
319 if (newCount > cnt) {
320 Add (i, newCount - cnt);
322 else if (newCount < cnt) {
323 Remove (i, cnt - newCount);
326 template <
typename T,
typename TRAITS>
329 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().OccurrencesOf (item);
331 template <
typename T,
typename TRAITS>
332 template <
typename RESULT_CONTAINER, invocable<T> ELEMENT_MAPPER>
334 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, typename TRAITS::CountedValueType>,
typename RESULT_CONTAINER::value_type> or
335 convertible_to<invoke_result_t<ELEMENT_MAPPER, typename TRAITS::CountedValueType>, optional<typename RESULT_CONTAINER::value_type>>)
337 if constexpr (same_as<RESULT_CONTAINER, MultiSet>) {
339 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper),
340 RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
343 return inherited::template Map<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper));
346 template <
typename T,
typename TRAITS>
347 template <derived_from<Iterable<
typename TRAITS::CountedValueType>> RESULT_CONTAINER, predicate<
typename TRAITS::CountedValueType> INCLUDE_PREDICATE>
350 if constexpr (same_as<RESULT_CONTAINER, MultiSet>) {
352 return inherited::template Where<RESULT_CONTAINER> (
353 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
356 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue));
359 template <
typename T,
typename TRAITS>
362 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().
Add (item, 1);
365 template <
typename T,
typename TRAITS>
371 template <
typename T,
typename TRAITS>
374 Require (not i.Done ());
375 using element_type =
typename inherited::_SharedByValueRepType::element_type;
377 element_type* writableRep = this->_fRep.rwget ([&] (
const element_type& prevRepPtr) ->
typename inherited::_SharedByValueRepType::shared_ptr_type {
378 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
381 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
383 template <
typename T,
typename TRAITS>
387 _SafeReadRepAccessor<_IRep>{
this};
390 template <
typename T,
typename TRAITS>
393 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Equals (_SafeReadRepAccessor<_IRep>{&rhs}._ConstGetRep ());
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireExpression(c)
nonvirtual MultiSet & operator+=(ArgByValueType< T > item)
nonvirtual void AddAll(ITERATOR_OF_ADDABLE &&start, ITERATOR_OF_ADDABLE2 &&end)
nonvirtual CounterType TotalOccurrences() const
nonvirtual Iterator< value_type > erase(const Iterator< value_type > &i)
nonvirtual void Remove(ArgByValueType< T > item, CounterType count=1)
remove the argument data from the multiset. The data specified MUST exist (require) - else use Remove...
nonvirtual Iterable< T > Elements() const
nonvirtual void UpdateCount(const Iterator< value_type > &i, CounterType newCount, Iterator< value_type > *nextI=nullptr)
nonvirtual void Add(ArgByValueType< T > item)
nonvirtual Iterable< T > TopElements() const
Find the most commonly occurring elements of the multiset (list of elements - without count - ordered...
nonvirtual ElementEqualityComparerType GetElementEqualsComparer() const
typename inherited::value_type value_type
nonvirtual bool operator==(const MultiSet &rhs) const
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to MultiSet, and improve that cas...
nonvirtual Iterable< typename TRAITS::CountedValueType > Top() const
Find the most commonly occurring elements of the multiset (list with count ordered most to last)
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 RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
nonvirtual bool Contains(ArgByValueType< T > item) const
nonvirtual void RemoveAll()
RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items...
nonvirtual CounterType OccurrencesOf(ArgByValueType< T > item) const
nonvirtual size_t RemoveIf(ArgByValueType< T > item, CounterType count=1)
remove the argument data from the multiset (can specify remove of more than are present) - returns nu...
nonvirtual void SetCount(ArgByValueType< T > i, CounterType newCount)
nonvirtual Iterable< T > UniqueElements() const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.
nonvirtual Iterator< T > MakeIterator() const
Create an iterator object which can be used to traverse the 'Iterable'.
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....