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}