numerical_multiset/
lib.rs

1//! This crate implements an ordered multiset of machine
2//! numbers.
3//!
4//! Well, that sentence is quite a mouthful. Let's break it down into
5//! more digestible chunks:
6//!
7//! - **Multiset:** The [`NumericalMultiset`] container provided by this crate
8//!   implements a generalization of the mathematical set, the multiset.
9//!   Unlike a set, a multiset can conceptually hold multiple copies of a value.
10//!   This is done by tracking how many occurences of each value are present.
11//! - **Ordered:** Multiset implementations are usually based on associative
12//!   containers, using distinct multiset elements as keys and integer occurence
13//!   counts as values. A popular choice is hash maps, which do not provide any
14//!   meaningful key ordering:
15//!
16//!   - Any key insertion may change the order of keys that is exposed by
17//!     iterators.
18//!   - There is no way to find e.g. the smallest key without iterating over
19//!     all key.
20//!
21//!   In contrast, [`NumericalMultiset`] is based on an ordered associative
22//!   container. This allows it to efficiently answer order-related queries,
23//!   like in-order iteration over elements or extraction of the minimum/maximum
24//!   element. The price to pay is that order-insenstive multiset operations,
25//!   like item insertions and removals, will scale a little less well to
26//!   larger sets of distinct values than in a hash-based implementation.
27//! - **Numbers:** The multiset provided by this crate is not general-purpose,
28//!   but specialized for machine number types (`u32`, `f32`...) and newtypes
29//!   thereof. These types are all `Copy`, which lets us provide a simplified
30//!   value-based API, that may also result in slightly improved runtime
31//!   performance in some scenarios.
32
33use std::{
34    cmp::Ordering,
35    collections::btree_map::{self, BTreeMap, Entry},
36    hash::Hash,
37    iter::FusedIterator,
38    num::NonZeroUsize,
39    ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub},
40};
41
42/// An ordered multiset of machine numbers.
43///
44/// You can learn more about the design rationale and overall capabilities of
45/// this data structure in the [crate-level documentation](index.html).
46///
47/// At the time of writing, this data structure is based on the standard
48/// library's [`BTreeMap`], and many points of the [`BTreeMap`] documentation
49/// also apply to it. In particular, it is a logic error to modify the order of
50/// values stored inside of the multiset using internal mutability tricks.
51///
52/// # Floating-point data
53///
54/// To build multisets of floating-point numbers, you will need to handle the
55/// fact that NaN is unordered. This can be done using one of the [`Ord`] float
56/// wrappers available on crates.io, which work by either [asserting absence of
57/// NaNs](https://docs.rs/ordered-float/latest/ordered_float/struct.NotNan.html)
58/// or [making NaNs
59/// ordered](https://docs.rs/ordered-float/latest/ordered_float/struct.OrderedFloat.html).
60///
61/// For optimal `NumericalMultiset` performance, we advise...
62///
63/// - Preferring
64///   [`NotNan`](https://docs.rs/ordered-float/latest/ordered_float/struct.NotNan.html)-like
65///   wrappers, whose `Ord` implementation can leverage fast hardware
66///   comparisons instead of implementing other ordering semantics in software.
67/// - Using them right from the point where your application receives inputs, to
68///   avoid repeatedly checking your inputs for NaNs by having to rebuild such
69///   wrappers every time a number is inserted into a `NumericalMultiset`.
70///
71/// # Terminology
72///
73/// Because multisets can hold multiple occurences of a value, it is useful to
74/// have concise wording to distinguish between unique values and (possibly
75/// duplicate) occurences of these values.
76///
77/// Throughout this documentation, we will use the following terminology:
78///
79/// - "values" refers to distinct values of type `T` as defined by the [`Eq`]
80///   implementation of `T`.
81/// - "items" refers to possibly duplicate occurences of a value within the
82///   multiset.
83/// - "multiplicity" refers to the number of occurences of a value within the
84///   multiset, i.e. the number of items that are equal to this value.
85///
86/// # Examples
87///
88/// ```
89/// use numerical_multiset::NumericalMultiset;
90/// use std::num::NonZeroUsize;
91///
92/// // Create a multiset
93/// let mut mset = NumericalMultiset::new();
94///
95/// // Inserting items is handled much like a standard library set type,
96/// // except we return an Option<NonZeroUsize> instead of a boolean.
97/// assert!(mset.insert(123).is_none());
98/// assert!(mset.insert(456).is_none());
99///
100/// // This allows us to report the number of pre-existing items
101/// // that have the same value, if any.
102/// assert_eq!(mset.insert(123), NonZeroUsize::new(1));
103///
104/// // It is possible to query the minimal and maximal values cheaply, along
105/// // with their multiplicity within the multiset.
106/// let nonzero = |x| NonZeroUsize::new(x).unwrap();
107/// assert_eq!(mset.first(), Some((123, nonzero(2))));
108/// assert_eq!(mset.last(), Some((456, nonzero(1))));
109///
110/// // ...and it is more generally possible to iterate over values and
111/// // multiplicities in order, from the smallest value to the largest one:
112/// for (elem, multiplicity) in &mset {
113///     println!("{elem} with multiplicity {multiplicity}");
114/// }
115/// ```
116#[derive(Clone, Debug, Default, Eq)]
117pub struct NumericalMultiset<T> {
118    /// Mapping from distinct values to their multiplicities
119    value_to_multiplicity: BTreeMap<T, NonZeroUsize>,
120
121    /// Number of items = sum of all multiplicities
122    len: usize,
123}
124//
125impl<T> NumericalMultiset<T> {
126    /// Makes a new, empty `NumericalMultiset`.
127    ///
128    /// Does not allocate anything on its own.
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use numerical_multiset::NumericalMultiset;
134    ///
135    /// let mset = NumericalMultiset::<i32>::new();
136    /// assert!(mset.is_empty());
137    /// ```
138    #[must_use = "Only effect is to produce a result"]
139    pub fn new() -> Self {
140        Self {
141            value_to_multiplicity: BTreeMap::new(),
142            len: 0,
143        }
144    }
145
146    /// Clears the multiset, removing all items.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// use numerical_multiset::NumericalMultiset;
152    ///
153    /// let mut v = NumericalMultiset::from_iter([1, 2, 3]);
154    /// v.clear();
155    /// assert!(v.is_empty());
156    /// ```
157    pub fn clear(&mut self) {
158        self.value_to_multiplicity.clear();
159        self.len = 0;
160    }
161
162    /// Number of items currently present in the multiset, including
163    /// duplicate occurences of the same value.
164    ///
165    /// See also [`num_values()`](Self::num_values) for a count of distinct
166    /// values, ignoring duplicates.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// use numerical_multiset::NumericalMultiset;
172    ///
173    /// let mut v = NumericalMultiset::new();
174    /// assert_eq!(v.len(), 0);
175    /// v.insert(1);
176    /// assert_eq!(v.len(), 1);
177    /// v.insert(1);
178    /// assert_eq!(v.len(), 2);
179    /// v.insert(2);
180    /// assert_eq!(v.len(), 3);
181    /// ```
182    #[must_use = "Only effect is to produce a result"]
183    pub fn len(&self) -> usize {
184        self.len
185    }
186
187    /// Number of distinct values currently present in the multiset
188    ///
189    /// See also [`len()`](Self::len) for a count of multiset items,
190    /// including duplicate occurences of the same value.
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// use numerical_multiset::NumericalMultiset;
196    ///
197    /// let mut v = NumericalMultiset::new();
198    /// assert_eq!(v.num_values(), 0);
199    /// v.insert(1);
200    /// assert_eq!(v.num_values(), 1);
201    /// v.insert(1);
202    /// assert_eq!(v.num_values(), 1);
203    /// v.insert(2);
204    /// assert_eq!(v.num_values(), 2);
205    /// ```
206    #[must_use = "Only effect is to produce a result"]
207    pub fn num_values(&self) -> usize {
208        self.value_to_multiplicity.len()
209    }
210
211    /// Truth that the multiset contains no items
212    ///
213    /// # Examples
214    ///
215    /// ```
216    /// use numerical_multiset::NumericalMultiset;
217    ///
218    /// let mut v = NumericalMultiset::new();
219    /// assert!(v.is_empty());
220    /// v.insert(1);
221    /// assert!(!v.is_empty());
222    /// ```
223    #[must_use = "Only effect is to produce a result"]
224    pub fn is_empty(&self) -> bool {
225        self.len == 0
226    }
227
228    /// Creates a consuming iterator visiting all distinct values in the
229    /// multiset, i.e. the mathematical support of the multiset.
230    ///
231    /// Values are emitted in ascending order, and the multiset cannot be used
232    /// after calling this method.
233    ///
234    /// Call `into_iter()` (from the [`IntoIterator`] trait) to get a variation
235    /// of this iterator that additionally tells you how many occurences of each
236    /// value were present in the multiset, in the usual `(value, multiplicity)`
237    /// format.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use numerical_multiset::NumericalMultiset;
243    ///
244    /// let mset = NumericalMultiset::from_iter([3, 1, 2, 2]);
245    /// assert!(mset.into_values().eq([1, 2, 3]));
246    /// ```
247    #[must_use = "Only effect is to produce a result"]
248    pub fn into_values(
249        self,
250    ) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator {
251        self.value_to_multiplicity.into_keys()
252    }
253
254    /// Update `self.len` to match `self.value_to_multiplicity`'s contents
255    ///
256    /// This expensive `O(N)` operation should only be performed after calling
257    /// into `BTreeMap` operations that do not provide the right hooks to update
258    /// the length field more efficiently.
259    fn reset_len(&mut self) {
260        self.len = self.value_to_multiplicity.values().map(|x| x.get()).sum();
261    }
262}
263
264impl<T: Copy> NumericalMultiset<T> {
265    /// Iterator over all distinct values in the multiset, along with their
266    /// multiplicities.
267    ///
268    /// Values are emitted in ascending order.
269    ///
270    /// See also [`values()`](Self::values) for a more efficient alternative if
271    /// you do not need to know how many occurences of each value are present.
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// use numerical_multiset::NumericalMultiset;
277    /// use std::num::NonZeroUsize;
278    ///
279    /// let mset = NumericalMultiset::from_iter([3, 1, 2, 2]);
280    ///
281    /// let mut iter = mset.iter();
282    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
283    /// assert_eq!(iter.next(), Some((1, nonzero(1))));
284    /// assert_eq!(iter.next(), Some((2, nonzero(2))));
285    /// assert_eq!(iter.next(), Some((3, nonzero(1))));
286    /// assert_eq!(iter.next(), None);
287    /// ```
288    #[must_use = "Only effect is to produce a result"]
289    pub fn iter(&self) -> Iter<'_, T> {
290        self.into_iter()
291    }
292
293    /// Iterator over all distinct values in the multiset, i.e. the mathematical
294    /// support of the multiset.
295    ///
296    /// Values are emitted in ascending order.
297    ///
298    /// See also [`iter()`](Self::iter) if you need to know how many occurences
299    /// of each value are present in the multiset.
300    ///
301    /// # Examples
302    ///
303    /// ```
304    /// use numerical_multiset::NumericalMultiset;
305    ///
306    /// let mset = NumericalMultiset::from_iter([3, 1, 2, 2]);
307    ///
308    /// let mut iter = mset.values();
309    /// assert_eq!(iter.next(), Some(1));
310    /// assert_eq!(iter.next(), Some(2));
311    /// assert_eq!(iter.next(), Some(3));
312    /// assert_eq!(iter.next(), None);
313    /// ```
314    #[must_use = "Only effect is to produce a result"]
315    pub fn values(
316        &self,
317    ) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator + Clone {
318        self.value_to_multiplicity.keys().copied()
319    }
320}
321
322impl<T: Ord> NumericalMultiset<T> {
323    /// Returns `true` if the multiset contains at least one occurence of a
324    /// value.
325    ///
326    /// See also [`multiplicity()`](Self::multiplicity) if you need to know how
327    /// many occurences of a value are present inside of the multiset.
328    ///
329    /// # Examples
330    ///
331    /// ```
332    /// use numerical_multiset::NumericalMultiset;
333    ///
334    /// let mset = NumericalMultiset::from_iter([1, 2, 2]);
335    ///
336    /// assert_eq!(mset.contains(1), true);
337    /// assert_eq!(mset.contains(2), true);
338    /// assert_eq!(mset.contains(3), false);
339    /// ```
340    #[inline]
341    #[must_use = "Only effect is to produce a result"]
342    pub fn contains(&self, value: T) -> bool {
343        self.value_to_multiplicity.contains_key(&value)
344    }
345
346    /// Returns the number of occurences of a value inside of the multiset, or
347    /// `None` if this value is not present.
348    ///
349    /// See also [`contains()`](Self::contains) for a more efficient alternative
350    /// if you only need to know whether at least one occurence of `value` is
351    /// present inside of the multiset.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// use numerical_multiset::NumericalMultiset;
357    /// use std::num::NonZeroUsize;
358    ///
359    /// let mset = NumericalMultiset::from_iter([1, 2, 2]);
360    ///
361    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
362    /// assert_eq!(mset.multiplicity(1), Some(nonzero(1)));
363    /// assert_eq!(mset.multiplicity(2), Some(nonzero(2)));
364    /// assert_eq!(mset.multiplicity(3), None);
365    /// ```
366    #[inline]
367    #[must_use = "Only effect is to produce a result"]
368    pub fn multiplicity(&self, value: T) -> Option<NonZeroUsize> {
369        self.value_to_multiplicity.get(&value).copied()
370    }
371
372    /// Returns `true` if `self` has no items in common with `other`. This is
373    /// logically equivalent to checking for an empty intersection, but may be
374    /// more efficient.
375    ///
376    /// # Examples
377    ///
378    /// ```
379    /// use numerical_multiset::NumericalMultiset;
380    ///
381    /// let a = NumericalMultiset::from_iter([1, 2, 2]);
382    /// let mut b = NumericalMultiset::new();
383    ///
384    /// assert!(a.is_disjoint(&b));
385    /// b.insert(3);
386    /// assert!(a.is_disjoint(&b));
387    /// b.insert(2);
388    /// assert!(!a.is_disjoint(&b));
389    /// ```
390    #[must_use = "Only effect is to produce a result"]
391    pub fn is_disjoint(&self, other: &Self) -> bool {
392        let mut iter1 = self.value_to_multiplicity.keys().peekable();
393        let mut iter2 = other.value_to_multiplicity.keys().peekable();
394        'joint_iter: loop {
395            match (iter1.peek(), iter2.peek()) {
396                // As long as both iterators yield values, must watch out for
397                // common values through well-ordered joint iteration.
398                (Some(value1), Some(value2)) => {
399                    match value1.cmp(value2) {
400                        // Advance the iterator which is behind, trying to make
401                        // it reach the same value as the other iterator.
402                        Ordering::Less => {
403                            let _ = iter1.next();
404                            continue 'joint_iter;
405                        }
406                        Ordering::Greater => {
407                            let _ = iter2.next();
408                            continue 'joint_iter;
409                        }
410
411                        // The same value was yielded by both iterators, which
412                        // means that the multisets are not disjoint.
413                        Ordering::Equal => return false,
414                    }
415                }
416
417                // Once one iterator ends, we know there is no common value
418                // left, so we can conclude that the multisets are disjoint.
419                (Some(_), None) | (None, Some(_)) | (None, None) => return true,
420            }
421        }
422    }
423
424    /// Returns `true` if this multiset is a subset of another, i.e., `other`
425    /// contains at least all the items in `self`.
426    ///
427    /// In a multiset context, this means that if `self` contains N occurences
428    /// of a certain value, then `other` must contain at least N occurences of
429    /// that value.
430    ///
431    /// # Examples
432    ///
433    /// ```
434    /// use numerical_multiset::NumericalMultiset;
435    ///
436    /// let sup = NumericalMultiset::from_iter([1, 2, 2]);
437    /// let mut mset = NumericalMultiset::new();
438    ///
439    /// assert!(mset.is_subset(&sup));
440    /// mset.insert(2);
441    /// assert!(mset.is_subset(&sup));
442    /// mset.insert(2);
443    /// assert!(mset.is_subset(&sup));
444    /// mset.insert(2);
445    /// assert!(!mset.is_subset(&sup));
446    /// ```
447    #[must_use = "Only effect is to produce a result"]
448    pub fn is_subset(&self, other: &Self) -> bool {
449        let mut other_iter = other.value_to_multiplicity.iter().peekable();
450        for (value, &multiplicity) in self.value_to_multiplicity.iter() {
451            // Check if this value also exists in the other iterator
452            'other_iter: loop {
453                match other_iter.peek() {
454                    Some((other_value, other_multiplicity)) => match value.cmp(other_value) {
455                        // Other iterator is ahead, and because it emits values
456                        // in sorted order, we know it's never going to get back
457                        // to the current value.
458                        //
459                        // We can thus conclude that `other` does not contain
460                        // `value` and thus `self` is not a subset of it.
461                        Ordering::Less => return false,
462
463                        // Other iterator is behind and may get to the current
464                        // value later in its sorted sequence, so we must
465                        // advance it and check again.
466                        Ordering::Greater => {
467                            let _ = other_iter.next();
468                            continue 'other_iter;
469                        }
470
471                        // Current value exists in both iterators
472                        Ordering::Equal => {
473                            // For `self` to be a subset, `other` must also
474                            // contain at least the same number of occurences of
475                            // this common value. Check this.
476                            if **other_multiplicity < multiplicity {
477                                return false;
478                            }
479
480                            // We're done checking this common value, now we can
481                            // advance the other iterator beyond it and move to
482                            // the next value from `self`.
483                            let _ = other_iter.next();
484                            break 'other_iter;
485                        }
486                    },
487
488                    // Other iterator has ended, it won't yield `value`. Thus
489                    // `other` doesn't contain `value` and therefore `self` is
490                    // not a subset of `other`.
491                    None => return false,
492                }
493            }
494        }
495        true
496    }
497
498    /// Returns `true` if this multiset is a superset of another, i.e., `self`
499    /// contains at least all the items in `other`.
500    ///
501    /// In a multiset context, this means that if `other` contains N occurences
502    /// of a certain value, then `self` must contain at least N occurences of
503    /// that value.
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// use numerical_multiset::NumericalMultiset;
509    ///
510    /// let sub = NumericalMultiset::from_iter([1, 2, 2]);
511    /// let mut mset = NumericalMultiset::new();
512    ///
513    /// assert!(!mset.is_superset(&sub));
514    ///
515    /// mset.insert(3);
516    /// mset.insert(1);
517    /// assert!(!mset.is_superset(&sub));
518    ///
519    /// mset.insert(2);
520    /// assert!(!mset.is_superset(&sub));
521    ///
522    /// mset.insert(2);
523    /// assert!(mset.is_superset(&sub));
524    /// ```
525    #[must_use = "Only effect is to produce a result"]
526    pub fn is_superset(&self, other: &Self) -> bool {
527        other.is_subset(self)
528    }
529
530    /// Remove all occurences of the smallest value from the multiset, if any.
531    ///
532    /// Returns the former smallest value along with the number of occurences of
533    /// this value that were previously present in the multiset.
534    ///
535    /// See also [`pop_first()`](Self::pop_first) if you only want to remove one
536    /// occurence of the smallest value.
537    ///
538    /// # Examples
539    ///
540    /// ```
541    /// use numerical_multiset::NumericalMultiset;
542    /// use std::num::NonZeroUsize;
543    ///
544    /// let mut mset = NumericalMultiset::from_iter([1, 1, 2]);
545    ///
546    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
547    /// assert_eq!(mset.pop_all_first(), Some((1, nonzero(2))));
548    /// assert_eq!(mset.pop_all_first(), Some((2, nonzero(1))));
549    /// assert_eq!(mset.pop_all_first(), None);
550    /// ```
551    #[inline]
552    #[must_use = "Invalid removal should be handled"]
553    pub fn pop_all_first(&mut self) -> Option<(T, NonZeroUsize)> {
554        self.value_to_multiplicity
555            .pop_first()
556            .inspect(|(_value, count)| self.len -= count.get())
557    }
558
559    /// Remove all occurences of the largest value from the multiset, if any
560    ///
561    /// Returns the former largest value along with the number of occurences of
562    /// this value that were previously present in the multiset.
563    ///
564    /// See also [`pop_last()`](Self::pop_last) if you only want to remove one
565    /// occurence of the largest value.
566    ///
567    /// # Examples
568    ///
569    /// ```
570    /// use numerical_multiset::NumericalMultiset;
571    /// use std::num::NonZeroUsize;
572    ///
573    /// let mut mset = NumericalMultiset::from_iter([1, 1, 2]);
574    ///
575    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
576    /// assert_eq!(mset.pop_all_last(), Some((2, nonzero(1))));
577    /// assert_eq!(mset.pop_all_last(), Some((1, nonzero(2))));
578    /// assert_eq!(mset.pop_all_last(), None);
579    /// ```
580    #[inline]
581    #[must_use = "Invalid removal should be handled"]
582    pub fn pop_all_last(&mut self) -> Option<(T, NonZeroUsize)> {
583        self.value_to_multiplicity
584            .pop_last()
585            .inspect(|(_value, count)| self.len -= count.get())
586    }
587
588    /// Insert an item into the multiset, tell how many identical items were
589    /// already present in the multiset before insertion.
590    ///
591    /// See also [`insert_multiple()`](Self::insert_multiple) for a more
592    /// efficient alternative if you need to insert multiple copies of a value.
593    ///
594    /// # Examples
595    ///
596    /// ```
597    /// use numerical_multiset::NumericalMultiset;
598    /// use std::num::NonZeroUsize;
599    ///
600    /// let mut mset = NumericalMultiset::new();
601    ///
602    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
603    /// assert_eq!(mset.insert(1), None);
604    /// assert_eq!(mset.insert(1), Some(nonzero(1)));
605    /// assert_eq!(mset.insert(1), Some(nonzero(2)));
606    /// assert_eq!(mset.insert(2), None);
607    ///
608    /// assert_eq!(mset.len(), 4);
609    /// assert_eq!(mset.num_values(), 2);
610    /// ```
611    #[inline]
612    pub fn insert(&mut self, value: T) -> Option<NonZeroUsize> {
613        self.insert_multiple(value, NonZeroUsize::new(1).unwrap())
614    }
615
616    /// Insert multiple copies of an item, tell how many identical items were
617    /// already present in the multiset.
618    ///
619    /// This method is typically used for the purpose of efficiently
620    /// transferring all copies of a value from one multiset to another.
621    ///
622    /// See also [`insert()`](Self::insert) for a convenience shortcut in cases
623    /// where you only need to insert one copy of a value.
624    ///
625    /// # Examples
626    ///
627    /// ```
628    /// use numerical_multiset::NumericalMultiset;
629    /// use std::num::NonZeroUsize;
630    ///
631    /// let mut mset = NumericalMultiset::new();
632    ///
633    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
634    /// assert_eq!(mset.insert_multiple(1, nonzero(2)), None);
635    /// assert_eq!(mset.insert_multiple(1, nonzero(3)), Some(nonzero(2)));
636    /// assert_eq!(mset.insert_multiple(2, nonzero(2)), None);
637    ///
638    /// assert_eq!(mset.len(), 7);
639    /// assert_eq!(mset.num_values(), 2);
640    /// ```
641    #[inline]
642    pub fn insert_multiple(&mut self, value: T, count: NonZeroUsize) -> Option<NonZeroUsize> {
643        let result = match self.value_to_multiplicity.entry(value) {
644            Entry::Vacant(v) => {
645                v.insert(count);
646                None
647            }
648            Entry::Occupied(mut o) => {
649                let old_count = *o.get();
650                *o.get_mut() = old_count
651                    .checked_add(count.get())
652                    .expect("Multiplicity counter has overflown");
653                Some(old_count)
654            }
655        };
656        self.len += count.get();
657        result
658    }
659
660    /// Insert multiple copies of a value, replacing all occurences of this
661    /// value that were previously present in the multiset. Tell how many
662    /// occurences of the value were previously present in the multiset.
663    ///
664    /// # Examples
665    ///
666    /// ```
667    /// use numerical_multiset::NumericalMultiset;
668    /// use std::num::NonZeroUsize;
669    ///
670    /// let mut mset = NumericalMultiset::new();
671    ///
672    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
673    /// assert_eq!(mset.replace_all(1, nonzero(2)), None);
674    /// assert_eq!(mset.replace_all(1, nonzero(3)), Some(nonzero(2)));
675    /// assert_eq!(mset.replace_all(2, nonzero(2)), None);
676    ///
677    /// assert_eq!(mset.len(), 5);
678    /// assert_eq!(mset.num_values(), 2);
679    /// ```
680    #[inline]
681    pub fn replace_all(&mut self, value: T, count: NonZeroUsize) -> Option<NonZeroUsize> {
682        let result = match self.value_to_multiplicity.entry(value) {
683            Entry::Vacant(v) => {
684                v.insert(count);
685                None
686            }
687            Entry::Occupied(mut o) => {
688                let old_count = *o.get();
689                *o.get_mut() = count;
690                self.len -= old_count.get();
691                Some(old_count)
692            }
693        };
694        self.len += count.get();
695        result
696    }
697
698    /// Attempt to remove one item from the multiset, on success tell how many
699    /// identical items were previously present in the multiset (including the
700    /// one that was just removed).
701    ///
702    /// See also [`remove_all()`](Self::remove_all) if you want to remove all
703    /// occurences of a value from the multiset.
704    ///
705    /// # Examples
706    ///
707    /// ```
708    /// use numerical_multiset::NumericalMultiset;
709    /// use std::num::NonZeroUsize;
710    ///
711    /// let mut mset = NumericalMultiset::from_iter([1, 1, 2]);
712    ///
713    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
714    /// assert_eq!(mset.remove(1), Some(nonzero(2)));
715    /// assert_eq!(mset.remove(1), Some(nonzero(1)));
716    /// assert_eq!(mset.remove(1), None);
717    /// assert_eq!(mset.remove(2), Some(nonzero(1)));
718    /// assert_eq!(mset.remove(2), None);
719    /// ```
720    #[inline]
721    #[must_use = "Invalid removal should be handled"]
722    pub fn remove(&mut self, value: T) -> Option<NonZeroUsize> {
723        match self.value_to_multiplicity.entry(value) {
724            Entry::Vacant(_) => None,
725            Entry::Occupied(mut o) => {
726                let old_multiplicity = *o.get();
727                self.len -= 1;
728                match NonZeroUsize::new(old_multiplicity.get() - 1) {
729                    Some(new_multiplicity) => {
730                        *o.get_mut() = new_multiplicity;
731                    }
732                    None => {
733                        o.remove_entry();
734                    }
735                }
736                Some(old_multiplicity)
737            }
738        }
739    }
740
741    /// Attempt to remove all occurences of a value from the multiset, on
742    /// success tell how many items were removed from the multiset.
743    ///
744    /// See also [`remove()`](Self::remove) if you only want to remove one
745    /// occurence of a value from the multiset.
746    ///
747    /// # Examples
748    ///
749    /// ```
750    /// use numerical_multiset::NumericalMultiset;
751    /// use std::num::NonZeroUsize;
752    ///
753    /// let mut mset = NumericalMultiset::from_iter([1, 1, 2]);
754    ///
755    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
756    /// assert_eq!(mset.remove_all(1), Some(nonzero(2)));
757    /// assert_eq!(mset.remove_all(1), None);
758    /// assert_eq!(mset.remove_all(2), Some(nonzero(1)));
759    /// assert_eq!(mset.remove_all(2), None);
760    /// ```
761    #[inline]
762    #[must_use = "Invalid removal should be handled"]
763    pub fn remove_all(&mut self, value: T) -> Option<NonZeroUsize> {
764        let result = self.value_to_multiplicity.remove(&value);
765        self.len -= result.map_or(0, |nz| nz.get());
766        result
767    }
768
769    /// Splits the collection into two at the specified `value`.
770    ///
771    /// This returns a new multiset containing all items greater than or equal
772    /// to `value`. The multiset on which this method was called will retain all
773    /// items strictly smaller than `value`.
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// use numerical_multiset::NumericalMultiset;
779    /// use std::num::NonZeroUsize;
780    ///
781    /// let mut a = NumericalMultiset::from_iter([1, 2, 2, 3, 3, 3, 4]);
782    /// let b = a.split_off(3);
783    ///
784    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
785    /// assert!(a.iter().eq([
786    ///     (1, nonzero(1)),
787    ///     (2, nonzero(2)),
788    /// ]));
789    /// assert!(b.iter().eq([
790    ///     (3, nonzero(3)),
791    ///     (4, nonzero(1)),
792    /// ]));
793    /// ```
794    pub fn split_off(&mut self, value: T) -> Self {
795        let mut result = Self {
796            value_to_multiplicity: self.value_to_multiplicity.split_off(&value),
797            len: 0,
798        };
799        self.reset_len();
800        result.reset_len();
801        result
802    }
803}
804
805impl<T: Copy + Ord> NumericalMultiset<T> {
806    /// Double-ended iterator over a sub-range of values and their
807    /// multiplicities
808    ///
809    /// The simplest way is to use the range syntax `min..max`, thus
810    /// `range(min..max)` will yield values from `min` (inclusive) to `max`
811    /// (exclusive).
812    ///
813    /// The range may also be entered as `(Bound<T>, Bound<T>)`, so
814    /// for example `range((Excluded(4), Included(10)))` will yield a
815    /// left-exclusive, right-inclusive value range from 4 to 10.
816    ///
817    /// # Panics
818    ///
819    /// May panic if range `start > end`, or if range `start == end` and both
820    /// bounds are `Excluded`.
821    ///
822    /// # Examples
823    ///
824    /// ```
825    /// use numerical_multiset::NumericalMultiset;
826    /// use std::num::NonZeroUsize;
827    ///
828    /// let mset = NumericalMultiset::from_iter([3, 3, 5, 8, 8]);
829    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
830    /// assert!(mset.range(4..).eq([
831    ///     (5, nonzero(1)),
832    ///     (8, nonzero(2)),
833    /// ]));
834    /// ```
835    #[must_use = "Only effect is to produce a result"]
836    pub fn range<R>(
837        &self,
838        range: R,
839    ) -> impl DoubleEndedIterator<Item = (T, NonZeroUsize)> + FusedIterator
840    where
841        R: RangeBounds<T>,
842    {
843        self.value_to_multiplicity
844            .range(range)
845            .map(|(&k, &v)| (k, v))
846    }
847
848    /// Visits the items representing the difference, i.e., those that are in
849    /// `self` but not in `other`. They are sorted in ascending value order and
850    /// emitted in the usual deduplicated `(value, multiplicity)` format.
851    ///
852    /// The difference is computed item-wise, not value-wise, so if both
853    /// `self` and `other` contain occurences of a certain value `v` with
854    /// respective multiplicities `s` and `o`, then...
855    ///
856    /// - If `self` contains more occurences of `v` than `other` (i.e. `s > o`),
857    ///   then the difference will contain `s - o` occurences of `v`.
858    /// - Otherwise (if `s <= o`) the difference will not contain any occurence
859    ///   of `v`.
860    ///
861    /// # Examples
862    ///
863    /// ```
864    /// use numerical_multiset::NumericalMultiset;
865    /// use std::num::NonZeroUsize;
866    ///
867    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
868    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
869    ///
870    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
871    /// assert!(a.difference(&b).eq([
872    ///     (1, nonzero(2)),
873    ///     (2, nonzero(1)),
874    /// ]));
875    /// ```
876    #[must_use = "Only effect is to produce a result"]
877    pub fn difference<'a>(
878        &'a self,
879        other: &'a Self,
880    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
881        let mut iter = self.iter();
882        let mut other_iter = other.iter().peekable();
883        std::iter::from_fn(move || {
884            // Advance self iterator normally
885            let (mut value, mut multiplicity) = iter.next()?;
886
887            // Check if this value also exists in the other iterator
888            'other_iter: loop {
889                match other_iter.peek() {
890                    Some((other_value, other_multiplicity)) => match value.cmp(other_value) {
891                        // Other iterator is ahead, and because it emits values
892                        // in sorted order, we know it's never going to get back
893                        // to the current value. So we can yield it.
894                        Ordering::Less => return Some((value, multiplicity)),
895
896                        // Other iterator is behind and may get to the current
897                        // value later in its sorted sequence, so we must
898                        // advance it and check again.
899                        Ordering::Greater => {
900                            let _ = other_iter.next();
901                            continue 'other_iter;
902                        }
903
904                        // Current value exists in both iterators
905                        Ordering::Equal => {
906                            // If `self` contains more occurences of the common
907                            // value than `other`, then we must still yield
908                            // those occurences.
909                            if multiplicity > *other_multiplicity {
910                                let difference_multiplicity = NonZeroUsize::new(
911                                    multiplicity.get() - other_multiplicity.get(),
912                                )
913                                .expect("Checked above that this is fine");
914                                let _ = other_iter.next();
915                                return Some((value, difference_multiplicity));
916                            } else {
917                                // Otherwise, discard this entry on both sides
918                                // and move on to the next iterator items.
919                                let _ = other_iter.next();
920                                (value, multiplicity) = iter.next()?;
921                                continue 'other_iter;
922                            }
923                        }
924                    },
925
926                    // Other iterator has ended, can yield all remaining items
927                    None => return Some((value, multiplicity)),
928                }
929            }
930        })
931    }
932
933    /// Visits the items representing the symmetric difference, i.e., those
934    /// that are in `self` or in `other` but not in both. They are sorted in
935    /// ascending value order and emitted in the usual deduplicated `(value,
936    /// multiplicity)` format.
937    ///
938    /// The symmetric difference is computed item-wise, not value-wise, so if
939    /// both `self` and `other` contain occurences of a certain value `v` with
940    /// respective multiplicities `s` and `o`, then...
941    ///
942    /// - If `self` contains as many occurences of `v` as `other` (i.e. `s ==
943    ///   o`), then the symmetric difference will not contain any occurence of
944    ///   `v`.
945    /// - Otherwise (if `s != o`) the symmetric difference will contain
946    ///   `s.abs_diff(o)` occurences of `v`.
947    ///
948    /// # Examples
949    ///
950    /// ```
951    /// use numerical_multiset::NumericalMultiset;
952    /// use std::num::NonZeroUsize;
953    ///
954    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
955    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
956    ///
957    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
958    /// assert!(a.symmetric_difference(&b).eq([
959    ///     (1, nonzero(2)),
960    ///     (2, nonzero(1)),
961    ///     (4, nonzero(1)),
962    /// ]));
963    /// ```
964    #[must_use = "Only effect is to produce a result"]
965    pub fn symmetric_difference<'a>(
966        &'a self,
967        other: &'a Self,
968    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
969        let mut iter1 = self.iter().peekable();
970        let mut iter2 = other.iter().peekable();
971        std::iter::from_fn(move || {
972            'joint_iter: loop {
973                match (iter1.peek(), iter2.peek()) {
974                    // As long as both iterators yield values, must be careful to
975                    // yield values from both iterators, in the right order, and to
976                    // skip common values.
977                    (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
978                        match value1.cmp(value2) {
979                            // Yield the smallest value, if any, advancing the
980                            // corresponding iterator along the way
981                            Ordering::Less => return iter1.next(),
982                            Ordering::Greater => return iter2.next(),
983
984                            // Same value was yielded by both iterators
985                            Ordering::Equal => {
986                                // If the value was yielded with different
987                                // multiplicities, then we must still yield an
988                                // entry with a multiplicity that is the
989                                // absolute difference of these multiplicities.
990                                if multiplicity1 != multiplicity2 {
991                                    let value12 = *value1;
992                                    let difference_multiplicity = NonZeroUsize::new(
993                                        multiplicity1.get().abs_diff(multiplicity2.get()),
994                                    )
995                                    .expect("Checked above that this is fine");
996                                    let _ = (iter1.next(), iter2.next());
997                                    return Some((value12, difference_multiplicity));
998                                } else {
999                                    // Otherwise ignore the common value,
1000                                    // advance both iterators and try again
1001                                    let _ = (iter1.next(), iter2.next());
1002                                    continue 'joint_iter;
1003                                }
1004                            }
1005                        }
1006                    }
1007
1008                    // One one iterator ends, we know there's no common value
1009                    // left and there is no sorted sequence merging business to
1010                    // care about, so we can just yield the remainder as-is.
1011                    (Some(_), None) => return iter1.next(),
1012                    (None, Some(_)) => return iter2.next(),
1013                    (None, None) => return None,
1014                }
1015            }
1016        })
1017    }
1018
1019    /// Visits the items representing the intersection, i.e., those that are
1020    /// both in `self` and `other`. They are sorted in ascending value order and
1021    /// emitted in the usual deduplicated `(value, multiplicity)` format.
1022    ///
1023    /// The intersection is computed item-wise, not value-wise, so if both
1024    /// `self` and `other` contain occurences of a certain value `v` with
1025    /// respective multiplicities `s` and `o`, then the intersection will
1026    /// contain `s.min(o)` occurences of `v`.
1027    ///
1028    /// # Examples
1029    ///
1030    /// ```
1031    /// use numerical_multiset::NumericalMultiset;
1032    /// use std::num::NonZeroUsize;
1033    ///
1034    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1035    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1036    ///
1037    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1038    /// assert!(a.intersection(&b).eq([
1039    ///     (2, nonzero(1)),
1040    ///     (3, nonzero(1)),
1041    /// ]));
1042    /// ```
1043    #[must_use = "Only effect is to produce a result"]
1044    pub fn intersection<'a>(
1045        &'a self,
1046        other: &'a Self,
1047    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
1048        let mut iter1 = self.iter().peekable();
1049        let mut iter2 = other.iter().peekable();
1050        std::iter::from_fn(move || {
1051            'joint_iter: loop {
1052                match (iter1.peek(), iter2.peek()) {
1053                    // As long as both iterators yield values, must be careful
1054                    // to yield common values with merged multiplicities
1055                    (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
1056                        match value1.cmp(value2) {
1057                            // Advance the iterator which is behind, trying to make
1058                            // it reach the same value as the other iterator.
1059                            Ordering::Less => {
1060                                let _ = iter1.next();
1061                                continue 'joint_iter;
1062                            }
1063                            Ordering::Greater => {
1064                                let _ = iter2.next();
1065                                continue 'joint_iter;
1066                            }
1067
1068                            // Merge items associated with a common value
1069                            Ordering::Equal => {
1070                                let value12 = *value1;
1071                                let multiplicity12 = *multiplicity1.min(multiplicity2);
1072                                let _ = (iter1.next(), iter2.next());
1073                                return Some((value12, multiplicity12));
1074                            }
1075                        }
1076                    }
1077
1078                    // One one iterator ends, we know there's no common value
1079                    // left, so we can just yield nothing.
1080                    (Some(_), None) | (None, Some(_)) | (None, None) => return None,
1081                }
1082            }
1083        })
1084    }
1085
1086    /// Visits the items representing the union, i.e., those that are in
1087    /// either `self` or `other`, without counting values that are present in
1088    /// both multisets twice. They are sorted in ascending value order and
1089    /// emitted in the usual deduplicated `(value, multiplicity)` format.
1090    ///
1091    /// The union is computed item-wise, not value-wise, so if both
1092    /// `self` and `other` contain occurences of a certain value `v` with
1093    /// respective multiplicities `s` and `o`, then the union will contain
1094    /// `s.max(o)` occurences of `v`.
1095    ///
1096    /// # Examples
1097    ///
1098    /// ```
1099    /// use numerical_multiset::NumericalMultiset;
1100    /// use std::num::NonZeroUsize;
1101    ///
1102    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1103    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1104    ///
1105    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1106    /// assert!(a.union(&b).eq([
1107    ///     (1, nonzero(2)),
1108    ///     (2, nonzero(2)),
1109    ///     (3, nonzero(1)),
1110    ///     (4, nonzero(1)),
1111    /// ]));
1112    /// ```
1113    #[must_use = "Only effect is to produce a result"]
1114    pub fn union<'a>(
1115        &'a self,
1116        other: &'a Self,
1117    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
1118        let mut iter1 = self.iter().peekable();
1119        let mut iter2 = other.iter().peekable();
1120        std::iter::from_fn(move || match (iter1.peek(), iter2.peek()) {
1121            // As long as both iterators yield values, must be careful to
1122            // yield values in the right order and merge common multiplicities
1123            (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
1124                match value1.cmp(value2) {
1125                    // Yield non-common values in the right order
1126                    Ordering::Less => iter1.next(),
1127                    Ordering::Greater => iter2.next(),
1128
1129                    // Merge items associated with a common value
1130                    Ordering::Equal => {
1131                        let value12 = *value1;
1132                        let multiplicity12 = *multiplicity1.max(multiplicity2);
1133                        let _ = (iter1.next(), iter2.next());
1134                        Some((value12, multiplicity12))
1135                    }
1136                }
1137            }
1138
1139            // Once one iterator ends, we can just yield the rest as-is
1140            (Some(_), None) => iter1.next(),
1141            (None, Some(_)) => iter2.next(),
1142            (None, None) => None,
1143        })
1144    }
1145
1146    /// Minimal value present in the multiset, if any, along with its
1147    /// multiplicity.
1148    ///
1149    /// # Examples
1150    ///
1151    /// ```
1152    /// use numerical_multiset::NumericalMultiset;
1153    /// use std::num::NonZeroUsize;
1154    ///
1155    /// let mut mset = NumericalMultiset::new();
1156    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1157    /// assert_eq!(mset.first(), None);
1158    /// mset.insert(2);
1159    /// assert_eq!(mset.first(), Some((2, nonzero(1))));
1160    /// mset.insert(2);
1161    /// assert_eq!(mset.first(), Some((2, nonzero(2))));
1162    /// mset.insert(1);
1163    /// assert_eq!(mset.first(), Some((1, nonzero(1))));
1164    /// ```
1165    #[inline]
1166    #[must_use = "Only effect is to produce a result"]
1167    pub fn first(&self) -> Option<(T, NonZeroUsize)> {
1168        self.value_to_multiplicity
1169            .first_key_value()
1170            .map(|(&k, &v)| (k, v))
1171    }
1172
1173    /// Maximal value present in the multiset, if any, along with its
1174    /// multiplicity.
1175    ///
1176    /// # Examples
1177    ///
1178    /// ```
1179    /// use numerical_multiset::NumericalMultiset;
1180    /// use std::num::NonZeroUsize;
1181    ///
1182    /// let mut mset = NumericalMultiset::new();
1183    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1184    /// assert_eq!(mset.last(), None);
1185    /// mset.insert(1);
1186    /// assert_eq!(mset.last(), Some((1, nonzero(1))));
1187    /// mset.insert(1);
1188    /// assert_eq!(mset.last(), Some((1, nonzero(2))));
1189    /// mset.insert(2);
1190    /// assert_eq!(mset.last(), Some((2, nonzero(1))));
1191    /// ```
1192    #[inline]
1193    #[must_use = "Only effect is to produce a result"]
1194    pub fn last(&self) -> Option<(T, NonZeroUsize)> {
1195        self.value_to_multiplicity
1196            .last_key_value()
1197            .map(|(&k, &v)| (k, v))
1198    }
1199
1200    /// Remove the smallest item from the multiset.
1201    ///
1202    /// See also [`pop_all_first()`](Self::pop_all_first) if you want to remove
1203    /// all occurences of the smallest value from the multiset.
1204    ///
1205    /// # Examples
1206    ///
1207    /// ```
1208    /// use numerical_multiset::NumericalMultiset;
1209    ///
1210    /// let mut mset = NumericalMultiset::new();
1211    /// mset.insert(1);
1212    /// mset.insert(1);
1213    /// mset.insert(2);
1214    ///
1215    /// assert_eq!(mset.pop_first(), Some(1));
1216    /// assert_eq!(mset.pop_first(), Some(1));
1217    /// assert_eq!(mset.pop_first(), Some(2));
1218    /// assert_eq!(mset.pop_first(), None);
1219    /// ```
1220    #[inline]
1221    #[must_use = "Invalid removal should be handled"]
1222    pub fn pop_first(&mut self) -> Option<T> {
1223        let mut occupied = self.value_to_multiplicity.first_entry()?;
1224        let old_multiplicity = *occupied.get();
1225        let value = *occupied.key();
1226        match NonZeroUsize::new(old_multiplicity.get() - 1) {
1227            Some(new_multiplicity) => {
1228                *occupied.get_mut() = new_multiplicity;
1229            }
1230            None => {
1231                occupied.remove_entry();
1232            }
1233        }
1234        self.len -= 1;
1235        Some(value)
1236    }
1237
1238    /// Remove the largest item from the multiset.
1239    ///
1240    /// See also [`pop_all_last()`](Self::pop_all_last) if you want to remove
1241    /// all occurences of the smallest value from the multiset.
1242    ///
1243    /// # Examples
1244    ///
1245    /// ```
1246    /// use numerical_multiset::NumericalMultiset;
1247    ///
1248    /// let mut mset = NumericalMultiset::new();
1249    /// mset.insert(1);
1250    /// mset.insert(1);
1251    /// mset.insert(2);
1252    ///
1253    /// assert_eq!(mset.pop_last(), Some(2));
1254    /// assert_eq!(mset.pop_last(), Some(1));
1255    /// assert_eq!(mset.pop_last(), Some(1));
1256    /// assert_eq!(mset.pop_last(), None);
1257    /// ```
1258    #[inline]
1259    #[must_use = "Invalid removal should be handled"]
1260    pub fn pop_last(&mut self) -> Option<T> {
1261        let mut occupied = self.value_to_multiplicity.last_entry()?;
1262        let old_multiplicity = *occupied.get();
1263        let value = *occupied.key();
1264        match NonZeroUsize::new(old_multiplicity.get() - 1) {
1265            Some(new_multiplicity) => {
1266                *occupied.get_mut() = new_multiplicity;
1267            }
1268            None => {
1269                occupied.remove_entry();
1270            }
1271        }
1272        self.len -= 1;
1273        Some(value)
1274    }
1275
1276    /// Retains only the items specified by the predicate.
1277    ///
1278    /// For efficiency reasons, the filtering callback `f` is not run once per
1279    /// item, but once per distinct value present inside of the multiset.
1280    /// However, it is also provided with the multiplicity of that value within
1281    /// the multiset, which can be used as a filtering criterion.
1282    ///
1283    /// Furthermore, you get read/write access to the multiplicity, which allows
1284    /// you to change it if you desire to do so.
1285    ///
1286    /// In other words, this method removes all values `v` with multiplicity `m`
1287    /// for which `f(v, m)` returns `false`, and allows changing the
1288    /// multiplicity for all values where `f` returns `true`.
1289    ///
1290    /// Values are visited in ascending order.
1291    ///
1292    /// # Examples
1293    ///
1294    /// ```
1295    /// use numerical_multiset::NumericalMultiset;
1296    /// use std::num::NonZeroUsize;
1297    ///
1298    /// let mut mset = NumericalMultiset::from_iter([1, 1, 2, 3, 4, 4, 5, 5, 5]);
1299    /// // Keep even values with an even multiplicity
1300    /// // and odd values with an odd multiplicity.
1301    /// mset.retain(|value, multiplicity| value % 2 == multiplicity.get() % 2);
1302    ///
1303    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1304    /// assert!(mset.iter().eq([
1305    ///     (3, nonzero(1)),
1306    ///     (4, nonzero(2)),
1307    ///     (5, nonzero(3)),
1308    /// ]));
1309    /// ```
1310    pub fn retain(&mut self, mut f: impl FnMut(T, &mut NonZeroUsize) -> bool) {
1311        self.value_to_multiplicity.retain(|&k, v| f(k, v));
1312        self.reset_len();
1313    }
1314
1315    /// Moves all items from `other` into `self`, leaving `other` empty.
1316    ///
1317    /// # Examples
1318    ///
1319    /// ```
1320    /// use numerical_multiset::NumericalMultiset;
1321    /// use std::num::NonZeroUsize;
1322    ///
1323    /// let mut a = NumericalMultiset::from_iter([1, 1, 2, 3]);
1324    /// let mut b = NumericalMultiset::from_iter([3, 3, 4, 5]);
1325    ///
1326    /// a.append(&mut b);
1327    ///
1328    /// assert_eq!(a.len(), 8);
1329    /// assert!(b.is_empty());
1330    ///
1331    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1332    /// assert!(a.iter().eq([
1333    ///     (1, nonzero(2)),
1334    ///     (2, nonzero(1)),
1335    ///     (3, nonzero(3)),
1336    ///     (4, nonzero(1)),
1337    ///     (5, nonzero(1)),
1338    /// ]));
1339    /// ```
1340    pub fn append(&mut self, other: &mut Self) {
1341        // Fast path when self is empty
1342        if self.is_empty() {
1343            std::mem::swap(self, other);
1344            return;
1345        }
1346
1347        // Otherwise just insert everything into self. This is the fastest
1348        // available approach because...
1349        //
1350        // - BTreeMap::append() does not have the right semantics, if both self
1351        //   and other contain entries associated with a certain value it will
1352        //   discard the entries from self instead of adding those from others.
1353        // - BTreeMap does not externally expose a mutable iterator that allows
1354        //   for both modification of existing entries and insertions of new
1355        //   entries, which is what we would need in order to implement this
1356        //   loop more efficiently.
1357        for (value, multiplicity) in other.iter() {
1358            self.insert_multiple(value, multiplicity);
1359        }
1360        other.clear();
1361    }
1362}
1363
1364impl<T: Copy + Ord> BitAnd<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1365    type Output = NumericalMultiset<T>;
1366
1367    /// Returns the intersection of `self` and `rhs` as a new `NumericalMultiset<T>`.
1368    ///
1369    /// # Examples
1370    ///
1371    /// ```
1372    /// use numerical_multiset::NumericalMultiset;
1373    ///
1374    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1375    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1376    /// assert_eq!(
1377    ///     &a & &b,
1378    ///     NumericalMultiset::from_iter([2, 3])
1379    /// );
1380    /// ```
1381    #[must_use = "Only effect is to produce a result"]
1382    fn bitand(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1383        self.intersection(rhs).collect()
1384    }
1385}
1386
1387impl<T: Copy + Ord> BitOr<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1388    type Output = NumericalMultiset<T>;
1389
1390    /// Returns the union of `self` and `rhs` as a new `NumericalMultiset<T>`.
1391    ///
1392    /// # Examples
1393    ///
1394    /// ```
1395    /// use numerical_multiset::NumericalMultiset;
1396    ///
1397    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1398    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1399    /// assert_eq!(
1400    ///     &a | &b,
1401    ///     NumericalMultiset::from_iter([1, 1, 2, 2, 3, 4])
1402    /// );
1403    /// ```
1404    #[must_use = "Only effect is to produce a result"]
1405    fn bitor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1406        self.union(rhs).collect()
1407    }
1408}
1409
1410impl<T: Copy + Ord> BitXor<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1411    type Output = NumericalMultiset<T>;
1412
1413    /// Returns the symmetric difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1414    ///
1415    /// # Examples
1416    ///
1417    /// ```
1418    /// use numerical_multiset::NumericalMultiset;
1419    ///
1420    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1421    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1422    /// assert_eq!(
1423    ///     &a ^ &b,
1424    ///     NumericalMultiset::from_iter([1, 1, 2, 4])
1425    /// );
1426    /// ```
1427    #[must_use = "Only effect is to produce a result"]
1428    fn bitxor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1429        self.symmetric_difference(rhs).collect()
1430    }
1431}
1432
1433impl<T: Ord> Extend<T> for NumericalMultiset<T> {
1434    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1435        for element in iter {
1436            self.insert(element);
1437        }
1438    }
1439}
1440
1441impl<T: Ord> Extend<(T, NonZeroUsize)> for NumericalMultiset<T> {
1442    /// More efficient alternative to [`Extend<T>`] for cases where you know in
1443    /// advance that you are going to insert several copies of a value
1444    ///
1445    /// # Examples
1446    ///
1447    /// ```
1448    /// use numerical_multiset::NumericalMultiset;
1449    /// use std::num::NonZeroUsize;
1450    ///
1451    /// let mut mset = NumericalMultiset::from_iter([1, 2, 3]);
1452    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1453    /// mset.extend([(3, nonzero(3)), (4, nonzero(2))]);
1454    /// assert_eq!(mset, NumericalMultiset::from_iter([1, 2, 3, 3, 3, 3, 4, 4]));
1455    /// ```
1456    fn extend<I: IntoIterator<Item = (T, NonZeroUsize)>>(&mut self, iter: I) {
1457        for (value, count) in iter {
1458            self.insert_multiple(value, count);
1459        }
1460    }
1461}
1462
1463impl<T: Ord> FromIterator<T> for NumericalMultiset<T> {
1464    #[must_use = "Only effect is to produce a result"]
1465    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1466        let mut result = Self::new();
1467        result.extend(iter);
1468        result
1469    }
1470}
1471
1472impl<T: Ord> FromIterator<(T, NonZeroUsize)> for NumericalMultiset<T> {
1473    /// More efficient alternative to [`FromIterator<T>`] for cases where you
1474    /// know in advance that you are going to insert several copies of a value
1475    ///
1476    /// # Examples
1477    ///
1478    /// ```
1479    /// use numerical_multiset::NumericalMultiset;
1480    /// use std::num::NonZeroUsize;
1481    ///
1482    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1483    /// assert_eq!(
1484    ///     NumericalMultiset::from_iter([1, 2, 2, 2, 3, 3]),
1485    ///     NumericalMultiset::from_iter([
1486    ///         (1, nonzero(1)),
1487    ///         (2, nonzero(3)),
1488    ///         (3, nonzero(2)),
1489    ///     ])
1490    /// );
1491    /// ```
1492    #[must_use = "Only effect is to produce a result"]
1493    fn from_iter<I: IntoIterator<Item = (T, NonZeroUsize)>>(iter: I) -> Self {
1494        let mut result = Self::new();
1495        result.extend(iter);
1496        result
1497    }
1498}
1499
1500impl<T: Hash> Hash for NumericalMultiset<T> {
1501    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1502        self.value_to_multiplicity.hash(state)
1503    }
1504}
1505
1506impl<'a, T: Copy> IntoIterator for &'a NumericalMultiset<T> {
1507    type Item = (T, NonZeroUsize);
1508    type IntoIter = Iter<'a, T>;
1509
1510    #[must_use = "Only effect is to produce a result"]
1511    fn into_iter(self) -> Self::IntoIter {
1512        Iter(self.value_to_multiplicity.iter())
1513    }
1514}
1515//
1516/// An iterator over the contents of an [`NumericalMultiset`], sorted by value.
1517///
1518/// This `struct` is created by the [`iter()`](NumericalMultiset::iter) method on
1519/// [`NumericalMultiset`]. See its documentation for more.
1520#[derive(Clone, Debug, Default)]
1521pub struct Iter<'a, T: Copy>(btree_map::Iter<'a, T, NonZeroUsize>);
1522//
1523impl<T: Copy> DoubleEndedIterator for Iter<'_, T> {
1524    #[inline]
1525    fn next_back(&mut self) -> Option<Self::Item> {
1526        self.0.next_back().map(|(&k, &v)| (k, v))
1527    }
1528
1529    #[inline]
1530    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1531        self.0.nth_back(n).map(|(&k, &v)| (k, v))
1532    }
1533}
1534//
1535impl<T: Copy> ExactSizeIterator for Iter<'_, T> {
1536    #[must_use = "Only effect is to produce a result"]
1537    fn len(&self) -> usize {
1538        self.0.len()
1539    }
1540}
1541//
1542impl<T: Copy> FusedIterator for Iter<'_, T> {}
1543//
1544impl<T: Copy> Iterator for Iter<'_, T> {
1545    type Item = (T, NonZeroUsize);
1546
1547    #[inline]
1548    fn next(&mut self) -> Option<Self::Item> {
1549        self.0.next().map(|(&k, &v)| (k, v))
1550    }
1551
1552    #[must_use = "Only effect is to produce a result"]
1553    fn size_hint(&self) -> (usize, Option<usize>) {
1554        self.0.size_hint()
1555    }
1556
1557    fn count(self) -> usize
1558    where
1559        Self: Sized,
1560    {
1561        self.0.count()
1562    }
1563
1564    fn last(self) -> Option<Self::Item>
1565    where
1566        Self: Sized,
1567    {
1568        self.0.last().map(|(&k, &v)| (k, v))
1569    }
1570
1571    #[inline]
1572    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1573        self.0.nth(n).map(|(&k, &v)| (k, v))
1574    }
1575
1576    fn is_sorted(self) -> bool
1577    where
1578        Self: Sized,
1579        Self::Item: PartialOrd,
1580    {
1581        true
1582    }
1583}
1584
1585impl<T> IntoIterator for NumericalMultiset<T> {
1586    type Item = (T, NonZeroUsize);
1587    type IntoIter = IntoIter<T>;
1588
1589    /// Gets an iterator for moving out the `NumericalMultiset`’s contents.
1590    ///
1591    /// Items are grouped by value and emitted in `(value, multiplicity)`
1592    /// format, in ascending value order.
1593    ///
1594    /// # Examples
1595    ///
1596    /// ```
1597    /// use numerical_multiset::NumericalMultiset;
1598    /// use std::num::NonZeroUsize;
1599    ///
1600    /// let mset = NumericalMultiset::from_iter([3, 1, 2, 2]);
1601    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1602    /// assert!(mset.into_iter().eq([
1603    ///     (1, nonzero(1)),
1604    ///     (2, nonzero(2)),
1605    ///     (3, nonzero(1))
1606    /// ]));
1607    /// ```
1608    fn into_iter(self) -> Self::IntoIter {
1609        IntoIter(self.value_to_multiplicity.into_iter())
1610    }
1611}
1612//
1613/// An owning iterator over the contents of an [`NumericalMultiset`], sorted by
1614/// value.
1615///
1616/// This struct is created by the `into_iter()` method on [`NumericalMultiset`]
1617/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1618#[derive(Debug, Default)]
1619pub struct IntoIter<T>(btree_map::IntoIter<T, NonZeroUsize>);
1620//
1621impl<T> DoubleEndedIterator for IntoIter<T> {
1622    #[inline]
1623    fn next_back(&mut self) -> Option<Self::Item> {
1624        self.0.next_back()
1625    }
1626
1627    #[inline]
1628    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1629        self.0.nth_back(n)
1630    }
1631}
1632//
1633impl<T> ExactSizeIterator for IntoIter<T> {
1634    #[must_use = "Only effect is to produce a result"]
1635    fn len(&self) -> usize {
1636        self.0.len()
1637    }
1638}
1639//
1640impl<T> FusedIterator for IntoIter<T> {}
1641//
1642impl<T> Iterator for IntoIter<T> {
1643    type Item = (T, NonZeroUsize);
1644
1645    #[inline]
1646    fn next(&mut self) -> Option<Self::Item> {
1647        self.0.next()
1648    }
1649
1650    #[must_use = "Only effect is to produce a result"]
1651    fn size_hint(&self) -> (usize, Option<usize>) {
1652        self.0.size_hint()
1653    }
1654
1655    fn count(self) -> usize
1656    where
1657        Self: Sized,
1658    {
1659        self.0.count()
1660    }
1661
1662    fn last(self) -> Option<Self::Item>
1663    where
1664        Self: Sized,
1665    {
1666        self.0.last()
1667    }
1668
1669    #[inline]
1670    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1671        self.0.nth(n)
1672    }
1673
1674    fn is_sorted(self) -> bool
1675    where
1676        Self: Sized,
1677        Self::Item: PartialOrd,
1678    {
1679        true
1680    }
1681}
1682
1683impl<T: Ord> Ord for NumericalMultiset<T> {
1684    #[must_use = "Only effect is to produce a result"]
1685    fn cmp(&self, other: &Self) -> Ordering {
1686        self.value_to_multiplicity.cmp(&other.value_to_multiplicity)
1687    }
1688}
1689
1690impl<T: PartialEq> PartialEq for NumericalMultiset<T> {
1691    #[must_use = "Only effect is to produce a result"]
1692    fn eq(&self, other: &Self) -> bool {
1693        self.len == other.len && self.value_to_multiplicity == other.value_to_multiplicity
1694    }
1695}
1696
1697impl<T: PartialOrd> PartialOrd for NumericalMultiset<T> {
1698    #[must_use = "Only effect is to produce a result"]
1699    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1700        self.value_to_multiplicity
1701            .partial_cmp(&other.value_to_multiplicity)
1702    }
1703}
1704
1705impl<T: Copy + Ord> Sub<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1706    type Output = NumericalMultiset<T>;
1707
1708    /// Returns the difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1709    ///
1710    /// # Examples
1711    ///
1712    /// ```
1713    /// use numerical_multiset::NumericalMultiset;
1714    ///
1715    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1716    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1717    /// assert_eq!(
1718    ///     &a - &b,
1719    ///     NumericalMultiset::from_iter([1, 1, 2])
1720    /// );
1721    /// ```
1722    #[must_use = "Only effect is to produce a result"]
1723    fn sub(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1724        self.difference(rhs).collect()
1725    }
1726}
1727
1728#[cfg(test)]
1729mod test {
1730    use super::*;
1731    use proptest::{prelude::*, sample::SizeRange};
1732    use std::{
1733        cmp::Ordering,
1734        collections::HashSet,
1735        fmt::Debug,
1736        hash::{BuildHasher, RandomState},
1737        ops::Range,
1738    };
1739
1740    /// Clearer name for the constant 1 in NonZeroUsize format
1741    const ONE: NonZeroUsize = NonZeroUsize::MIN;
1742
1743    /// Alternative to Iterator::eq that prints a clearer message on failure
1744    fn check_equal_iterable<V, It1, It2>(it1: It1, it2: It2)
1745    where
1746        It1: IntoIterator<Item = V>,
1747        It2: IntoIterator<Item = V>,
1748        V: Debug + PartialEq,
1749    {
1750        assert_eq!(
1751            it1.into_iter().collect::<Vec<_>>(),
1752            it2.into_iter().collect::<Vec<_>>(),
1753        );
1754    }
1755
1756    /// Alternative to it.count() == 0 that prints a clearer message on failure
1757    fn check_empty_iterable<It>(it: It)
1758    where
1759        It: IntoIterator,
1760        It::Item: Debug + PartialEq,
1761    {
1762        check_equal_iterable(it, std::iter::empty());
1763    }
1764
1765    /// Check properties that should be true of any pair of multisets
1766    fn check_any_mset_pair(mset1: &NumericalMultiset<i32>, mset2: &NumericalMultiset<i32>) {
1767        let intersection = mset1 & mset2;
1768        for (val, mul) in &intersection {
1769            assert_eq!(
1770                mul,
1771                mset1
1772                    .multiplicity(val)
1773                    .unwrap()
1774                    .min(mset2.multiplicity(val).unwrap()),
1775            );
1776        }
1777        for val1 in mset1.values() {
1778            assert!(intersection.contains(val1) || !mset2.contains(val1));
1779        }
1780        for val2 in mset2.values() {
1781            assert!(intersection.contains(val2) || !mset1.contains(val2));
1782        }
1783        check_equal_iterable(mset1.intersection(mset2), &intersection);
1784
1785        let union = mset1 | mset2;
1786        for (val, mul) in &union {
1787            assert_eq!(
1788                mul.get(),
1789                mset1
1790                    .multiplicity(val)
1791                    .map_or(0, |nz| nz.get())
1792                    .max(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1793            );
1794        }
1795        for val in mset1.values().chain(mset2.values()) {
1796            assert!(union.contains(val));
1797        }
1798        check_equal_iterable(mset1.union(mset2), &union);
1799
1800        let difference = mset1 - mset2;
1801        for (val, mul) in &difference {
1802            assert_eq!(
1803                mul.get(),
1804                mset1
1805                    .multiplicity(val)
1806                    .unwrap()
1807                    .get()
1808                    .checked_sub(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1809                    .unwrap()
1810            );
1811        }
1812        for (val, mul1) in mset1 {
1813            assert!(difference.contains(val) || mset2.multiplicity(val).unwrap() >= mul1);
1814        }
1815        check_equal_iterable(mset1.difference(mset2), difference);
1816
1817        let symmetric_difference = mset1 ^ mset2;
1818        for (val, mul) in &symmetric_difference {
1819            assert_eq!(
1820                mul.get(),
1821                mset1
1822                    .multiplicity(val)
1823                    .map_or(0, |nz| nz.get())
1824                    .abs_diff(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1825            );
1826        }
1827        for (val1, mul1) in mset1 {
1828            assert!(
1829                symmetric_difference.contains(val1) || mset2.multiplicity(val1).unwrap() >= mul1
1830            );
1831        }
1832        for (val2, mul2) in mset2 {
1833            assert!(
1834                symmetric_difference.contains(val2) || mset1.multiplicity(val2).unwrap() >= mul2
1835            );
1836        }
1837        check_equal_iterable(mset1.symmetric_difference(mset2), symmetric_difference);
1838
1839        assert_eq!(mset1.is_disjoint(mset2), intersection.is_empty(),);
1840
1841        if mset1.is_subset(mset2) {
1842            for (val, mul1) in mset1 {
1843                assert!(mset2.multiplicity(val).unwrap() >= mul1);
1844            }
1845        } else {
1846            assert!(
1847                mset1.iter().any(|(val1, mul1)| {
1848                    mset2.multiplicity(val1).is_none_or(|mul2| mul2 < mul1)
1849                })
1850            )
1851        }
1852        assert_eq!(mset2.is_superset(mset1), mset1.is_subset(mset2));
1853
1854        let mut combined = mset1.clone();
1855        let mut appended = mset2.clone();
1856        combined.append(&mut appended);
1857        assert_eq!(
1858            combined,
1859            mset1
1860                .iter()
1861                .chain(mset2.iter())
1862                .collect::<NumericalMultiset<_>>()
1863        );
1864        assert!(appended.is_empty());
1865
1866        let mut extended_by_tuples = mset1.clone();
1867        extended_by_tuples.extend(mset2.iter());
1868        assert_eq!(extended_by_tuples, combined);
1869
1870        let mut extended_by_values = mset1.clone();
1871        extended_by_values.extend(
1872            mset2
1873                .iter()
1874                .flat_map(|(val, mul)| std::iter::repeat_n(val, mul.get())),
1875        );
1876        assert_eq!(
1877            extended_by_values, combined,
1878            "{mset1:?} + {mset2:?} != {extended_by_values:?}"
1879        );
1880
1881        assert_eq!(
1882            mset1.cmp(mset2),
1883            mset1
1884                .value_to_multiplicity
1885                .cmp(&mset2.value_to_multiplicity)
1886        );
1887        assert_eq!(mset1.partial_cmp(mset2), Some(mset1.cmp(mset2)));
1888    }
1889
1890    /// Check properties that should be true of any multiset, knowing its contents
1891    fn check_any_mset(mset: &NumericalMultiset<i32>, contents: &[(i32, NonZeroUsize)]) {
1892        let sorted_contents = contents
1893            .iter()
1894            .map(|(v, m)| (*v, m.get()))
1895            .collect::<BTreeMap<i32, usize>>();
1896
1897        check_equal_iterable(
1898            mset.iter().map(|(val, mul)| (val, mul.get())),
1899            sorted_contents.iter().map(|(&k, &v)| (k, v)),
1900        );
1901        check_equal_iterable(mset, mset.iter());
1902        check_equal_iterable(mset.clone(), mset.iter());
1903        check_equal_iterable(mset.range(..), mset.iter());
1904        check_equal_iterable(mset.values(), sorted_contents.keys().copied());
1905        check_equal_iterable(mset.clone().into_values(), mset.values());
1906
1907        assert_eq!(mset.len(), sorted_contents.values().sum());
1908        assert_eq!(mset.num_values(), contents.len());
1909        assert_eq!(mset.is_empty(), contents.is_empty());
1910
1911        for (&val, &mul) in &sorted_contents {
1912            assert!(mset.contains(val));
1913            assert_eq!(mset.multiplicity(val).unwrap().get(), mul);
1914        }
1915
1916        assert_eq!(
1917            mset.first().map(|(val, mul)| (val, mul.get())),
1918            sorted_contents.first_key_value().map(|(&k, &v)| (k, v)),
1919        );
1920        assert_eq!(
1921            mset.last().map(|(val, mul)| (val, mul.get())),
1922            sorted_contents.last_key_value().map(|(&k, &v)| (k, v)),
1923        );
1924
1925        #[allow(clippy::eq_op)]
1926        {
1927            assert_eq!(mset, mset);
1928        }
1929        assert_eq!(*mset, mset.clone());
1930        assert_eq!(mset.cmp(mset), Ordering::Equal);
1931        assert_eq!(mset.partial_cmp(mset), Some(mset.cmp(mset)));
1932
1933        let state = RandomState::new();
1934        assert_eq!(
1935            state.hash_one(mset),
1936            state.hash_one(&mset.value_to_multiplicity),
1937        );
1938
1939        let mut mutable = mset.clone();
1940        if let Some((first, first_mul)) = mset.first() {
1941            // Pop the smallest items...
1942            assert_eq!(mutable.pop_all_first(), Some((first, first_mul)));
1943            assert_eq!(mutable.len(), mset.len() - first_mul.get());
1944            assert_eq!(mutable.num_values(), mset.num_values() - 1);
1945            assert!(!mutable.contains(first));
1946            assert_eq!(mutable.multiplicity(first), None);
1947            assert_ne!(mutable, *mset);
1948
1949            // ...then insert them back
1950            assert_eq!(mutable.insert_multiple(first, first_mul), None);
1951            assert_eq!(mutable, *mset);
1952
1953            // Same with a single item
1954            assert_eq!(mutable.pop_first(), Some(first));
1955            assert_eq!(mutable.len(), mset.len() - 1);
1956            let new_first_mul = NonZeroUsize::new(first_mul.get() - 1);
1957            let first_is_single = new_first_mul.is_none();
1958            assert_eq!(
1959                mutable.num_values(),
1960                mset.num_values() - first_is_single as usize
1961            );
1962            assert_eq!(mutable.contains(first), !first_is_single);
1963            assert_eq!(mutable.multiplicity(first), new_first_mul);
1964            assert_ne!(mutable, *mset);
1965            assert_eq!(mutable.insert(first), new_first_mul);
1966            assert_eq!(mutable, *mset);
1967
1968            // If there is a first item, there is a last item
1969            let (last, last_mul) = mset.last().unwrap();
1970
1971            // And everything we checked for the smallest items should also
1972            // applies to the largest ones
1973            assert_eq!(mutable.pop_all_last(), Some((last, last_mul)));
1974            assert_eq!(mutable.len(), mset.len() - last_mul.get());
1975            assert_eq!(mutable.num_values(), mset.num_values() - 1);
1976            assert!(!mutable.contains(last));
1977            assert_eq!(mutable.multiplicity(last), None);
1978            assert_ne!(mutable, *mset);
1979            //
1980            assert_eq!(mutable.insert_multiple(last, last_mul), None);
1981            assert_eq!(mutable, *mset);
1982            //
1983            assert_eq!(mutable.pop_last(), Some(last));
1984            assert_eq!(mutable.len(), mset.len() - 1);
1985            let new_last_mul = NonZeroUsize::new(last_mul.get() - 1);
1986            let last_is_single = new_last_mul.is_none();
1987            assert_eq!(
1988                mutable.num_values(),
1989                mset.num_values() - last_is_single as usize
1990            );
1991            assert_eq!(mutable.contains(last), !last_is_single);
1992            assert_eq!(mutable.multiplicity(last), new_last_mul);
1993            assert_ne!(mutable, *mset);
1994            assert_eq!(mutable.insert(last), new_last_mul);
1995            assert_eq!(mutable, *mset);
1996        } else {
1997            assert!(mset.is_empty());
1998            assert_eq!(mutable.pop_first(), None);
1999            assert!(mutable.is_empty());
2000            assert_eq!(mutable.pop_all_first(), None);
2001            assert!(mutable.is_empty());
2002            assert_eq!(mutable.pop_last(), None);
2003            assert!(mutable.is_empty());
2004            assert_eq!(mutable.pop_all_last(), None);
2005            assert!(mutable.is_empty());
2006        }
2007
2008        let mut retain_all = mset.clone();
2009        retain_all.retain(|_, _| true);
2010        assert_eq!(retain_all, *mset);
2011
2012        let mut retain_nothing = mset.clone();
2013        retain_nothing.retain(|_, _| false);
2014        assert!(retain_nothing.is_empty());
2015    }
2016
2017    /// Check properties that should be true of an empty multiset
2018    fn check_empty_mset(empty: &NumericalMultiset<i32>) {
2019        check_any_mset(empty, &[]);
2020
2021        assert_eq!(empty.len(), 0);
2022        assert_eq!(empty.num_values(), 0);
2023        assert!(empty.is_empty());
2024        assert_eq!(empty.first(), None);
2025        assert_eq!(empty.last(), None);
2026
2027        check_empty_iterable(empty.iter());
2028        check_empty_iterable(empty.values());
2029        check_empty_iterable(empty.clone());
2030        check_empty_iterable(empty.clone().into_values());
2031
2032        let mut mutable = empty.clone();
2033        assert_eq!(mutable.pop_first(), None);
2034        assert_eq!(mutable.pop_last(), None);
2035        assert_eq!(mutable.pop_all_first(), None);
2036        assert_eq!(mutable.pop_all_last(), None);
2037    }
2038
2039    /// Check that clear() makes a multiset empty
2040    fn check_clear_outcome(mut mset: NumericalMultiset<i32>) {
2041        mset.clear();
2042        check_empty_mset(&mset);
2043    }
2044
2045    /// Check the various ways to build an empty multiset
2046    #[test]
2047    fn empty() {
2048        check_empty_mset(&NumericalMultiset::default());
2049        let mset = NumericalMultiset::<i32>::new();
2050        check_empty_mset(&mset);
2051        check_clear_outcome(mset);
2052    }
2053
2054    /// Maximal acceptable multiplicity value
2055    fn max_multiplicity() -> usize {
2056        SizeRange::default().end_excl()
2057    }
2058
2059    /// Generate a reasonably low multiplicity value
2060    fn multiplicity() -> impl Strategy<Value = NonZeroUsize> {
2061        prop_oneof![Just(1), Just(2), 3..max_multiplicity()]
2062            .prop_map(|m| NonZeroUsize::new(m).unwrap())
2063    }
2064
2065    /// Build an arbitrary multiset
2066    fn mset_contents() -> impl Strategy<Value = Vec<(i32, NonZeroUsize)>> {
2067        any::<HashSet<i32>>().prop_flat_map(|values| {
2068            prop::collection::vec(multiplicity(), values.len()).prop_map(move |multiplicities| {
2069                values.iter().copied().zip(multiplicities).collect()
2070            })
2071        })
2072    }
2073
2074    proptest! {
2075        /// Check properties of arbitrary multisets
2076        #[test]
2077        fn single(contents in mset_contents()) {
2078            for mset in [
2079                contents.iter().copied().collect(),
2080                contents.iter().flat_map(|(v, m)| {
2081                    std::iter::repeat_n(*v, m.get())
2082                }).collect(),
2083            ] {
2084                check_any_mset(&mset, &contents);
2085                check_any_mset_pair(&mset, &mset);
2086                let empty = NumericalMultiset::default();
2087                check_any_mset_pair(&mset, &empty);
2088                check_any_mset_pair(&empty, &mset);
2089                check_clear_outcome(mset);
2090            }
2091        }
2092    }
2093
2094    /// Build an arbitrary multiset
2095    fn mset() -> impl Strategy<Value = NumericalMultiset<i32>> {
2096        mset_contents().prop_map(NumericalMultiset::from_iter)
2097    }
2098
2099    /// Build a multiset and pick a value that has a high chance of being from
2100    /// the multiset if it is not empty.
2101    fn mset_and_value() -> impl Strategy<Value = (NumericalMultiset<i32>, i32)> {
2102        mset().prop_flat_map(|mset| {
2103            if mset.is_empty() {
2104                (Just(mset), any::<i32>()).boxed()
2105            } else {
2106                let inner_value = prop::sample::select(mset.values().collect::<Vec<_>>());
2107                let value = prop_oneof![inner_value, any::<i32>()];
2108                (Just(mset), value).boxed()
2109            }
2110        })
2111    }
2112
2113    proptest! {
2114        /// Test operations that combine a multiset with a value
2115        #[test]
2116        fn with_value((initial, value) in mset_and_value()) {
2117            // Most operations depend on whether the value was present...
2118            if let Some(&mul) = initial.value_to_multiplicity.get(&value) {
2119                assert!(initial.contains(value));
2120                assert_eq!(initial.multiplicity(value), Some(mul));
2121                {
2122                    let mut mset = initial.clone();
2123                    assert_eq!(mset.insert(value), Some(mul));
2124                    let mut expected = initial.clone();
2125                    let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2126                        unreachable!();
2127                    };
2128                    *entry.get_mut() = mul.checked_add(1).unwrap();
2129                    expected.len += 1;
2130                    assert_eq!(mset, expected);
2131                }
2132                {
2133                    let mut mset = initial.clone();
2134                    assert_eq!(mset.remove(value), Some(mul));
2135                    let mut expected = initial.clone();
2136                    if mul == ONE {
2137                        expected.value_to_multiplicity.remove(&value);
2138                    } else {
2139                        let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2140                            unreachable!();
2141                        };
2142                        *entry.get_mut() = NonZeroUsize::new(mul.get() - 1).unwrap();
2143                    }
2144                    expected.len -= 1;
2145                    assert_eq!(mset, expected);
2146                }
2147                {
2148                    let mut mset = initial.clone();
2149                    assert_eq!(mset.remove_all(value), Some(mul));
2150                    let mut expected = initial.clone();
2151                    expected.value_to_multiplicity.remove(&value);
2152                    expected.len -= mul.get();
2153                    assert_eq!(mset, expected);
2154                }
2155            } else {
2156                assert!(!initial.contains(value));
2157                assert_eq!(initial.multiplicity(value), None);
2158                {
2159                    let mut mset = initial.clone();
2160                    assert_eq!(mset.insert(value), None);
2161                    let mut expected = initial.clone();
2162                    expected.value_to_multiplicity.insert(value, ONE);
2163                    expected.len += 1;
2164                    assert_eq!(mset, expected);
2165                }
2166                {
2167                    let mut mset = initial.clone();
2168                    assert_eq!(mset.remove(value), None);
2169                    assert_eq!(mset, initial);
2170                    assert_eq!(mset.remove_all(value), None);
2171                    assert_eq!(mset, initial);
2172                }
2173            }
2174
2175            // ...except for split_off, which doesn't really care
2176            {
2177                let mut mset = initial.clone();
2178                let ge = mset.split_off(value);
2179                let lt = mset;
2180                let mut expected_lt = initial.clone();
2181                let ge_value_to_multiplicity = expected_lt.value_to_multiplicity.split_off(&value);
2182                expected_lt.reset_len();
2183                assert_eq!(lt, expected_lt);
2184                let expected_ge = NumericalMultiset::from_iter(ge_value_to_multiplicity);
2185                assert_eq!(ge, expected_ge);
2186            }
2187        }
2188
2189        /// Check operations that require a value and a multiplicity
2190        #[test]
2191        fn with_value_and_multiplicity((initial, value) in mset_and_value(),
2192                                       new_mul in multiplicity()) {
2193            // Most operations depend on whether the value was present...
2194            if let Some(&initial_mul) = initial.value_to_multiplicity.get(&value) {
2195                {
2196                    let mut mset = initial.clone();
2197                    assert_eq!(mset.insert_multiple(value, new_mul), Some(initial_mul));
2198                    let mut expected = initial.clone();
2199                    let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2200                        unreachable!();
2201                    };
2202                    *entry.get_mut() = initial_mul.checked_add(new_mul.get()).unwrap();
2203                    expected.len += new_mul.get();
2204                    assert_eq!(mset, expected);
2205                }
2206                {
2207                    let mut mset = initial.clone();
2208                    assert_eq!(mset.replace_all(value, new_mul), Some(initial_mul));
2209                    let mut expected = initial.clone();
2210                        let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2211                            unreachable!();
2212                        };
2213                        *entry.get_mut() = new_mul;
2214                    expected.len = expected.len - initial_mul.get() + new_mul.get();
2215                    assert_eq!(mset, expected);
2216                }
2217            } else {
2218                let mut inserted = initial.clone();
2219                assert_eq!(inserted.insert_multiple(value, new_mul), None);
2220                let mut expected = initial.clone();
2221                expected.value_to_multiplicity.insert(value, new_mul);
2222                expected.len += new_mul.get();
2223                assert_eq!(inserted, expected);
2224
2225                let mut replaced = initial.clone();
2226                assert_eq!(replaced.replace_all(value, new_mul), None);
2227                assert_eq!(replaced, expected);
2228            }
2229
2230            // ...but retain doesn't care much
2231            {
2232                let f = |v, m: &mut NonZeroUsize| {
2233                    if v <= value && *m <= new_mul {
2234                        *m = m.checked_add(42).unwrap();
2235                        true
2236                    } else {
2237                        false
2238                    }
2239                };
2240                let mut retained = initial.clone();
2241                retained.retain(f);
2242                let mut expected = initial.clone();
2243                expected.value_to_multiplicity.retain(|&v, m| f(v, m));
2244                expected.reset_len();
2245                assert_eq!(retained, expected);
2246            }
2247        }
2248    }
2249
2250    /// Build a multiset and pick a range of values that have a high chance of
2251    /// being from the multiset if it is not empty, and of being in sorted order
2252    fn mset_and_value_range() -> impl Strategy<Value = (NumericalMultiset<i32>, Range<i32>)> {
2253        let pair_to_range = |values: [i32; 2]| values[0]..values[1];
2254        mset().prop_flat_map(move |mset| {
2255            if mset.is_empty() {
2256                (Just(mset), any::<[i32; 2]>().prop_map(pair_to_range)).boxed()
2257            } else {
2258                let inner_value = || prop::sample::select(mset.values().collect::<Vec<_>>());
2259                let value = || prop_oneof![3 => inner_value(), 2 => any::<i32>()];
2260                let range = [value(), value()].prop_map(pair_to_range);
2261                (Just(mset), range).boxed()
2262            }
2263        })
2264    }
2265
2266    proptest! {
2267        #[test]
2268        fn range((mset, range) in mset_and_value_range()) {
2269            match std::panic::catch_unwind(|| {
2270                mset.range(range.clone()).collect::<Vec<_>>()
2271            }) {
2272                Ok(output) => check_equal_iterable(output, mset.value_to_multiplicity.range(range).map(|(&v, &m)| (v, m))),
2273                Err(_panicked) => assert!(range.start > range.end),
2274            }
2275        }
2276    }
2277
2278    /// Build a pair of multisets that have reasonable odds of having some
2279    /// simple set relationship with each other.
2280    fn mset_pair() -> impl Strategy<Value = (NumericalMultiset<i32>, NumericalMultiset<i32>)> {
2281        mset().prop_flat_map(|mset1| {
2282            if mset1.is_empty() {
2283                (Just(mset1), mset()).boxed()
2284            } else {
2285                // For related sets, we first extract a subsequence of the
2286                // (value, multiplicity) pairs contained inside mset1...
2287                let related = prop::sample::subsequence(
2288                    mset1.iter().collect::<Vec<_>>(),
2289                    0..mset1.num_values(),
2290                )
2291                .prop_flat_map(move |subseq| {
2292                    // ...then, for each retained (value, multiplicity) pairs...
2293                    subseq
2294                        .into_iter()
2295                        .map(|(v, m)| {
2296                            let m = m.get();
2297                            // ...we pick a multiplicity that has equal chance of being...
2298                            // - 1: Common gotcha in tests
2299                            // - 2..M: Less than in mset1
2300                            // - M: As many as in mset1
2301                            // - (M+1)..: More than in mset1
2302                            let multiplicity = match m {
2303                                1 => prop_oneof![Just(1), 2..max_multiplicity()].boxed(),
2304                                2 => prop_oneof![Just(1), Just(2), 3..max_multiplicity()].boxed(),
2305                                _ if m + 1 < max_multiplicity() => {
2306                                    prop_oneof![Just(1), 2..m, Just(m), (m + 1)..max_multiplicity()]
2307                                        .boxed()
2308                                }
2309                                _ => prop_oneof![Just(1), 2..max_multiplicity()].boxed(),
2310                            }
2311                            .prop_map(|m| NonZeroUsize::new(m).unwrap());
2312                            (Just(v), multiplicity)
2313                        })
2314                        .collect::<Vec<_>>()
2315                })
2316                .prop_map(|elems| elems.into_iter().collect());
2317
2318                // As a result, mset2 convers less values than mset1, so their
2319                // roles are asymmetrical. To ensure this bias isn't exposed to
2320                // tests, we should randomly flip them.
2321                let related_pair = (Just(mset1.clone()), related, any::<bool>()).prop_map(
2322                    |(mset1, mset2, flip)| {
2323                        if flip { (mset2, mset1) } else { (mset1, mset2) }
2324                    },
2325                );
2326
2327                // Finally, we can and should also sometimes pick unrelated sets
2328                // like we do when mset1 is empty
2329                prop_oneof![
2330                    1 => (Just(mset1), mset()),
2331                    4 => related_pair,
2332                ]
2333                .boxed()
2334            }
2335        })
2336    }
2337
2338    proptest! {
2339        /// Check properties of arbitrary pairs of multisets
2340        #[test]
2341        fn pair((mset1, mset2) in mset_pair()) {
2342            check_any_mset_pair(&mset1, &mset2);
2343        }
2344    }
2345}