numerical_multiset/
lib.rs

1//! An ordered multiset implementation for primitive number types based on
2//! sparse histograms.
3//!
4//! This crate implements a kind of multiset, which is a generalization of the
5//! notion of mathematical set where multiple elements that are equal to each
6//! other can be present simulatneously.
7//!
8//! Our multiset implementation differs from popular multiset implementations of
9//! crates.io at the time of its release in the following respects:
10//!
11//! - It is ordered, which means that order-based queries such as getting a
12//!   sorted list of elements or finding the minimum and maximum elements are
13//!   relatively cheap. For example, the complexity of a min/max query grows
14//!   logarithmically with the number of distinct values in the multiset.
15//!     * The price to pay for this ordering is that classic set operations like
16//!       inserting/removing elements or querying whether an element is present
17//!       will scale less well to larger datasets than in the more common
18//!       hash-based multiset implementations: element-wise operations also have
19//!       logarithmic complexity, whereas a hash-based multiset can instead
20//!       achieve a constant-time operation complexity that's independent of the
21//!       collection size.
22//! - It is specialized for primitive number types and `repr(transparent)`
23//!   wrappers thereof, which means that it can leverage the property of these
24//!   numbers to improve ergonomics and compute/memory efficiency:
25//!     * Since all primitive number types are [`Copy`], we do not need to
26//!       bother with references and [`Borrow`](std::borrow::Borrow) trait
27//!       complexity like general-purpose map and set implementations do, and
28//!       can instead provide a simpler value-based API.
29//!     * Since all primitive number types have well-behaved [`Eq`]
30//!       implementations where numbers that compare equal are identical, we do
31//!       not need to track lists of equal entries like many multiset
32//!       implementations do, and can instead use a more efficient sparse
33//!       histogramming approach where we simply count the number of equal
34//!       entries.
35//!
36//! One example application of this multiset implementation would be median
37//! filtering of streaming numerical data whose bit width is too large for the
38//! classic dense histogram approach to be applicable, like floats and integers
39//! of width >= 32 bits.
40//!
41//! To use this crate with floating-point data, you will need to use one of the
42//! available [`Ord`] float wrapper that assert absence of NaNs, such as the
43//! [`NotNan`](https://docs.rs/ordered-float/latest/ordered_float/struct.NotNan.html)
44//! type from the [`ordered_float`](https://docs.rs/ordered-float) crate. We do
45//! not handle this concern for you because checking for NaN has a cost and we
46//! believe this cost is best paid once on your side and hopefully amortized
47//! across many reuses of the resulting wrapper, rather than repeatedly paid
48//! every time an element is inserted into a [`NumericalMultiset`].
49
50use std::{
51    cmp::Ordering,
52    collections::btree_map::{self, BTreeMap, Entry},
53    hash::Hash,
54    iter::FusedIterator,
55    num::NonZeroUsize,
56    ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub},
57};
58
59/// An ordered multiset implementation for primitive number types based on
60/// sparse histograms.
61///
62/// You can learn more about the design rationale and overall capabilities of
63/// this data structure in the [crate-level documentation](index.html).
64///
65/// At the time of writing, this data structure is based on the standard
66/// library's [`BTreeMap`], and many points of the [`BTreeMap`] documentation
67/// also apply to it. In particular, it is a logic error to modify the order of
68/// values stored inside of the multiset using internal mutability tricks.
69///
70/// In all the following documentation, we will use the following terminology:
71///
72/// - "values" refers to a unique value as defined by equality of the
73///   [`Eq`] implementation of type `T`
74/// - "elements" refers to possibly duplicate occurences of a value within the
75///   multiset.
76/// - "multiplicity" refers to the number of occurences of a value within the
77///   multiset, i.e. the number of elements that are equal to this value.
78///
79/// # Examples
80///
81/// ```
82/// use numerical_multiset::NumericalMultiset;
83/// use std::num::NonZeroUsize;
84///
85/// // Create a multiset
86/// let mut set = NumericalMultiset::new();
87///
88/// // Inserting elements that do not exist yet is handled much like a standard
89/// // library set type, except we return an Option instead of a boolean...
90/// assert!(set.insert(123).is_none());
91/// assert!(set.insert(456).is_none());
92///
93/// // ...which allows us to report the number of pre-existing elements, if any
94/// assert_eq!(set.insert(123), NonZeroUsize::new(1));
95///
96/// // It is possible to query the minimal and maximal elements cheaply, along
97/// // with their multiplicity within the multiset.
98/// let nonzero = |x| NonZeroUsize::new(x).unwrap();
99/// assert_eq!(set.first(), Some((123, nonzero(2))));
100/// assert_eq!(set.last(), Some((456, nonzero(1))));
101///
102/// // ...and it is more generally possible to iterate over elements in order,
103/// // from the smallest to the largest:
104/// for (elem, multiplicity) in &set {
105///     println!("{elem} with multiplicity {multiplicity}");
106/// }
107/// ```
108#[derive(Clone, Debug, Default, Eq)]
109pub struct NumericalMultiset<T> {
110    /// Mapping from distinct values to their multiplicities
111    value_to_multiplicity: BTreeMap<T, NonZeroUsize>,
112
113    /// Number of elements = sum of all multiplicities
114    len: usize,
115}
116//
117impl<T> NumericalMultiset<T> {
118    /// Makes a new, empty `NumericalMultiset`.
119    ///
120    /// Does not allocate anything on its own.
121    ///
122    /// # Examples
123    ///
124    /// ```
125    /// use numerical_multiset::NumericalMultiset;
126    ///
127    /// let mut set: NumericalMultiset<i32> = NumericalMultiset::new();
128    /// ```
129    #[must_use = "Only effect is to produce a result"]
130    pub fn new() -> Self {
131        Self {
132            value_to_multiplicity: BTreeMap::new(),
133            len: 0,
134        }
135    }
136
137    /// Clears the multiset, removing all elements.
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// use numerical_multiset::NumericalMultiset;
143    ///
144    /// let mut v = NumericalMultiset::from_iter([1, 2, 3]);
145    /// v.clear();
146    /// assert!(v.is_empty());
147    /// ```
148    pub fn clear(&mut self) {
149        self.value_to_multiplicity.clear();
150        self.len = 0;
151    }
152
153    /// Number of elements currently present in the multiset, including
154    /// duplicate occurences of a value.
155    ///
156    /// See also [`num_values()`](Self::num_values) for a count of distinct
157    /// values, ignoring duplicate elements.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use numerical_multiset::NumericalMultiset;
163    ///
164    /// let mut v = NumericalMultiset::new();
165    /// assert_eq!(v.len(), 0);
166    /// v.insert(1);
167    /// assert_eq!(v.len(), 1);
168    /// v.insert(1);
169    /// assert_eq!(v.len(), 2);
170    /// v.insert(2);
171    /// assert_eq!(v.len(), 3);
172    /// ```
173    #[must_use = "Only effect is to produce a result"]
174    pub fn len(&self) -> usize {
175        self.len
176    }
177
178    /// Number of distinct values currently present in the multiset
179    ///
180    /// See also [`len()`](Self::len) for a count of multiset elements,
181    /// including duplicates of each value.
182    ///
183    /// # Examples
184    ///
185    /// ```
186    /// use numerical_multiset::NumericalMultiset;
187    ///
188    /// let mut v = NumericalMultiset::new();
189    /// assert_eq!(v.num_values(), 0);
190    /// v.insert(1);
191    /// assert_eq!(v.num_values(), 1);
192    /// v.insert(1);
193    /// assert_eq!(v.num_values(), 1);
194    /// v.insert(2);
195    /// assert_eq!(v.num_values(), 2);
196    /// ```
197    #[must_use = "Only effect is to produce a result"]
198    pub fn num_values(&self) -> usize {
199        self.value_to_multiplicity.len()
200    }
201
202    /// Truth that the multiset contains no elements
203    ///
204    /// # Examples
205    ///
206    /// ```
207    /// use numerical_multiset::NumericalMultiset;
208    ///
209    /// let mut v = NumericalMultiset::new();
210    /// assert!(v.is_empty());
211    /// v.insert(1);
212    /// assert!(!v.is_empty());
213    /// ```
214    #[must_use = "Only effect is to produce a result"]
215    pub fn is_empty(&self) -> bool {
216        self.len == 0
217    }
218
219    /// Creates a consuming iterator visiting all the distinct values, in sorted
220    /// order. The multiset cannot be used after calling this method.
221    ///
222    /// Call [`into_iter()`](IntoIterator::into_iter) for a variation of this
223    /// iterator that additionally tells how many occurences of each value were
224    /// present in the multiset, in the usual `(value, multiplicity)` format.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use numerical_multiset::NumericalMultiset;
230    ///
231    /// let set = NumericalMultiset::from_iter([3, 1, 2, 2]);
232    /// assert!(set.into_values().eq([1, 2, 3]));
233    /// ```
234    #[must_use = "Only effect is to produce a result"]
235    pub fn into_values(
236        self,
237    ) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator {
238        self.value_to_multiplicity.into_keys()
239    }
240
241    /// Update `self.len` to match `self.value_to_multiplicity` contents
242    ///
243    /// This expensive `O(N)` operation should only be performed after calling
244    /// `BTreeMap` operations that do not provide the right hooks to update the
245    /// length field more efficiently.
246    fn reset_len(&mut self) {
247        self.len = self.value_to_multiplicity.values().map(|x| x.get()).sum();
248    }
249}
250
251impl<T: Copy> NumericalMultiset<T> {
252    /// Iterator over all distinct values in the multiset, along with their
253    /// multiplicities. Output is sorted by ascending value.
254    ///
255    /// See also [`values()`](Self::values) for a more efficient alternative if
256    /// you do not need to know how many occurences of each value are present.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use numerical_multiset::NumericalMultiset;
262    /// use std::num::NonZeroUsize;
263    ///
264    /// let set = NumericalMultiset::from_iter([3, 1, 2, 2]);
265    ///
266    /// let mut iter = set.iter();
267    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
268    /// assert_eq!(iter.next(), Some((1, nonzero(1))));
269    /// assert_eq!(iter.next(), Some((2, nonzero(2))));
270    /// assert_eq!(iter.next(), Some((3, nonzero(1))));
271    /// assert_eq!(iter.next(), None);
272    /// ```
273    #[must_use = "Only effect is to produce a result"]
274    pub fn iter(&self) -> Iter<'_, T> {
275        self.into_iter()
276    }
277
278    /// Iterator over all distinct values in the multiset. Output is sorted by
279    /// ascending value.
280    ///
281    /// See also [`iter()`](Self::iter) if you need to know how many occurences
282    /// of each value are present in the multiset.
283    ///
284    /// # Examples
285    ///
286    /// ```
287    /// use numerical_multiset::NumericalMultiset;
288    ///
289    /// let set = NumericalMultiset::from_iter([3, 1, 2, 2]);
290    ///
291    /// let mut iter = set.values();
292    /// assert_eq!(iter.next(), Some(1));
293    /// assert_eq!(iter.next(), Some(2));
294    /// assert_eq!(iter.next(), Some(3));
295    /// assert_eq!(iter.next(), None);
296    /// ```
297    #[must_use = "Only effect is to produce a result"]
298    pub fn values(
299        &self,
300    ) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator + Clone {
301        self.value_to_multiplicity.keys().copied()
302    }
303}
304
305impl<T: Ord> NumericalMultiset<T> {
306    /// Returns `true` if the multiset contains at least one occurence of a
307    /// value.
308    ///
309    /// See also [`multiplicity()`](Self::multiplicity) if you need to know how
310    /// many occurences of a value are present inside of the multiset.
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// use numerical_multiset::NumericalMultiset;
316    ///
317    /// let set = NumericalMultiset::from_iter([1, 2, 2]);
318    ///
319    /// assert_eq!(set.contains(1), true);
320    /// assert_eq!(set.contains(2), true);
321    /// assert_eq!(set.contains(3), false);
322    /// ```
323    #[inline]
324    #[must_use = "Only effect is to produce a result"]
325    pub fn contains(&self, value: T) -> bool {
326        self.value_to_multiplicity.contains_key(&value)
327    }
328
329    /// Returns the number of occurences of a value inside of the multiset, or
330    /// `None` if this value is not present.
331    ///
332    /// See also [`contains()`](Self::contains) for a more efficient alternative
333    /// if you only need to know whether at least one occurence of value is
334    /// present inside of the multiset.
335    ///
336    /// # Examples
337    ///
338    /// ```
339    /// use numerical_multiset::NumericalMultiset;
340    /// use std::num::NonZeroUsize;
341    ///
342    /// let set = NumericalMultiset::from_iter([1, 2, 2]);
343    ///
344    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
345    /// assert_eq!(set.multiplicity(1), Some(nonzero(1)));
346    /// assert_eq!(set.multiplicity(2), Some(nonzero(2)));
347    /// assert_eq!(set.multiplicity(3), None);
348    /// ```
349    #[inline]
350    #[must_use = "Only effect is to produce a result"]
351    pub fn multiplicity(&self, value: T) -> Option<NonZeroUsize> {
352        self.value_to_multiplicity.get(&value).copied()
353    }
354
355    /// Returns `true` if `self` has no elements in common with `other`. This is
356    /// logically equivalent to checking for an empty intersection, but may be
357    /// more efficient.
358    ///
359    /// # Examples
360    ///
361    /// ```
362    /// use numerical_multiset::NumericalMultiset;
363    ///
364    /// let a = NumericalMultiset::from_iter([1, 2, 2]);
365    /// let mut b = NumericalMultiset::new();
366    ///
367    /// assert!(a.is_disjoint(&b));
368    /// b.insert(3);
369    /// assert!(a.is_disjoint(&b));
370    /// b.insert(2);
371    /// assert!(!a.is_disjoint(&b));
372    /// ```
373    #[must_use = "Only effect is to produce a result"]
374    pub fn is_disjoint(&self, other: &Self) -> bool {
375        let mut iter1 = self.value_to_multiplicity.keys().peekable();
376        let mut iter2 = other.value_to_multiplicity.keys().peekable();
377        'joint_iter: loop {
378            match (iter1.peek(), iter2.peek()) {
379                // As long as both iterators yield values, must watch out for
380                // common values through well-ordered joint iteration.
381                (Some(value1), Some(value2)) => {
382                    match value1.cmp(value2) {
383                        // Advance the iterator which is behind, trying to make
384                        // it reach the same value as the other iterator.
385                        Ordering::Less => {
386                            let _ = iter1.next();
387                            continue 'joint_iter;
388                        }
389                        Ordering::Greater => {
390                            let _ = iter2.next();
391                            continue 'joint_iter;
392                        }
393
394                        // The same value was yielded by both iterators, which
395                        // means that the multisets are not disjoint.
396                        Ordering::Equal => return false,
397                    }
398                }
399
400                // Once one iterator ends, we know there's no common element
401                // left, so we can conclude that the multisets are disjoint.
402                (Some(_), None) | (None, Some(_)) | (None, None) => return true,
403            }
404        }
405    }
406
407    /// Returns `true` if the set is a subset of another, i.e., `other` contains
408    /// at least all the elements in `self`.
409    ///
410    /// In a multiset context, this means that if `self` contains N occurences
411    /// of a certain value, then `other` must contain at least N occurences of
412    /// that value.
413    ///
414    /// # Examples
415    ///
416    /// ```
417    /// use numerical_multiset::NumericalMultiset;
418    ///
419    /// let sup = NumericalMultiset::from_iter([1, 2, 2]);
420    /// let mut set = NumericalMultiset::new();
421    ///
422    /// assert!(set.is_subset(&sup));
423    /// set.insert(2);
424    /// assert!(set.is_subset(&sup));
425    /// set.insert(2);
426    /// assert!(set.is_subset(&sup));
427    /// set.insert(2);
428    /// assert!(!set.is_subset(&sup));
429    /// ```
430    #[must_use = "Only effect is to produce a result"]
431    pub fn is_subset(&self, other: &Self) -> bool {
432        let mut other_iter = other.value_to_multiplicity.iter().peekable();
433        for (value, &multiplicity) in self.value_to_multiplicity.iter() {
434            // Check if this value also exists in the other iterator
435            'other_iter: loop {
436                match other_iter.peek() {
437                    Some((other_value, other_multiplicity)) => match value.cmp(other_value) {
438                        // Other iterator is ahead, and because it emits values
439                        // in sorted order, we know it's never going to get back
440                        // to the current value.
441                        //
442                        // We can thus conclude that `other` does not contain
443                        // `value` and thus `self` is not a subset of it.
444                        Ordering::Less => return false,
445
446                        // Other iterator is behind and may get to the current
447                        // value later in its sorted sequence, so we must
448                        // advance it and check again.
449                        Ordering::Greater => {
450                            let _ = other_iter.next();
451                            continue 'other_iter;
452                        }
453
454                        // Current value exists in both iterators
455                        Ordering::Equal => {
456                            // For `self` to be a subset, `other` must also
457                            // contain at least the same number of occurences of
458                            // this common value. Check this.
459                            if **other_multiplicity < multiplicity {
460                                return false;
461                            }
462
463                            // We're done checking this common value, now we can
464                            // advance the other iterator beyond it and move to
465                            // the next value from `self`.
466                            let _ = other_iter.next();
467                            break 'other_iter;
468                        }
469                    },
470
471                    // Other iterator has ended, it won't yield `value`. Thus
472                    // `other` doesn't contain `value` and therefore `self` is
473                    // not a subset of `other`.
474                    None => return false,
475                }
476            }
477        }
478        true
479    }
480
481    /// Returns `true` if the set is a superset of another, i.e., `self`
482    /// contains at least all the elements in `other`.
483    ///
484    /// In a multiset context, this means that if `other` contains N occurences
485    /// of a certain value, then `self` must contain at least N occurences of
486    /// that value.
487    ///
488    /// # Examples
489    ///
490    /// ```
491    /// use numerical_multiset::NumericalMultiset;
492    ///
493    /// let sub = NumericalMultiset::from_iter([1, 2, 2]);
494    /// let mut set = NumericalMultiset::new();
495    ///
496    /// assert!(!set.is_superset(&sub));
497    ///
498    /// set.insert(3);
499    /// set.insert(1);
500    /// assert!(!set.is_superset(&sub));
501    ///
502    /// set.insert(2);
503    /// assert!(!set.is_superset(&sub));
504    ///
505    /// set.insert(2);
506    /// assert!(set.is_superset(&sub));
507    /// ```
508    #[must_use = "Only effect is to produce a result"]
509    pub fn is_superset(&self, other: &Self) -> bool {
510        other.is_subset(self)
511    }
512
513    /// Remove all occurences of the smallest value from the multiset, if any.
514    ///
515    /// Returns the former smallest value along with the number of occurences of
516    /// this value that were previously present in the multiset.
517    ///
518    /// See also [`pop_first()`](Self::pop_first) if you only want to remove one
519    /// occurence of the smallest value.
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// use numerical_multiset::NumericalMultiset;
525    /// use std::num::NonZeroUsize;
526    ///
527    /// let mut set = NumericalMultiset::from_iter([1, 1, 2]);
528    ///
529    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
530    /// assert_eq!(set.pop_all_first(), Some((1, nonzero(2))));
531    /// assert_eq!(set.pop_all_first(), Some((2, nonzero(1))));
532    /// assert_eq!(set.pop_all_first(), None);
533    /// ```
534    #[inline]
535    #[must_use = "Invalid removal should be handled"]
536    pub fn pop_all_first(&mut self) -> Option<(T, NonZeroUsize)> {
537        self.value_to_multiplicity
538            .pop_first()
539            .inspect(|(_value, count)| self.len -= count.get())
540    }
541
542    /// Remove all occurences of the largest value from the multiset, if any
543    ///
544    /// Returns the former largest value along with the number of occurences of
545    /// this value that were previously present in the multiset.
546    ///
547    /// See also [`pop_last()`](Self::pop_last) if you only want to remove one
548    /// occurence of the largest value.
549    ///
550    /// # Examples
551    ///
552    /// ```
553    /// use numerical_multiset::NumericalMultiset;
554    /// use std::num::NonZeroUsize;
555    ///
556    /// let mut set = NumericalMultiset::from_iter([1, 1, 2]);
557    ///
558    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
559    /// assert_eq!(set.pop_all_last(), Some((2, nonzero(1))));
560    /// assert_eq!(set.pop_all_last(), Some((1, nonzero(2))));
561    /// assert_eq!(set.pop_all_last(), None);
562    /// ```
563    #[inline]
564    #[must_use = "Invalid removal should be handled"]
565    pub fn pop_all_last(&mut self) -> Option<(T, NonZeroUsize)> {
566        self.value_to_multiplicity
567            .pop_last()
568            .inspect(|(_value, count)| self.len -= count.get())
569    }
570
571    /// Insert an element into the multiset, tell how many identical elements
572    /// were already present in the multiset before insertion.
573    ///
574    /// See also [`insert_multiple()`](Self::insert_multiple) if you need to
575    /// insert multiple copies of a value.
576    ///
577    /// # Examples
578    ///
579    /// ```
580    /// use numerical_multiset::NumericalMultiset;
581    /// use std::num::NonZeroUsize;
582    ///
583    /// let mut set = NumericalMultiset::new();
584    ///
585    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
586    /// assert_eq!(set.insert(1), None);
587    /// assert_eq!(set.insert(1), Some(nonzero(1)));
588    /// assert_eq!(set.insert(1), Some(nonzero(2)));
589    /// assert_eq!(set.insert(2), None);
590    ///
591    /// assert_eq!(set.len(), 4);
592    /// assert_eq!(set.num_values(), 2);
593    /// ```
594    #[inline]
595    pub fn insert(&mut self, value: T) -> Option<NonZeroUsize> {
596        self.insert_multiple(value, NonZeroUsize::new(1).unwrap())
597    }
598
599    /// Insert multiple copies of a value, tell how many identical elements were
600    /// already present in the multiset.
601    ///
602    /// This method is typically used when transferring all copies of a value
603    /// from one multiset to another.
604    ///
605    /// See also [`insert()`](Self::insert) for a convenience shortcut in cases
606    /// where you only need to insert one copy of a value.
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use numerical_multiset::NumericalMultiset;
612    /// use std::num::NonZeroUsize;
613    ///
614    /// let mut set = NumericalMultiset::new();
615    ///
616    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
617    /// assert_eq!(set.insert_multiple(1, nonzero(2)), None);
618    /// assert_eq!(set.insert_multiple(1, nonzero(3)), Some(nonzero(2)));
619    /// assert_eq!(set.insert_multiple(2, nonzero(2)), None);
620    ///
621    /// assert_eq!(set.len(), 7);
622    /// assert_eq!(set.num_values(), 2);
623    /// ```
624    #[inline]
625    pub fn insert_multiple(&mut self, value: T, count: NonZeroUsize) -> Option<NonZeroUsize> {
626        let result = match self.value_to_multiplicity.entry(value) {
627            Entry::Vacant(v) => {
628                v.insert(count);
629                None
630            }
631            Entry::Occupied(mut o) => {
632                let old_count = *o.get();
633                *o.get_mut() = old_count
634                    .checked_add(count.get())
635                    .expect("Multiplicity counter has overflown");
636                Some(old_count)
637            }
638        };
639        self.len += count.get();
640        result
641    }
642
643    /// Insert multiple copies of a value, replacing all occurences of this
644    /// value that were previously present in the multiset. Tell how many
645    /// occurences of `value` were previously present in the multiset.
646    ///
647    /// # Examples
648    ///
649    /// ```
650    /// use numerical_multiset::NumericalMultiset;
651    /// use std::num::NonZeroUsize;
652    ///
653    /// let mut set = NumericalMultiset::new();
654    ///
655    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
656    /// assert_eq!(set.replace_all(1, nonzero(2)), None);
657    /// assert_eq!(set.replace_all(1, nonzero(3)), Some(nonzero(2)));
658    /// assert_eq!(set.replace_all(2, nonzero(2)), None);
659    ///
660    /// assert_eq!(set.len(), 5);
661    /// assert_eq!(set.num_values(), 2);
662    /// ```
663    #[inline]
664    pub fn replace_all(&mut self, value: T, count: NonZeroUsize) -> Option<NonZeroUsize> {
665        let result = match self.value_to_multiplicity.entry(value) {
666            Entry::Vacant(v) => {
667                v.insert(count);
668                None
669            }
670            Entry::Occupied(mut o) => {
671                let old_count = *o.get();
672                *o.get_mut() = count;
673                self.len -= old_count.get();
674                Some(old_count)
675            }
676        };
677        self.len += count.get();
678        result
679    }
680
681    /// Attempt to remove one element from the multiset, on success tell how
682    /// many identical elements were previously present in the multiset.
683    ///
684    /// See also [`remove_all()`](Self::remove_all) if you want to remove all
685    /// occurences of a value from the multiset.
686    ///
687    /// # Examples
688    ///
689    /// ```
690    /// use numerical_multiset::NumericalMultiset;
691    /// use std::num::NonZeroUsize;
692    ///
693    /// let mut set = NumericalMultiset::from_iter([1, 1, 2]);
694    ///
695    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
696    /// assert_eq!(set.remove(1), Some(nonzero(2)));
697    /// assert_eq!(set.remove(1), Some(nonzero(1)));
698    /// assert_eq!(set.remove(1), None);
699    /// assert_eq!(set.remove(2), Some(nonzero(1)));
700    /// assert_eq!(set.remove(2), None);
701    /// ```
702    #[inline]
703    #[must_use = "Invalid removal should be handled"]
704    pub fn remove(&mut self, value: T) -> Option<NonZeroUsize> {
705        match self.value_to_multiplicity.entry(value) {
706            Entry::Vacant(_) => None,
707            Entry::Occupied(mut o) => {
708                let old_multiplicity = *o.get();
709                self.len -= 1;
710                match NonZeroUsize::new(old_multiplicity.get() - 1) {
711                    Some(new_multiplicity) => {
712                        *o.get_mut() = new_multiplicity;
713                    }
714                    None => {
715                        o.remove_entry();
716                    }
717                }
718                Some(old_multiplicity)
719            }
720        }
721    }
722
723    /// Attempt to remove all occurences of a value from the multiset, on
724    /// success tell how many elements were removed from the multiset.
725    ///
726    /// See also [`remove()`](Self::remove) if you only want to remove one
727    /// occurence of a value from the multiset.
728    ///
729    /// # Examples
730    ///
731    /// ```
732    /// use numerical_multiset::NumericalMultiset;
733    /// use std::num::NonZeroUsize;
734    ///
735    /// let mut set = NumericalMultiset::from_iter([1, 1, 2]);
736    ///
737    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
738    /// assert_eq!(set.remove_all(1), Some(nonzero(2)));
739    /// assert_eq!(set.remove_all(1), None);
740    /// assert_eq!(set.remove_all(2), Some(nonzero(1)));
741    /// assert_eq!(set.remove_all(2), None);
742    /// ```
743    #[inline]
744    #[must_use = "Invalid removal should be handled"]
745    pub fn remove_all(&mut self, value: T) -> Option<NonZeroUsize> {
746        let result = self.value_to_multiplicity.remove(&value);
747        self.len -= result.map_or(0, |nz| nz.get());
748        result
749    }
750
751    /// Splits the collection into two at the specified `value`.
752    ///
753    /// This returns a new collection with all elements greater than or equal to
754    /// `value`. The multiset on which this method was called will retain all
755    /// elements strictly smaller than `value`.
756    ///
757    /// # Examples
758    ///
759    /// ```
760    /// use numerical_multiset::NumericalMultiset;
761    /// use std::num::NonZeroUsize;
762    ///
763    /// let mut a = NumericalMultiset::from_iter([1, 2, 2, 3, 3, 3, 4]);
764    /// let b = a.split_off(3);
765    ///
766    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
767    /// assert!(a.iter().eq([
768    ///     (1, nonzero(1)),
769    ///     (2, nonzero(2)),
770    /// ]));
771    /// assert!(b.iter().eq([
772    ///     (3, nonzero(3)),
773    ///     (4, nonzero(1)),
774    /// ]));
775    /// ```
776    pub fn split_off(&mut self, value: T) -> Self {
777        let mut result = Self {
778            value_to_multiplicity: self.value_to_multiplicity.split_off(&value),
779            len: 0,
780        };
781        self.reset_len();
782        result.reset_len();
783        result
784    }
785}
786
787impl<T: Copy + Ord> NumericalMultiset<T> {
788    /// Double-ended iterator over a sub-range of values and their
789    /// multiplicities
790    ///
791    /// The simplest way is to use the range syntax `min..max`, thus
792    /// `range(min..max)` will yield values from `min` (inclusive) to `max`
793    /// (exclusive).
794    ///
795    /// The range may also be entered as `(Bound<T>, Bound<T>)`, so
796    /// for example `range((Excluded(4), Included(10)))` will yield a
797    /// left-exclusive, right-inclusive value range from 4 to 10.
798    ///
799    /// # Panics
800    ///
801    /// Panics if range `start > end`. Panics if range `start == end` and both
802    /// bounds are `Excluded`.
803    ///
804    /// # Examples
805    ///
806    /// ```
807    /// use numerical_multiset::NumericalMultiset;
808    /// use std::num::NonZeroUsize;
809    ///
810    /// let set = NumericalMultiset::from_iter([3, 3, 5, 8, 8]);
811    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
812    /// assert!(set.range(4..).eq([
813    ///     (5, nonzero(1)),
814    ///     (8, nonzero(2)),
815    /// ]));
816    /// ```
817    #[must_use = "Only effect is to produce a result"]
818    pub fn range<R>(
819        &self,
820        range: R,
821    ) -> impl DoubleEndedIterator<Item = (T, NonZeroUsize)> + FusedIterator
822    where
823        R: RangeBounds<T>,
824    {
825        self.value_to_multiplicity
826            .range(range)
827            .map(|(&k, &v)| (k, v))
828    }
829
830    /// Visits the elements representing the difference, i.e., those that are in
831    /// `self` but not in `other`. They are sorted in ascending value order and
832    /// emitted in the usual deduplicated `(value, multiplicity)` format.
833    ///
834    /// The difference is computed element-wise, not value-wise, so if both
835    /// `self` and `other` contain occurences of a certain value `v` with
836    /// respective multiplicities `s` and `o`, then...
837    ///
838    /// - If `self` contains more occurences of `v` than `other` (i.e. `s > o`),
839    ///   then the difference will contain `s - o` occurences of `v`.
840    /// - Otherwise (if `s <= o`) the difference will not contain any occurence
841    ///   of `v`.
842    ///
843    /// # Examples
844    ///
845    /// ```
846    /// use numerical_multiset::NumericalMultiset;
847    /// use std::num::NonZeroUsize;
848    ///
849    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
850    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
851    ///
852    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
853    /// assert!(a.difference(&b).eq([
854    ///     (1, nonzero(2)),
855    ///     (2, nonzero(1)),
856    /// ]));
857    /// ```
858    #[must_use = "Only effect is to produce a result"]
859    pub fn difference<'a>(
860        &'a self,
861        other: &'a Self,
862    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
863        let mut iter = self.iter();
864        let mut other_iter = other.iter().peekable();
865        std::iter::from_fn(move || {
866            // Advance self iterator normally
867            let (mut value, mut multiplicity) = iter.next()?;
868
869            // Check if this value also exists in the other iterator
870            'other_iter: loop {
871                match other_iter.peek() {
872                    Some((other_value, other_multiplicity)) => match value.cmp(other_value) {
873                        // Other iterator is ahead, and because it emits values
874                        // in sorted order, we know it's never going to get back
875                        // to the current value. So we can yield it.
876                        Ordering::Less => return Some((value, multiplicity)),
877
878                        // Other iterator is behind and may get to the current
879                        // value later in its sorted sequence, so we must
880                        // advance it and check again.
881                        Ordering::Greater => {
882                            let _ = other_iter.next();
883                            continue 'other_iter;
884                        }
885
886                        // Current value exists in both iterators
887                        Ordering::Equal => {
888                            // If `self` contains more occurences of the common
889                            // value than `other`, then we must still yield
890                            // those occurences.
891                            if multiplicity > *other_multiplicity {
892                                let difference_multiplicity = NonZeroUsize::new(
893                                    multiplicity.get() - other_multiplicity.get(),
894                                )
895                                .expect("Checked above that this is fine");
896                                let _ = other_iter.next();
897                                return Some((value, difference_multiplicity));
898                            } else {
899                                // Otherwise, discard this entry on both sides
900                                // and move on to the next iterator items.
901                                let _ = other_iter.next();
902                                (value, multiplicity) = iter.next()?;
903                                continue 'other_iter;
904                            }
905                        }
906                    },
907
908                    // Other iterator has ended, can yield all remaining values
909                    None => return Some((value, multiplicity)),
910                }
911            }
912        })
913    }
914
915    /// Visits the elements representing the symmetric difference, i.e., those
916    /// that are in `self` or in `other` but not in both. They are sorted in
917    /// ascending value order and emitted in the usual deduplicated `(value,
918    /// multiplicity)` format.
919    ///
920    /// The symmetric difference is computed element-wise, not value-wise, so if
921    /// both `self` and `other` contain occurences of a certain value `v` with
922    /// respective multiplicities `s` and `o`, then...
923    ///
924    /// - If `self` contains as many occurences of `v` as `other` (i.e. `s ==
925    ///   o`), then the symmetric difference will not contain any occurence of
926    ///   `v`.
927    /// - Otherwise (if `s != o`) the symmetric difference will contain
928    ///   `s.abs_diff(o)` occurences of `v`.
929    ///
930    /// # Examples
931    ///
932    /// ```
933    /// use numerical_multiset::NumericalMultiset;
934    /// use std::num::NonZeroUsize;
935    ///
936    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
937    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
938    ///
939    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
940    /// assert!(a.symmetric_difference(&b).eq([
941    ///     (1, nonzero(2)),
942    ///     (2, nonzero(1)),
943    ///     (4, nonzero(1)),
944    /// ]));
945    /// ```
946    #[must_use = "Only effect is to produce a result"]
947    pub fn symmetric_difference<'a>(
948        &'a self,
949        other: &'a Self,
950    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
951        let mut iter1 = self.iter().peekable();
952        let mut iter2 = other.iter().peekable();
953        std::iter::from_fn(move || {
954            'joint_iter: loop {
955                match (iter1.peek(), iter2.peek()) {
956                    // As long as both iterators yield values, must be careful to
957                    // yield values from both iterators, in the right order, and to
958                    // skip common values.
959                    (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
960                        match value1.cmp(value2) {
961                            // Return the smallest element, if any, advancing the
962                            // corresponding iterator along the way
963                            Ordering::Less => return iter1.next(),
964                            Ordering::Greater => return iter2.next(),
965
966                            // Same value was yielded from both iterators
967                            Ordering::Equal => {
968                                // If the value was yielded with different
969                                // multiplicities, then we must still yield an entry
970                                // with a multiplicity that is the absolute
971                                // difference of these multiplicities.
972                                if multiplicity1 != multiplicity2 {
973                                    let value12 = *value1;
974                                    let difference_multiplicity = NonZeroUsize::new(
975                                        multiplicity1.get().abs_diff(multiplicity2.get()),
976                                    )
977                                    .expect("Checked above that this is fine");
978                                    let _ = (iter1.next(), iter2.next());
979                                    return Some((value12, difference_multiplicity));
980                                } else {
981                                    // Otherwise ignore the common value, advance
982                                    // both iterators and try again
983                                    let _ = (iter1.next(), iter2.next());
984                                    continue 'joint_iter;
985                                }
986                            }
987                        }
988                    }
989
990                    // One one iterator ends, we know there's no common value left
991                    // and there is no sorted sequence merging business to care
992                    // about, so we can just yield the remainder as-is.
993                    (Some(_), None) => return iter1.next(),
994                    (None, Some(_)) => return iter2.next(),
995                    (None, None) => return None,
996                }
997            }
998        })
999    }
1000
1001    /// Visits the elements representing the intersection, i.e., those that are
1002    /// both in `self` and `other`. They are sorted in ascending value order and
1003    /// emitted in the usual deduplicated `(value, multiplicity)` format.
1004    ///
1005    /// The intersection is computed element-wise, not value-wise, so if both
1006    /// `self` and `other` contain occurences of a certain value `v` with
1007    /// respective multiplicities `s` and `o`, then the intersection will
1008    /// contain `s.min(o)` occurences of `v`.
1009    ///
1010    /// # Examples
1011    ///
1012    /// ```
1013    /// use numerical_multiset::NumericalMultiset;
1014    /// use std::num::NonZeroUsize;
1015    ///
1016    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1017    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1018    ///
1019    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1020    /// assert!(a.intersection(&b).eq([
1021    ///     (2, nonzero(1)),
1022    ///     (3, nonzero(1)),
1023    /// ]));
1024    /// ```
1025    #[must_use = "Only effect is to produce a result"]
1026    pub fn intersection<'a>(
1027        &'a self,
1028        other: &'a Self,
1029    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
1030        let mut iter1 = self.iter().peekable();
1031        let mut iter2 = other.iter().peekable();
1032        std::iter::from_fn(move || {
1033            'joint_iter: loop {
1034                match (iter1.peek(), iter2.peek()) {
1035                    // As long as both iterators yield elements, must be careful to
1036                    // yield common elements with merged multiplicities
1037                    (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
1038                        match value1.cmp(value2) {
1039                            // Advance the iterator which is behind, trying to make
1040                            // it reach the same value as the other iterator.
1041                            Ordering::Less => {
1042                                let _ = iter1.next();
1043                                continue 'joint_iter;
1044                            }
1045                            Ordering::Greater => {
1046                                let _ = iter2.next();
1047                                continue 'joint_iter;
1048                            }
1049
1050                            // Merge entries associated with a common value
1051                            Ordering::Equal => {
1052                                let value12 = *value1;
1053                                let multiplicity12 = *multiplicity1.min(multiplicity2);
1054                                let _ = (iter1.next(), iter2.next());
1055                                return Some((value12, multiplicity12));
1056                            }
1057                        }
1058                    }
1059
1060                    // One one iterator ends, we know there's no common value
1061                    // left, so we can just yield nothing.
1062                    (Some(_), None) | (None, Some(_)) | (None, None) => return None,
1063                }
1064            }
1065        })
1066    }
1067
1068    /// Visits the elements representing the union, i.e., those that are in
1069    /// either `self` or `other`, without counting values that are present in
1070    /// both multisets twice. They are sorted in ascending value order and
1071    /// emitted in the usual deduplicated `(value, multiplicity)` format.
1072    ///
1073    /// The union is computed element-wise, not value-wise, so if both
1074    /// `self` and `other` contain occurences of a certain value `v` with
1075    /// respective multiplicities `s` and `o`, then the union will contain
1076    /// `s.max(o)` occurences of `v`.
1077    ///
1078    /// # Examples
1079    ///
1080    /// ```
1081    /// use numerical_multiset::NumericalMultiset;
1082    /// use std::num::NonZeroUsize;
1083    ///
1084    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1085    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1086    ///
1087    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1088    /// assert!(a.union(&b).eq([
1089    ///     (1, nonzero(2)),
1090    ///     (2, nonzero(2)),
1091    ///     (3, nonzero(1)),
1092    ///     (4, nonzero(1)),
1093    /// ]));
1094    /// ```
1095    #[must_use = "Only effect is to produce a result"]
1096    pub fn union<'a>(
1097        &'a self,
1098        other: &'a Self,
1099    ) -> impl Iterator<Item = (T, NonZeroUsize)> + Clone + 'a {
1100        let mut iter1 = self.iter().peekable();
1101        let mut iter2 = other.iter().peekable();
1102        std::iter::from_fn(move || match (iter1.peek(), iter2.peek()) {
1103            // As long as both iterators yield elements, must be careful to
1104            // yield elements in the right order and merge common multiplicities
1105            (Some((value1, multiplicity1)), Some((value2, multiplicity2))) => {
1106                match value1.cmp(value2) {
1107                    // Yield non-common elements in the right order
1108                    Ordering::Less => iter1.next(),
1109                    Ordering::Greater => iter2.next(),
1110
1111                    // Merge entries associated with a common value
1112                    Ordering::Equal => {
1113                        let value12 = *value1;
1114                        let multiplicity12 = *multiplicity1.max(multiplicity2);
1115                        let _ = (iter1.next(), iter2.next());
1116                        Some((value12, multiplicity12))
1117                    }
1118                }
1119            }
1120
1121            // Once one iterator ends, we can just yield the rest as-is
1122            (Some(_), None) => iter1.next(),
1123            (None, Some(_)) => iter2.next(),
1124            (None, None) => None,
1125        })
1126    }
1127
1128    /// Minimal value present in the multiset, if any, along with its
1129    /// multiplicity.
1130    ///
1131    /// # Examples
1132    ///
1133    /// ```
1134    /// use numerical_multiset::NumericalMultiset;
1135    /// use std::num::NonZeroUsize;
1136    ///
1137    /// let mut set = NumericalMultiset::new();
1138    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1139    /// assert_eq!(set.first(), None);
1140    /// set.insert(2);
1141    /// assert_eq!(set.first(), Some((2, nonzero(1))));
1142    /// set.insert(2);
1143    /// assert_eq!(set.first(), Some((2, nonzero(2))));
1144    /// set.insert(1);
1145    /// assert_eq!(set.first(), Some((1, nonzero(1))));
1146    /// ```
1147    #[inline]
1148    #[must_use = "Only effect is to produce a result"]
1149    pub fn first(&self) -> Option<(T, NonZeroUsize)> {
1150        self.value_to_multiplicity
1151            .first_key_value()
1152            .map(|(&k, &v)| (k, v))
1153    }
1154
1155    /// Maximal value present in the multiset, if any, along with its
1156    /// multiplicity.
1157    ///
1158    /// # Examples
1159    ///
1160    /// ```
1161    /// use numerical_multiset::NumericalMultiset;
1162    /// use std::num::NonZeroUsize;
1163    ///
1164    /// let mut set = NumericalMultiset::new();
1165    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1166    /// assert_eq!(set.last(), None);
1167    /// set.insert(1);
1168    /// assert_eq!(set.last(), Some((1, nonzero(1))));
1169    /// set.insert(1);
1170    /// assert_eq!(set.last(), Some((1, nonzero(2))));
1171    /// set.insert(2);
1172    /// assert_eq!(set.last(), Some((2, nonzero(1))));
1173    /// ```
1174    #[inline]
1175    #[must_use = "Only effect is to produce a result"]
1176    pub fn last(&self) -> Option<(T, NonZeroUsize)> {
1177        self.value_to_multiplicity
1178            .last_key_value()
1179            .map(|(&k, &v)| (k, v))
1180    }
1181
1182    /// Remove the smallest element from the multiset.
1183    ///
1184    /// See also [`pop_all_first()`](Self::pop_all_first) if you want to remove
1185    /// all occurences of the smallest value from the multiset.
1186    ///
1187    /// # Examples
1188    ///
1189    /// ```
1190    /// use numerical_multiset::NumericalMultiset;
1191    ///
1192    /// let mut set = NumericalMultiset::new();
1193    /// set.insert(1);
1194    /// set.insert(1);
1195    /// set.insert(2);
1196    ///
1197    /// assert_eq!(set.pop_first(), Some(1));
1198    /// assert_eq!(set.pop_first(), Some(1));
1199    /// assert_eq!(set.pop_first(), Some(2));
1200    /// assert_eq!(set.pop_first(), None);
1201    /// ```
1202    #[inline]
1203    #[must_use = "Invalid removal should be handled"]
1204    pub fn pop_first(&mut self) -> Option<T> {
1205        let mut occupied = self.value_to_multiplicity.first_entry()?;
1206        let old_multiplicity = *occupied.get();
1207        let value = *occupied.key();
1208        match NonZeroUsize::new(old_multiplicity.get() - 1) {
1209            Some(new_multiplicity) => {
1210                *occupied.get_mut() = new_multiplicity;
1211            }
1212            None => {
1213                occupied.remove_entry();
1214            }
1215        }
1216        self.len -= 1;
1217        Some(value)
1218    }
1219
1220    /// Remove the largest element from the multiset.
1221    ///
1222    /// See also [`pop_all_last()`](Self::pop_all_last) if you want to remove
1223    /// all occurences of the smallest value from the multiset.
1224    ///
1225    /// # Examples
1226    ///
1227    /// ```
1228    /// use numerical_multiset::NumericalMultiset;
1229    ///
1230    /// let mut set = NumericalMultiset::new();
1231    /// set.insert(1);
1232    /// set.insert(1);
1233    /// set.insert(2);
1234    ///
1235    /// assert_eq!(set.pop_last(), Some(2));
1236    /// assert_eq!(set.pop_last(), Some(1));
1237    /// assert_eq!(set.pop_last(), Some(1));
1238    /// assert_eq!(set.pop_last(), None);
1239    /// ```
1240    #[inline]
1241    #[must_use = "Invalid removal should be handled"]
1242    pub fn pop_last(&mut self) -> Option<T> {
1243        let mut occupied = self.value_to_multiplicity.last_entry()?;
1244        let old_multiplicity = *occupied.get();
1245        let value = *occupied.key();
1246        match NonZeroUsize::new(old_multiplicity.get() - 1) {
1247            Some(new_multiplicity) => {
1248                *occupied.get_mut() = new_multiplicity;
1249            }
1250            None => {
1251                occupied.remove_entry();
1252            }
1253        }
1254        self.len -= 1;
1255        Some(value)
1256    }
1257
1258    /// Retains only the elements specified by the predicate.
1259    ///
1260    /// For efficiency reasons, the filtering callback `f` is not run once per
1261    /// element, but once per distinct value present inside of the multiset.
1262    /// However, it is also provided with the number of occurences of that value
1263    /// within the multiset, which can be used as a filtering criterion.
1264    ///
1265    /// In other words, this method removes all values `v` with multiplicity `m`
1266    /// for which `f(v, m)` returns `false`. The values are visited in ascending
1267    /// order.
1268    ///
1269    /// # Examples
1270    ///
1271    /// ```
1272    /// use numerical_multiset::NumericalMultiset;
1273    /// use std::num::NonZeroUsize;
1274    ///
1275    /// let mut set = NumericalMultiset::from_iter([1, 1, 2, 3, 4, 4, 5, 5, 5]);
1276    /// // Keep even values with an even multiplicity
1277    /// // and odd values with an odd multiplicity.
1278    /// set.retain(|value, multiplicity| value % 2 == multiplicity.get() % 2);
1279    ///
1280    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1281    /// assert!(set.iter().eq([
1282    ///     (3, nonzero(1)),
1283    ///     (4, nonzero(2)),
1284    ///     (5, nonzero(3)),
1285    /// ]));
1286    /// ```
1287    pub fn retain(&mut self, mut f: impl FnMut(T, NonZeroUsize) -> bool) {
1288        self.value_to_multiplicity.retain(|&k, &mut v| f(k, v));
1289        self.reset_len();
1290    }
1291
1292    /// Moves all elements from `other` into `self`, leaving `other` empty.
1293    ///
1294    /// # Examples
1295    ///
1296    /// ```
1297    /// use numerical_multiset::NumericalMultiset;
1298    /// use std::num::NonZeroUsize;
1299    ///
1300    /// let mut a = NumericalMultiset::from_iter([1, 1, 2, 3]);
1301    /// let mut b = NumericalMultiset::from_iter([3, 3, 4, 5]);
1302    ///
1303    /// a.append(&mut b);
1304    ///
1305    /// assert_eq!(a.len(), 8);
1306    /// assert!(b.is_empty());
1307    ///
1308    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1309    /// assert!(a.iter().eq([
1310    ///     (1, nonzero(2)),
1311    ///     (2, nonzero(1)),
1312    ///     (3, nonzero(3)),
1313    ///     (4, nonzero(1)),
1314    ///     (5, nonzero(1)),
1315    /// ]));
1316    /// ```
1317    pub fn append(&mut self, other: &mut Self) {
1318        // Fast path when self is empty
1319        if self.is_empty() {
1320            std::mem::swap(self, other);
1321            return;
1322        }
1323
1324        // Otherwise just insert everything into self. This is the fastest
1325        // available approach because...
1326        //
1327        // - BTreeMap::append() does not have the right semantics, if both self
1328        //   and other contain entries associated with a certain value it will
1329        //   discard the elements from self instead of adding those from others.
1330        // - BTreeMap does not externally expose a mutable iterator that allows
1331        //   for both modification of existing entries and insertions of new
1332        //   entries, which is what we would need in order to implement this
1333        //   loop more efficiently.
1334        for (value, multiplicity) in other.iter() {
1335            self.insert_multiple(value, multiplicity);
1336        }
1337        other.clear();
1338    }
1339}
1340
1341impl<T: Copy + Ord> BitAnd<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1342    type Output = NumericalMultiset<T>;
1343
1344    /// Returns the intersection of `self` and `rhs` as a new `NumericalMultiset<T>`.
1345    ///
1346    /// # Examples
1347    ///
1348    /// ```
1349    /// use numerical_multiset::NumericalMultiset;
1350    ///
1351    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1352    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1353    /// assert_eq!(
1354    ///     &a & &b,
1355    ///     NumericalMultiset::from_iter([2, 3])
1356    /// );
1357    /// ```
1358    #[must_use = "Only effect is to produce a result"]
1359    fn bitand(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1360        self.intersection(rhs).collect()
1361    }
1362}
1363
1364impl<T: Copy + Ord> BitOr<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1365    type Output = NumericalMultiset<T>;
1366
1367    /// Returns the union 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([1, 1, 2, 2, 3, 4])
1379    /// );
1380    /// ```
1381    #[must_use = "Only effect is to produce a result"]
1382    fn bitor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1383        self.union(rhs).collect()
1384    }
1385}
1386
1387impl<T: Copy + Ord> BitXor<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1388    type Output = NumericalMultiset<T>;
1389
1390    /// Returns the symmetric difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1391    ///
1392    /// # Examples
1393    ///
1394    /// ```
1395    /// use numerical_multiset::NumericalMultiset;
1396    ///
1397    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1398    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1399    /// assert_eq!(
1400    ///     &a ^ &b,
1401    ///     NumericalMultiset::from_iter([1, 1, 2, 4])
1402    /// );
1403    /// ```
1404    #[must_use = "Only effect is to produce a result"]
1405    fn bitxor(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1406        self.symmetric_difference(rhs).collect()
1407    }
1408}
1409
1410impl<T: Ord> Extend<T> for NumericalMultiset<T> {
1411    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1412        for element in iter {
1413            self.insert(element);
1414        }
1415    }
1416}
1417
1418impl<T: Ord> Extend<(T, NonZeroUsize)> for NumericalMultiset<T> {
1419    /// More efficient alternative to [`Extend<T>`] for cases where you know in
1420    /// advance that you are going to insert several copies of a value
1421    ///
1422    /// # Examples
1423    ///
1424    /// ```
1425    /// use numerical_multiset::NumericalMultiset;
1426    /// use std::num::NonZeroUsize;
1427    ///
1428    /// let mut set = NumericalMultiset::from_iter([1, 2, 3]);
1429    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1430    /// set.extend([(3, nonzero(3)), (4, nonzero(2))]);
1431    /// assert_eq!(set, NumericalMultiset::from_iter([1, 2, 3, 3, 3, 3, 4, 4]));
1432    /// ```
1433    fn extend<I: IntoIterator<Item = (T, NonZeroUsize)>>(&mut self, iter: I) {
1434        for (value, count) in iter {
1435            self.insert_multiple(value, count);
1436        }
1437    }
1438}
1439
1440impl<T: Ord> FromIterator<T> for NumericalMultiset<T> {
1441    #[must_use = "Only effect is to produce a result"]
1442    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1443        let mut result = Self::new();
1444        result.extend(iter);
1445        result
1446    }
1447}
1448
1449impl<T: Ord> FromIterator<(T, NonZeroUsize)> for NumericalMultiset<T> {
1450    /// More efficient alternative to [`FromIterator<T>`] for cases where you
1451    /// know in advance that you are going to insert several copies of a value
1452    ///
1453    /// # Examples
1454    ///
1455    /// ```
1456    /// use numerical_multiset::NumericalMultiset;
1457    /// use std::num::NonZeroUsize;
1458    ///
1459    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1460    /// assert_eq!(
1461    ///     NumericalMultiset::from_iter([1, 2, 2, 2, 3, 3]),
1462    ///     NumericalMultiset::from_iter([
1463    ///         (1, nonzero(1)),
1464    ///         (2, nonzero(3)),
1465    ///         (3, nonzero(2)),
1466    ///     ])
1467    /// );
1468    /// ```
1469    #[must_use = "Only effect is to produce a result"]
1470    fn from_iter<I: IntoIterator<Item = (T, NonZeroUsize)>>(iter: I) -> Self {
1471        let mut result = Self::new();
1472        result.extend(iter);
1473        result
1474    }
1475}
1476
1477impl<T: Hash> Hash for NumericalMultiset<T> {
1478    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1479        self.value_to_multiplicity.hash(state)
1480    }
1481}
1482
1483impl<'a, T: Copy> IntoIterator for &'a NumericalMultiset<T> {
1484    type Item = (T, NonZeroUsize);
1485    type IntoIter = Iter<'a, T>;
1486
1487    #[must_use = "Only effect is to produce a result"]
1488    fn into_iter(self) -> Self::IntoIter {
1489        Iter(self.value_to_multiplicity.iter())
1490    }
1491}
1492//
1493/// An iterator over the entries of an [`NumericalMultiset`], sorted by value.
1494///
1495/// This `struct` is created by the [`iter()`](NumericalMultiset::iter) method on
1496/// [`NumericalMultiset`]. See its documentation for more.
1497#[derive(Clone, Debug, Default)]
1498pub struct Iter<'a, T: Copy>(btree_map::Iter<'a, T, NonZeroUsize>);
1499//
1500impl<T: Copy> DoubleEndedIterator for Iter<'_, T> {
1501    #[inline]
1502    fn next_back(&mut self) -> Option<Self::Item> {
1503        self.0.next_back().map(|(&k, &v)| (k, v))
1504    }
1505
1506    #[inline]
1507    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1508        self.0.nth_back(n).map(|(&k, &v)| (k, v))
1509    }
1510}
1511//
1512impl<T: Copy> ExactSizeIterator for Iter<'_, T> {
1513    #[must_use = "Only effect is to produce a result"]
1514    fn len(&self) -> usize {
1515        self.0.len()
1516    }
1517}
1518//
1519impl<T: Copy> FusedIterator for Iter<'_, T> {}
1520//
1521impl<T: Copy> Iterator for Iter<'_, T> {
1522    type Item = (T, NonZeroUsize);
1523
1524    #[inline]
1525    fn next(&mut self) -> Option<Self::Item> {
1526        self.0.next().map(|(&k, &v)| (k, v))
1527    }
1528
1529    #[must_use = "Only effect is to produce a result"]
1530    fn size_hint(&self) -> (usize, Option<usize>) {
1531        self.0.size_hint()
1532    }
1533
1534    fn count(self) -> usize
1535    where
1536        Self: Sized,
1537    {
1538        self.0.count()
1539    }
1540
1541    fn last(self) -> Option<Self::Item>
1542    where
1543        Self: Sized,
1544    {
1545        self.0.last().map(|(&k, &v)| (k, v))
1546    }
1547
1548    #[inline]
1549    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1550        self.0.nth(n).map(|(&k, &v)| (k, v))
1551    }
1552
1553    fn is_sorted(self) -> bool
1554    where
1555        Self: Sized,
1556        Self::Item: PartialOrd,
1557    {
1558        true
1559    }
1560}
1561
1562impl<T> IntoIterator for NumericalMultiset<T> {
1563    type Item = (T, NonZeroUsize);
1564    type IntoIter = IntoIter<T>;
1565
1566    /// Gets an iterator for moving out the `NumericalMultiset`’s contents in
1567    /// ascending order.
1568    ///
1569    /// # Examples
1570    ///
1571    /// ```
1572    /// use numerical_multiset::NumericalMultiset;
1573    /// use std::num::NonZeroUsize;
1574    ///
1575    /// let set = NumericalMultiset::from_iter([3, 1, 2, 2]);
1576    /// let nonzero = |x| NonZeroUsize::new(x).unwrap();
1577    /// assert!(set.into_iter().eq([
1578    ///     (1, nonzero(1)),
1579    ///     (2, nonzero(2)),
1580    ///     (3, nonzero(1))
1581    /// ]));
1582    /// ```
1583    fn into_iter(self) -> Self::IntoIter {
1584        IntoIter(self.value_to_multiplicity.into_iter())
1585    }
1586}
1587//
1588/// An owning iterator over the entries of an [`NumericalMultiset`], sorted by
1589/// value.
1590///
1591/// This struct is created by the [`into_iter`](IntoIterator::into_iter) method
1592/// on [`NumericalMultiset`] (provided by the [`IntoIterator`] trait). See its
1593/// documentation for more.
1594#[derive(Debug, Default)]
1595pub struct IntoIter<T>(btree_map::IntoIter<T, NonZeroUsize>);
1596//
1597impl<T> DoubleEndedIterator for IntoIter<T> {
1598    #[inline]
1599    fn next_back(&mut self) -> Option<Self::Item> {
1600        self.0.next_back()
1601    }
1602
1603    #[inline]
1604    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1605        self.0.nth_back(n)
1606    }
1607}
1608//
1609impl<T> ExactSizeIterator for IntoIter<T> {
1610    #[must_use = "Only effect is to produce a result"]
1611    fn len(&self) -> usize {
1612        self.0.len()
1613    }
1614}
1615//
1616impl<T> FusedIterator for IntoIter<T> {}
1617//
1618impl<T> Iterator for IntoIter<T> {
1619    type Item = (T, NonZeroUsize);
1620
1621    #[inline]
1622    fn next(&mut self) -> Option<Self::Item> {
1623        self.0.next()
1624    }
1625
1626    #[must_use = "Only effect is to produce a result"]
1627    fn size_hint(&self) -> (usize, Option<usize>) {
1628        self.0.size_hint()
1629    }
1630
1631    fn count(self) -> usize
1632    where
1633        Self: Sized,
1634    {
1635        self.0.count()
1636    }
1637
1638    fn last(self) -> Option<Self::Item>
1639    where
1640        Self: Sized,
1641    {
1642        self.0.last()
1643    }
1644
1645    #[inline]
1646    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1647        self.0.nth(n)
1648    }
1649
1650    fn is_sorted(self) -> bool
1651    where
1652        Self: Sized,
1653        Self::Item: PartialOrd,
1654    {
1655        true
1656    }
1657}
1658
1659impl<T: Ord> Ord for NumericalMultiset<T> {
1660    #[must_use = "Only effect is to produce a result"]
1661    fn cmp(&self, other: &Self) -> Ordering {
1662        self.value_to_multiplicity.cmp(&other.value_to_multiplicity)
1663    }
1664}
1665
1666impl<T: PartialEq> PartialEq for NumericalMultiset<T> {
1667    #[must_use = "Only effect is to produce a result"]
1668    fn eq(&self, other: &Self) -> bool {
1669        self.len == other.len && self.value_to_multiplicity == other.value_to_multiplicity
1670    }
1671}
1672
1673impl<T: PartialOrd> PartialOrd for NumericalMultiset<T> {
1674    #[must_use = "Only effect is to produce a result"]
1675    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1676        self.value_to_multiplicity
1677            .partial_cmp(&other.value_to_multiplicity)
1678    }
1679}
1680
1681impl<T: Copy + Ord> Sub<&NumericalMultiset<T>> for &NumericalMultiset<T> {
1682    type Output = NumericalMultiset<T>;
1683
1684    /// Returns the difference of `self` and `rhs` as a new `NumericalMultiset<T>`.
1685    ///
1686    /// # Examples
1687    ///
1688    /// ```
1689    /// use numerical_multiset::NumericalMultiset;
1690    ///
1691    /// let a = NumericalMultiset::from_iter([1, 1, 2, 2, 3]);
1692    /// let b = NumericalMultiset::from_iter([2, 3, 4]);
1693    /// assert_eq!(
1694    ///     &a - &b,
1695    ///     NumericalMultiset::from_iter([1, 1, 2])
1696    /// );
1697    /// ```
1698    #[must_use = "Only effect is to produce a result"]
1699    fn sub(self, rhs: &NumericalMultiset<T>) -> Self::Output {
1700        self.difference(rhs).collect()
1701    }
1702}