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    fn bitand(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1382        self.intersection(rhs).collect()
1383    }
1384}
1385
1386impl<T: Copy + Ord> BitOr<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1387    type Output = NumericalMultiset<T>;
1388
1389    /// Returns the union of `self` and `rhs` as a new `NumericalMultiset<T>`.
1390    ///
1391    /// # Examples
1392    ///
1393    /// ```
1394    /// use numerical_multiset::NumericalMultiset;
1395    ///
1396    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1397    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1398    /// assert_eq!(
1399    ///     &a | &b,
1400    ///     NumericalMultiset::from_iter([1, 1, 2, 2, 3, 4])
1401    /// );
1402    /// ```
1403    fn bitor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1404        self.union(rhs).collect()
1405    }
1406}
1407
1408impl<T: Copy + Ord> BitXor<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1409    type Output = NumericalMultiset<T>;
1410
1411    /// Returns the symmetric difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1412    ///
1413    /// # Examples
1414    ///
1415    /// ```
1416    /// use numerical_multiset::NumericalMultiset;
1417    ///
1418    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1419    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1420    /// assert_eq!(
1421    ///     &a ^ &b,
1422    ///     NumericalMultiset::from_iter([1, 1, 2, 4])
1423    /// );
1424    /// ```
1425    fn bitxor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1426        self.symmetric_difference(rhs).collect()
1427    }
1428}
1429
1430impl<T: Ord> Extend<T> for NumericalMultiset<T> {
1431    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1432        for element in iter {
1433            self.insert(element);
1434        }
1435    }
1436}
1437
1438impl<T: Ord> Extend<(T, NonZeroUsize)> for NumericalMultiset<T> {
1439    /// More efficient alternative to [`Extend<T>`] for cases where you know in
1440    /// advance that you are going to insert several copies of a value
1441    ///
1442    /// # Examples
1443    ///
1444    /// ```
1445    /// use numerical_multiset::NumericalMultiset;
1446    /// use std::num::NonZeroUsize;
1447    ///
1448    /// let mut mset = NumericalMultiset::from_iter([1, 2, 3]);
1449    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1450    /// mset.extend([(3, nonzero(3)), (4, nonzero(2))]);
1451    /// assert_eq!(mset, NumericalMultiset::from_iter([1, 2, 3, 3, 3, 3, 4, 4]));
1452    /// ```
1453    fn extend<I: IntoIterator<Item = (T, NonZeroUsize)>>(&mut self, iter: I) {
1454        for (value, count) in iter {
1455            self.insert_multiple(value, count);
1456        }
1457    }
1458}
1459
1460impl<T: Ord> FromIterator<T> for NumericalMultiset<T> {
1461    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1462        let mut result = Self::new();
1463        result.extend(iter);
1464        result
1465    }
1466}
1467
1468impl<T: Ord> FromIterator<(T, NonZeroUsize)> for NumericalMultiset<T> {
1469    /// More efficient alternative to [`FromIterator<T>`] for cases where you
1470    /// know in advance that you are going to insert several copies of a value
1471    ///
1472    /// # Examples
1473    ///
1474    /// ```
1475    /// use numerical_multiset::NumericalMultiset;
1476    /// use std::num::NonZeroUsize;
1477    ///
1478    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1479    /// assert_eq!(
1480    ///     NumericalMultiset::from_iter([1, 2, 2, 2, 3, 3]),
1481    ///     NumericalMultiset::from_iter([
1482    ///         (1, nonzero(1)),
1483    ///         (2, nonzero(3)),
1484    ///         (3, nonzero(2)),
1485    ///     ])
1486    /// );
1487    /// ```
1488    fn from_iter<I: IntoIterator<Item = (T, NonZeroUsize)>>(iter: I) -> Self {
1489        let mut result = Self::new();
1490        result.extend(iter);
1491        result
1492    }
1493}
1494
1495impl<T: Hash> Hash for NumericalMultiset<T> {
1496    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1497        self.value_to_multiplicity.hash(state)
1498    }
1499}
1500
1501impl<'a, T: Copy> IntoIterator for &'a NumericalMultiset<T> {
1502    type Item = (T, NonZeroUsize);
1503    type IntoIter = Iter<'a, T>;
1504
1505    fn into_iter(self) -> Self::IntoIter {
1506        Iter(self.value_to_multiplicity.iter())
1507    }
1508}
1509//
1510/// An iterator over the contents of an [`NumericalMultiset`], sorted by value.
1511///
1512/// This `struct` is created by the [`iter()`](NumericalMultiset::iter) method on
1513/// [`NumericalMultiset`]. See its documentation for more.
1514#[derive(Clone, Debug, Default)]
1515pub struct Iter<'a, T: Copy>(btree_map::Iter<'a, T, NonZeroUsize>);
1516//
1517impl<T: Copy> DoubleEndedIterator for Iter<'_, T> {
1518    #[inline]
1519    fn next_back(&mut self) -> Option<Self::Item> {
1520        self.0.next_back().map(|(&k, &v)| (k, v))
1521    }
1522
1523    #[inline]
1524    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1525        self.0.nth_back(n).map(|(&k, &v)| (k, v))
1526    }
1527}
1528//
1529impl<T: Copy> ExactSizeIterator for Iter<'_, T> {
1530    fn len(&self) -> usize {
1531        self.0.len()
1532    }
1533}
1534//
1535impl<T: Copy> FusedIterator for Iter<'_, T> {}
1536//
1537impl<T: Copy> Iterator for Iter<'_, T> {
1538    type Item = (T, NonZeroUsize);
1539
1540    #[inline]
1541    fn next(&mut self) -> Option<Self::Item> {
1542        self.0.next().map(|(&k, &v)| (k, v))
1543    }
1544
1545    fn size_hint(&self) -> (usize, Option<usize>) {
1546        self.0.size_hint()
1547    }
1548
1549    fn count(self) -> usize
1550    where
1551        Self: Sized,
1552    {
1553        self.0.count()
1554    }
1555
1556    fn last(mut self) -> Option<Self::Item>
1557    where
1558        Self: Sized,
1559    {
1560        self.0.next_back().map(|(&k, &v)| (k, v))
1561    }
1562
1563    #[inline]
1564    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1565        self.0.nth(n).map(|(&k, &v)| (k, v))
1566    }
1567
1568    fn is_sorted(self) -> bool
1569    where
1570        Self: Sized,
1571        Self::Item: PartialOrd,
1572    {
1573        true
1574    }
1575}
1576
1577impl<T> IntoIterator for NumericalMultiset<T> {
1578    type Item = (T, NonZeroUsize);
1579    type IntoIter = IntoIter<T>;
1580
1581    /// Gets an iterator for moving out the `NumericalMultiset`’s contents.
1582    ///
1583    /// Items are grouped by value and emitted in `(value, multiplicity)`
1584    /// format, in ascending value order.
1585    ///
1586    /// # Examples
1587    ///
1588    /// ```
1589    /// use numerical_multiset::NumericalMultiset;
1590    /// use std::num::NonZeroUsize;
1591    ///
1592    /// let mset = NumericalMultiset::from_iter([3, 1, 2, 2]);
1593    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1594    /// assert!(mset.into_iter().eq([
1595    ///     (1, nonzero(1)),
1596    ///     (2, nonzero(2)),
1597    ///     (3, nonzero(1))
1598    /// ]));
1599    /// ```
1600    fn into_iter(self) -> Self::IntoIter {
1601        IntoIter(self.value_to_multiplicity.into_iter())
1602    }
1603}
1604//
1605/// An owning iterator over the contents of an [`NumericalMultiset`], sorted by
1606/// value.
1607///
1608/// This struct is created by the `into_iter()` method on [`NumericalMultiset`]
1609/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1610#[derive(Debug, Default)]
1611pub struct IntoIter<T>(btree_map::IntoIter<T, NonZeroUsize>);
1612//
1613impl<T> DoubleEndedIterator for IntoIter<T> {
1614    #[inline]
1615    fn next_back(&mut self) -> Option<Self::Item> {
1616        self.0.next_back()
1617    }
1618
1619    #[inline]
1620    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1621        self.0.nth_back(n)
1622    }
1623}
1624//
1625impl<T> ExactSizeIterator for IntoIter<T> {
1626    fn len(&self) -> usize {
1627        self.0.len()
1628    }
1629}
1630//
1631impl<T> FusedIterator for IntoIter<T> {}
1632//
1633impl<T> Iterator for IntoIter<T> {
1634    type Item = (T, NonZeroUsize);
1635
1636    #[inline]
1637    fn next(&mut self) -> Option<Self::Item> {
1638        self.0.next()
1639    }
1640
1641    fn size_hint(&self) -> (usize, Option<usize>) {
1642        self.0.size_hint()
1643    }
1644
1645    fn count(self) -> usize
1646    where
1647        Self: Sized,
1648    {
1649        self.0.count()
1650    }
1651
1652    fn last(mut self) -> Option<Self::Item>
1653    where
1654        Self: Sized,
1655    {
1656        self.0.next_back()
1657    }
1658
1659    #[inline]
1660    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1661        self.0.nth(n)
1662    }
1663
1664    fn is_sorted(self) -> bool
1665    where
1666        Self: Sized,
1667        Self::Item: PartialOrd,
1668    {
1669        true
1670    }
1671}
1672
1673impl<T: Ord> Ord for NumericalMultiset<T> {
1674    fn cmp(&self, other: &Self) -> Ordering {
1675        self.value_to_multiplicity.cmp(&other.value_to_multiplicity)
1676    }
1677}
1678
1679impl<T: PartialEq> PartialEq for NumericalMultiset<T> {
1680    fn eq(&self, other: &Self) -> bool {
1681        self.len == other.len && self.value_to_multiplicity == other.value_to_multiplicity
1682    }
1683}
1684
1685impl<T: PartialOrd> PartialOrd for NumericalMultiset<T> {
1686    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1687        self.value_to_multiplicity
1688            .partial_cmp(&other.value_to_multiplicity)
1689    }
1690}
1691
1692impl<T: Copy + Ord> Sub<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1693    type Output = NumericalMultiset<T>;
1694
1695    /// Returns the difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1696    ///
1697    /// # Examples
1698    ///
1699    /// ```
1700    /// use numerical_multiset::NumericalMultiset;
1701    ///
1702    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1703    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1704    /// assert_eq!(
1705    ///     &a - &b,
1706    ///     NumericalMultiset::from_iter([1, 1, 2])
1707    /// );
1708    /// ```
1709    fn sub(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1710        self.difference(rhs).collect()
1711    }
1712}
1713
1714#[cfg(test)]
1715mod test {
1716    use super::*;
1717    use proptest::{prelude::*, sample::SizeRange};
1718    use std::{
1719        cmp::Ordering,
1720        collections::HashSet,
1721        fmt::Debug,
1722        hash::{BuildHasher, RandomState},
1723        ops::Range,
1724    };
1725
1726    /// Clearer name for the constant 1 in NonZeroUsize format
1727    const ONE: NonZeroUsize = NonZeroUsize::MIN;
1728
1729    /// Alternative to Iterator::eq that prints a clearer message on failure
1730    fn check_equal_iterable<V, It1, It2>(it1: It1, it2: It2)
1731    where
1732        It1: IntoIterator<Item = V>,
1733        It2: IntoIterator<Item = V>,
1734        V: Debug + PartialEq,
1735    {
1736        assert_eq!(
1737            it1.into_iter().collect::<Vec<_>>(),
1738            it2.into_iter().collect::<Vec<_>>(),
1739        );
1740    }
1741
1742    /// Alternative to it.count() == 0 that prints a clearer message on failure
1743    fn check_empty_iterable<It>(it: It)
1744    where
1745        It: IntoIterator,
1746        It::Item: Debug + PartialEq,
1747    {
1748        check_equal_iterable(it, std::iter::empty());
1749    }
1750
1751    /// Check properties that should be true of any pair of multisets
1752    fn check_any_mset_pair(mset1: &NumericalMultiset<i32>, mset2: &NumericalMultiset<i32>) {
1753        let intersection = mset1 & mset2;
1754        for (val, mul) in &intersection {
1755            assert_eq!(
1756                mul,
1757                mset1
1758                    .multiplicity(val)
1759                    .unwrap()
1760                    .min(mset2.multiplicity(val).unwrap()),
1761            );
1762        }
1763        for val1 in mset1.values() {
1764            assert!(intersection.contains(val1) || !mset2.contains(val1));
1765        }
1766        for val2 in mset2.values() {
1767            assert!(intersection.contains(val2) || !mset1.contains(val2));
1768        }
1769        check_equal_iterable(mset1.intersection(mset2), &intersection);
1770
1771        let union = mset1 | mset2;
1772        for (val, mul) in &union {
1773            assert_eq!(
1774                mul.get(),
1775                mset1
1776                    .multiplicity(val)
1777                    .map_or(0, |nz| nz.get())
1778                    .max(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1779            );
1780        }
1781        for val in mset1.values().chain(mset2.values()) {
1782            assert!(union.contains(val));
1783        }
1784        check_equal_iterable(mset1.union(mset2), &union);
1785
1786        let difference = mset1 - mset2;
1787        for (val, mul) in &difference {
1788            assert_eq!(
1789                mul.get(),
1790                mset1
1791                    .multiplicity(val)
1792                    .unwrap()
1793                    .get()
1794                    .checked_sub(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1795                    .unwrap()
1796            );
1797        }
1798        for (val, mul1) in mset1 {
1799            assert!(difference.contains(val) || mset2.multiplicity(val).unwrap() >= mul1);
1800        }
1801        check_equal_iterable(mset1.difference(mset2), difference);
1802
1803        let symmetric_difference = mset1 ^ mset2;
1804        for (val, mul) in &symmetric_difference {
1805            assert_eq!(
1806                mul.get(),
1807                mset1
1808                    .multiplicity(val)
1809                    .map_or(0, |nz| nz.get())
1810                    .abs_diff(mset2.multiplicity(val).map_or(0, |nz| nz.get()))
1811            );
1812        }
1813        for (val1, mul1) in mset1 {
1814            assert!(
1815                symmetric_difference.contains(val1) || mset2.multiplicity(val1).unwrap() >= mul1
1816            );
1817        }
1818        for (val2, mul2) in mset2 {
1819            assert!(
1820                symmetric_difference.contains(val2) || mset1.multiplicity(val2).unwrap() >= mul2
1821            );
1822        }
1823        check_equal_iterable(mset1.symmetric_difference(mset2), symmetric_difference);
1824
1825        assert_eq!(mset1.is_disjoint(mset2), intersection.is_empty(),);
1826
1827        if mset1.is_subset(mset2) {
1828            for (val, mul1) in mset1 {
1829                assert!(mset2.multiplicity(val).unwrap() >= mul1);
1830            }
1831        } else {
1832            assert!(mset1
1833                .iter()
1834                .any(|(val1, mul1)| { mset2.multiplicity(val1).is_none_or(|mul2| mul2 < mul1) }))
1835        }
1836        assert_eq!(mset2.is_superset(mset1), mset1.is_subset(mset2));
1837
1838        let mut combined = mset1.clone();
1839        let mut appended = mset2.clone();
1840        combined.append(&mut appended);
1841        assert_eq!(
1842            combined,
1843            mset1
1844                .iter()
1845                .chain(mset2.iter())
1846                .collect::<NumericalMultiset<_>>()
1847        );
1848        assert!(appended.is_empty());
1849
1850        let mut extended_by_tuples = mset1.clone();
1851        extended_by_tuples.extend(mset2.iter());
1852        assert_eq!(extended_by_tuples, combined);
1853
1854        let mut extended_by_values = mset1.clone();
1855        extended_by_values.extend(
1856            mset2
1857                .iter()
1858                .flat_map(|(val, mul)| std::iter::repeat_n(val, mul.get())),
1859        );
1860        assert_eq!(
1861            extended_by_values, combined,
1862            "{mset1:?} + {mset2:?} != {extended_by_values:?}"
1863        );
1864
1865        assert_eq!(
1866            mset1.cmp(mset2),
1867            mset1
1868                .value_to_multiplicity
1869                .cmp(&mset2.value_to_multiplicity)
1870        );
1871        assert_eq!(mset1.partial_cmp(mset2), Some(mset1.cmp(mset2)));
1872    }
1873
1874    /// Check properties that should be true of any multiset, knowing its contents
1875    fn check_any_mset(mset: &NumericalMultiset<i32>, contents: &[(i32, NonZeroUsize)]) {
1876        let sorted_contents = contents
1877            .iter()
1878            .map(|(v, m)| (*v, m.get()))
1879            .collect::<BTreeMap<i32, usize>>();
1880
1881        check_equal_iterable(
1882            mset.iter().map(|(val, mul)| (val, mul.get())),
1883            sorted_contents.iter().map(|(&k, &v)| (k, v)),
1884        );
1885        check_equal_iterable(mset, mset.iter());
1886        check_equal_iterable(mset.clone(), mset.iter());
1887        check_equal_iterable(mset.range(..), mset.iter());
1888        check_equal_iterable(mset.values(), sorted_contents.keys().copied());
1889        check_equal_iterable(mset.clone().into_values(), mset.values());
1890
1891        assert_eq!(mset.len(), sorted_contents.values().sum());
1892        assert_eq!(mset.num_values(), contents.len());
1893        assert_eq!(mset.is_empty(), contents.is_empty());
1894
1895        for (&val, &mul) in &sorted_contents {
1896            assert!(mset.contains(val));
1897            assert_eq!(mset.multiplicity(val).unwrap().get(), mul);
1898        }
1899
1900        assert_eq!(
1901            mset.first().map(|(val, mul)| (val, mul.get())),
1902            sorted_contents.first_key_value().map(|(&k, &v)| (k, v)),
1903        );
1904        assert_eq!(
1905            mset.last().map(|(val, mul)| (val, mul.get())),
1906            sorted_contents.last_key_value().map(|(&k, &v)| (k, v)),
1907        );
1908
1909        #[allow(clippy::eq_op)]
1910        {
1911            assert_eq!(mset, mset);
1912        }
1913        assert_eq!(*mset, mset.clone());
1914        assert_eq!(mset.cmp(mset), Ordering::Equal);
1915        assert_eq!(mset.partial_cmp(mset), Some(mset.cmp(mset)));
1916
1917        let state = RandomState::new();
1918        assert_eq!(
1919            state.hash_one(mset),
1920            state.hash_one(&mset.value_to_multiplicity),
1921        );
1922
1923        let mut mutable = mset.clone();
1924        if let Some((first, first_mul)) = mset.first() {
1925            // Pop the smallest items...
1926            assert_eq!(mutable.pop_all_first(), Some((first, first_mul)));
1927            assert_eq!(mutable.len(), mset.len() - first_mul.get());
1928            assert_eq!(mutable.num_values(), mset.num_values() - 1);
1929            assert!(!mutable.contains(first));
1930            assert_eq!(mutable.multiplicity(first), None);
1931            assert_ne!(mutable, *mset);
1932
1933            // ...then insert them back
1934            assert_eq!(mutable.insert_multiple(first, first_mul), None);
1935            assert_eq!(mutable, *mset);
1936
1937            // Same with a single item
1938            assert_eq!(mutable.pop_first(), Some(first));
1939            assert_eq!(mutable.len(), mset.len() - 1);
1940            let new_first_mul = NonZeroUsize::new(first_mul.get() - 1);
1941            let first_is_single = new_first_mul.is_none();
1942            assert_eq!(
1943                mutable.num_values(),
1944                mset.num_values() - first_is_single as usize
1945            );
1946            assert_eq!(mutable.contains(first), !first_is_single);
1947            assert_eq!(mutable.multiplicity(first), new_first_mul);
1948            assert_ne!(mutable, *mset);
1949            assert_eq!(mutable.insert(first), new_first_mul);
1950            assert_eq!(mutable, *mset);
1951
1952            // If there is a first item, there is a last item
1953            let (last, last_mul) = mset.last().unwrap();
1954
1955            // And everything we checked for the smallest items should also
1956            // applies to the largest ones
1957            assert_eq!(mutable.pop_all_last(), Some((last, last_mul)));
1958            assert_eq!(mutable.len(), mset.len() - last_mul.get());
1959            assert_eq!(mutable.num_values(), mset.num_values() - 1);
1960            assert!(!mutable.contains(last));
1961            assert_eq!(mutable.multiplicity(last), None);
1962            assert_ne!(mutable, *mset);
1963            //
1964            assert_eq!(mutable.insert_multiple(last, last_mul), None);
1965            assert_eq!(mutable, *mset);
1966            //
1967            assert_eq!(mutable.pop_last(), Some(last));
1968            assert_eq!(mutable.len(), mset.len() - 1);
1969            let new_last_mul = NonZeroUsize::new(last_mul.get() - 1);
1970            let last_is_single = new_last_mul.is_none();
1971            assert_eq!(
1972                mutable.num_values(),
1973                mset.num_values() - last_is_single as usize
1974            );
1975            assert_eq!(mutable.contains(last), !last_is_single);
1976            assert_eq!(mutable.multiplicity(last), new_last_mul);
1977            assert_ne!(mutable, *mset);
1978            assert_eq!(mutable.insert(last), new_last_mul);
1979            assert_eq!(mutable, *mset);
1980        } else {
1981            assert!(mset.is_empty());
1982            assert_eq!(mutable.pop_first(), None);
1983            assert!(mutable.is_empty());
1984            assert_eq!(mutable.pop_all_first(), None);
1985            assert!(mutable.is_empty());
1986            assert_eq!(mutable.pop_last(), None);
1987            assert!(mutable.is_empty());
1988            assert_eq!(mutable.pop_all_last(), None);
1989            assert!(mutable.is_empty());
1990        }
1991
1992        let mut retain_all = mset.clone();
1993        retain_all.retain(|_, _| true);
1994        assert_eq!(retain_all, *mset);
1995
1996        let mut retain_nothing = mset.clone();
1997        retain_nothing.retain(|_, _| false);
1998        assert!(retain_nothing.is_empty());
1999    }
2000
2001    /// Check properties that should be true of an empty multiset
2002    fn check_empty_mset(empty: &NumericalMultiset<i32>) {
2003        check_any_mset(empty, &[]);
2004
2005        assert_eq!(empty.len(), 0);
2006        assert_eq!(empty.num_values(), 0);
2007        assert!(empty.is_empty());
2008        assert_eq!(empty.first(), None);
2009        assert_eq!(empty.last(), None);
2010
2011        check_empty_iterable(empty.iter());
2012        check_empty_iterable(empty.values());
2013        check_empty_iterable(empty.clone());
2014        check_empty_iterable(empty.clone().into_values());
2015
2016        let mut mutable = empty.clone();
2017        assert_eq!(mutable.pop_first(), None);
2018        assert_eq!(mutable.pop_last(), None);
2019        assert_eq!(mutable.pop_all_first(), None);
2020        assert_eq!(mutable.pop_all_last(), None);
2021    }
2022
2023    /// Check that clear() makes a multiset empty
2024    fn check_clear_outcome(mut mset: NumericalMultiset<i32>) {
2025        mset.clear();
2026        check_empty_mset(&mset);
2027    }
2028
2029    /// Check the various ways to build an empty multiset
2030    #[test]
2031    fn empty() {
2032        check_empty_mset(&NumericalMultiset::default());
2033        let mset = NumericalMultiset::<i32>::new();
2034        check_empty_mset(&mset);
2035        check_clear_outcome(mset);
2036    }
2037
2038    /// Maximal acceptable multiplicity value
2039    fn max_multiplicity() -> usize {
2040        SizeRange::default().end_excl()
2041    }
2042
2043    /// Generate a reasonably low multiplicity value
2044    fn multiplicity() -> impl Strategy<Value = NonZeroUsize> {
2045        prop_oneof![Just(1), Just(2), 3..max_multiplicity()]
2046            .prop_map(|m| NonZeroUsize::new(m).unwrap())
2047    }
2048
2049    /// Build an arbitrary multiset
2050    fn mset_contents() -> impl Strategy<Value = Vec<(i32, NonZeroUsize)>> {
2051        any::<HashSet<i32>>().prop_flat_map(|values| {
2052            prop::collection::vec(multiplicity(), values.len()).prop_map(move |multiplicities| {
2053                values.iter().copied().zip(multiplicities).collect()
2054            })
2055        })
2056    }
2057
2058    proptest! {
2059        /// Check properties of arbitrary multisets
2060        #[test]
2061        fn single(contents in mset_contents()) {
2062            for mset in [
2063                contents.iter().copied().collect(),
2064                contents.iter().flat_map(|(v, m)| {
2065                    std::iter::repeat_n(*v, m.get())
2066                }).collect(),
2067            ] {
2068                check_any_mset(&mset, &contents);
2069                check_any_mset_pair(&mset, &mset);
2070                let empty = NumericalMultiset::default();
2071                check_any_mset_pair(&mset, &empty);
2072                check_any_mset_pair(&empty, &mset);
2073                check_clear_outcome(mset);
2074            }
2075        }
2076    }
2077
2078    /// Build an arbitrary multiset
2079    fn mset() -> impl Strategy<Value = NumericalMultiset<i32>> {
2080        mset_contents().prop_map(NumericalMultiset::from_iter)
2081    }
2082
2083    /// Build a multiset and pick a value that has a high chance of being from
2084    /// the multiset if it is not empty.
2085    fn mset_and_value() -> impl Strategy<Value = (NumericalMultiset<i32>, i32)> {
2086        mset().prop_flat_map(|mset| {
2087            if mset.is_empty() {
2088                (Just(mset), any::<i32>()).boxed()
2089            } else {
2090                let inner_value = prop::sample::select(mset.values().collect::<Vec<_>>());
2091                let value = prop_oneof![inner_value, any::<i32>()];
2092                (Just(mset), value).boxed()
2093            }
2094        })
2095    }
2096
2097    proptest! {
2098        /// Test operations that combine a multiset with a value
2099        #[test]
2100        fn with_value((initial, value) in mset_and_value()) {
2101            // Most operations depend on whether the value was present...
2102            if let Some(&mul) = initial.value_to_multiplicity.get(&value) {
2103                assert!(initial.contains(value));
2104                assert_eq!(initial.multiplicity(value), Some(mul));
2105                {
2106                    let mut mset = initial.clone();
2107                    assert_eq!(mset.insert(value), Some(mul));
2108                    let mut expected = initial.clone();
2109                    let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2110                        unreachable!();
2111                    };
2112                    *entry.get_mut() = mul.checked_add(1).unwrap();
2113                    expected.len += 1;
2114                    assert_eq!(mset, expected);
2115                }
2116                {
2117                    let mut mset = initial.clone();
2118                    assert_eq!(mset.remove(value), Some(mul));
2119                    let mut expected = initial.clone();
2120                    if mul == ONE {
2121                        expected.value_to_multiplicity.remove(&value);
2122                    } else {
2123                        let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2124                            unreachable!();
2125                        };
2126                        *entry.get_mut() = NonZeroUsize::new(mul.get() - 1).unwrap();
2127                    }
2128                    expected.len -= 1;
2129                    assert_eq!(mset, expected);
2130                }
2131                {
2132                    let mut mset = initial.clone();
2133                    assert_eq!(mset.remove_all(value), Some(mul));
2134                    let mut expected = initial.clone();
2135                    expected.value_to_multiplicity.remove(&value);
2136                    expected.len -= mul.get();
2137                    assert_eq!(mset, expected);
2138                }
2139            } else {
2140                assert!(!initial.contains(value));
2141                assert_eq!(initial.multiplicity(value), None);
2142                {
2143                    let mut mset = initial.clone();
2144                    assert_eq!(mset.insert(value), None);
2145                    let mut expected = initial.clone();
2146                    expected.value_to_multiplicity.insert(value, ONE);
2147                    expected.len += 1;
2148                    assert_eq!(mset, expected);
2149                }
2150                {
2151                    let mut mset = initial.clone();
2152                    assert_eq!(mset.remove(value), None);
2153                    assert_eq!(mset, initial);
2154                    assert_eq!(mset.remove_all(value), None);
2155                    assert_eq!(mset, initial);
2156                }
2157            }
2158
2159            // ...except for split_off, which doesn't really care
2160            {
2161                let mut mset = initial.clone();
2162                let ge = mset.split_off(value);
2163                let lt = mset;
2164                let mut expected_lt = initial.clone();
2165                let ge_value_to_multiplicity = expected_lt.value_to_multiplicity.split_off(&value);
2166                expected_lt.reset_len();
2167                assert_eq!(lt, expected_lt);
2168                let expected_ge = NumericalMultiset::from_iter(ge_value_to_multiplicity);
2169                assert_eq!(ge, expected_ge);
2170            }
2171        }
2172
2173        /// Check operations that require a value and a multiplicity
2174        #[test]
2175        fn with_value_and_multiplicity((initial, value) in mset_and_value(),
2176                                       new_mul in multiplicity()) {
2177            // Most operations depend on whether the value was present...
2178            if let Some(&initial_mul) = initial.value_to_multiplicity.get(&value) {
2179                {
2180                    let mut mset = initial.clone();
2181                    assert_eq!(mset.insert_multiple(value, new_mul), Some(initial_mul));
2182                    let mut expected = initial.clone();
2183                    let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2184                        unreachable!();
2185                    };
2186                    *entry.get_mut() = initial_mul.checked_add(new_mul.get()).unwrap();
2187                    expected.len += new_mul.get();
2188                    assert_eq!(mset, expected);
2189                }
2190                {
2191                    let mut mset = initial.clone();
2192                    assert_eq!(mset.replace_all(value, new_mul), Some(initial_mul));
2193                    let mut expected = initial.clone();
2194                        let Entry::Occupied(mut entry) = expected.value_to_multiplicity.entry(value) else {
2195                            unreachable!();
2196                        };
2197                        *entry.get_mut() = new_mul;
2198                    expected.len = expected.len - initial_mul.get() + new_mul.get();
2199                    assert_eq!(mset, expected);
2200                }
2201            } else {
2202                let mut inserted = initial.clone();
2203                assert_eq!(inserted.insert_multiple(value, new_mul), None);
2204                let mut expected = initial.clone();
2205                expected.value_to_multiplicity.insert(value, new_mul);
2206                expected.len += new_mul.get();
2207                assert_eq!(inserted, expected);
2208
2209                let mut replaced = initial.clone();
2210                assert_eq!(replaced.replace_all(value, new_mul), None);
2211                assert_eq!(replaced, expected);
2212            }
2213
2214            // ...but retain doesn't care much
2215            {
2216                let f = |v, m: &mut NonZeroUsize| {
2217                    if v <= value && *m <= new_mul {
2218                        *m = m.checked_add(42).unwrap();
2219                        true
2220                    } else {
2221                        false
2222                    }
2223                };
2224                let mut retained = initial.clone();
2225                retained.retain(f);
2226                let mut expected = initial.clone();
2227                expected.value_to_multiplicity.retain(|&v, m| f(v, m));
2228                expected.reset_len();
2229                assert_eq!(retained, expected);
2230            }
2231        }
2232    }
2233
2234    /// Build a multiset and pick a range of values that have a high chance of
2235    /// being from the multiset if it is not empty, and of being in sorted order
2236    fn mset_and_value_range() -> impl Strategy<Value = (NumericalMultiset<i32>, Range<i32>)> {
2237        let pair_to_range = |values: [i32; 2]| values[0]..values[1];
2238        mset().prop_flat_map(move |mset| {
2239            if mset.is_empty() {
2240                (Just(mset), any::<[i32; 2]>().prop_map(pair_to_range)).boxed()
2241            } else {
2242                let inner_value = || prop::sample::select(mset.values().collect::<Vec<_>>());
2243                let value = || prop_oneof![3 => inner_value(), 2 => any::<i32>()];
2244                let range = [value(), value()].prop_map(pair_to_range);
2245                (Just(mset), range).boxed()
2246            }
2247        })
2248    }
2249
2250    proptest! {
2251        #[test]
2252        fn range((mset, range) in mset_and_value_range()) {
2253            match std::panic::catch_unwind(|| {
2254                mset.range(range.clone()).collect::<Vec<_>>()
2255            }) {
2256                Ok(output) => check_equal_iterable(output, mset.value_to_multiplicity.range(range).map(|(&v, &m)| (v, m))),
2257                Err(_panicked) => assert!(range.start > range.end),
2258            }
2259        }
2260    }
2261
2262    /// Build a pair of multisets that have reasonable odds of having some
2263    /// simple set relationship with each other.
2264    fn mset_pair() -> impl Strategy<Value = (NumericalMultiset<i32>, NumericalMultiset<i32>)> {
2265        mset().prop_flat_map(|mset1| {
2266            if mset1.is_empty() {
2267                (Just(mset1), mset()).boxed()
2268            } else {
2269                // For related sets, we first extract a subsequence of the
2270                // (value, multiplicity) pairs contained inside mset1...
2271                let related = prop::sample::subsequence(
2272                    mset1.iter().collect::<Vec<_>>(),
2273                    0..mset1.num_values(),
2274                )
2275                .prop_flat_map(move |subseq| {
2276                    // ...then, for each retained (value, multiplicity) pairs...
2277                    subseq
2278                        .into_iter()
2279                        .map(|(v, m)| {
2280                            let m = m.get();
2281                            // ...we pick a multiplicity that has equal chance of being...
2282                            // - 1: Common gotcha in tests
2283                            // - 2..M: Less than in mset1
2284                            // - M: As many as in mset1
2285                            // - (M+1)..: More than in mset1
2286                            let multiplicity = match m {
2287                                1 => prop_oneof![Just(1), 2..max_multiplicity()].boxed(),
2288                                2 => prop_oneof![Just(1), Just(2), 3..max_multiplicity()].boxed(),
2289                                _ if m + 1 < max_multiplicity() => {
2290                                    prop_oneof![Just(1), 2..m, Just(m), (m + 1)..max_multiplicity()]
2291                                        .boxed()
2292                                }
2293                                _ => prop_oneof![Just(1), 2..max_multiplicity()].boxed(),
2294                            }
2295                            .prop_map(|m| NonZeroUsize::new(m).unwrap());
2296                            (Just(v), multiplicity)
2297                        })
2298                        .collect::<Vec<_>>()
2299                })
2300                .prop_map(|elems| elems.into_iter().collect());
2301
2302                // As a result, mset2 convers less values than mset1, so their
2303                // roles are asymmetrical. To ensure this bias isn't exposed to
2304                // tests, we should randomly flip them.
2305                let related_pair = (Just(mset1.clone()), related, any::<bool>()).prop_map(
2306                    |(mset1, mset2, flip)| {
2307                        if flip {
2308                            (mset2, mset1)
2309                        } else {
2310                            (mset1, mset2)
2311                        }
2312                    },
2313                );
2314
2315                // Finally, we can and should also sometimes pick unrelated sets
2316                // like we do when mset1 is empty
2317                prop_oneof![
2318                    1 => (Just(mset1), mset()),
2319                    4 => related_pair,
2320                ]
2321                .boxed()
2322            }
2323        })
2324    }
2325
2326    proptest! {
2327        /// Check properties of arbitrary pairs of multisets
2328        #[test]
2329        fn pair((mset1, mset2) in mset_pair()) {
2330            check_any_mset_pair(&mset1, &mset2);
2331        }
2332    }
2333}