summaryrefslogtreecommitdiffstats
path: root/third_party/rust/fallible_collections/src/btree/set.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/fallible_collections/src/btree/set.rs')
-rw-r--r--third_party/rust/fallible_collections/src/btree/set.rs1346
1 files changed, 1346 insertions, 0 deletions
diff --git a/third_party/rust/fallible_collections/src/btree/set.rs b/third_party/rust/fallible_collections/src/btree/set.rs
new file mode 100644
index 0000000000..c6112ee6cd
--- /dev/null
+++ b/third_party/rust/fallible_collections/src/btree/set.rs
@@ -0,0 +1,1346 @@
+// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface
+// to TreeMap
+
+use crate::TryReserveError;
+use core::borrow::Borrow;
+use core::cmp::max;
+use core::cmp::Ordering::{self, Equal, Greater, Less};
+use core::fmt::{self, Debug};
+use core::iter::{FromIterator, FusedIterator, Peekable};
+use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
+
+use super::map::{self, BTreeMap, Keys};
+use super::Recover;
+
+// FIXME(conventions): implement bounded iterators
+
+/// A set based on a B-Tree.
+///
+/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
+/// benefits and drawbacks.
+///
+/// It is a logic error for an item to be modified in such a way that the item's ordering relative
+/// to any other item, as determined by the [`Ord`] trait, changes while it is in the set. This is
+/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
+///
+/// [`BTreeMap`]: struct.BTreeMap.html
+/// [`Ord`]: ../../std/cmp/trait.Ord.html
+/// [`Cell`]: ../../std/cell/struct.Cell.html
+/// [`RefCell`]: ../../std/cell/struct.RefCell.html
+///
+/// # Examples
+///
+/// ```
+/// use std::collections::BTreeSet;
+///
+/// // Type inference lets us omit an explicit type signature (which
+/// // would be `BTreeSet<&str>` in this example).
+/// let mut books = BTreeSet::new();
+///
+/// // Add some books.
+/// books.insert("A Dance With Dragons");
+/// books.insert("To Kill a Mockingbird");
+/// books.insert("The Odyssey");
+/// books.insert("The Great Gatsby");
+///
+/// // Check for a specific one.
+/// if !books.contains("The Winds of Winter") {
+/// println!("We have {} books, but The Winds of Winter ain't one.",
+/// books.len());
+/// }
+///
+/// // Remove a book.
+/// books.remove("The Odyssey");
+///
+/// // Iterate over everything.
+/// for book in &books {
+/// println!("{}", book);
+/// }
+/// ```
+#[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
+
+pub struct BTreeSet<T> {
+ map: BTreeMap<T, ()>,
+}
+
+/// An iterator over the items of a `BTreeSet`.
+///
+/// This `struct` is created by the [`iter`] method on [`BTreeSet`].
+/// See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`iter`]: struct.BTreeSet.html#method.iter
+
+pub struct Iter<'a, T: 'a> {
+ iter: Keys<'a, T, ()>,
+}
+
+impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("Iter").field(&self.iter.clone()).finish()
+ }
+}
+
+/// An owning iterator over the items of a `BTreeSet`.
+///
+/// This `struct` is created by the [`into_iter`] method on [`BTreeSet`][`BTreeSet`]
+/// (provided by the `IntoIterator` trait). See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`into_iter`]: struct.BTreeSet.html#method.into_iter
+
+#[derive(Debug)]
+pub struct IntoIter<T> {
+ iter: map::IntoIter<T, ()>,
+}
+
+/// An iterator over a sub-range of items in a `BTreeSet`.
+///
+/// This `struct` is created by the [`range`] method on [`BTreeSet`].
+/// See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`range`]: struct.BTreeSet.html#method.range
+#[derive(Debug)]
+
+pub struct Range<'a, T: 'a> {
+ iter: map::Range<'a, T, ()>,
+}
+
+/// A lazy iterator producing elements in the difference of `BTreeSet`s.
+///
+/// This `struct` is created by the [`difference`] method on [`BTreeSet`].
+/// See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`difference`]: struct.BTreeSet.html#method.difference
+
+pub struct Difference<'a, T: 'a> {
+ inner: DifferenceInner<'a, T>,
+}
+enum DifferenceInner<'a, T: 'a> {
+ Stitch {
+ self_iter: Iter<'a, T>,
+ other_iter: Peekable<Iter<'a, T>>,
+ },
+ Search {
+ self_iter: Iter<'a, T>,
+ other_set: &'a BTreeSet<T>,
+ },
+}
+
+impl<T: fmt::Debug> fmt::Debug for Difference<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match &self.inner {
+ DifferenceInner::Stitch {
+ self_iter,
+ other_iter,
+ } => f
+ .debug_tuple("Difference")
+ .field(&self_iter)
+ .field(&other_iter)
+ .finish(),
+ DifferenceInner::Search {
+ self_iter,
+ other_set: _,
+ } => f.debug_tuple("Difference").field(&self_iter).finish(),
+ }
+ }
+}
+
+/// A lazy iterator producing elements in the symmetric difference of `BTreeSet`s.
+///
+/// This `struct` is created by the [`symmetric_difference`] method on
+/// [`BTreeSet`]. See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`symmetric_difference`]: struct.BTreeSet.html#method.symmetric_difference
+
+pub struct SymmetricDifference<'a, T: 'a> {
+ a: Peekable<Iter<'a, T>>,
+ b: Peekable<Iter<'a, T>>,
+}
+
+impl<T: fmt::Debug> fmt::Debug for SymmetricDifference<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("SymmetricDifference")
+ .field(&self.a)
+ .field(&self.b)
+ .finish()
+ }
+}
+
+/// A lazy iterator producing elements in the intersection of `BTreeSet`s.
+///
+/// This `struct` is created by the [`intersection`] method on [`BTreeSet`].
+/// See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`intersection`]: struct.BTreeSet.html#method.intersection
+
+pub struct Intersection<'a, T: 'a> {
+ inner: IntersectionInner<'a, T>,
+}
+enum IntersectionInner<'a, T: 'a> {
+ Stitch {
+ small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets
+ other_iter: Iter<'a, T>,
+ },
+ Search {
+ small_iter: Iter<'a, T>,
+ large_set: &'a BTreeSet<T>,
+ },
+}
+
+impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match &self.inner {
+ IntersectionInner::Stitch {
+ small_iter,
+ other_iter,
+ } => f
+ .debug_tuple("Intersection")
+ .field(&small_iter)
+ .field(&other_iter)
+ .finish(),
+ IntersectionInner::Search {
+ small_iter,
+ large_set: _,
+ } => f.debug_tuple("Intersection").field(&small_iter).finish(),
+ }
+ }
+}
+
+/// A lazy iterator producing elements in the union of `BTreeSet`s.
+///
+/// This `struct` is created by the [`union`] method on [`BTreeSet`].
+/// See its documentation for more.
+///
+/// [`BTreeSet`]: struct.BTreeSet.html
+/// [`union`]: struct.BTreeSet.html#method.union
+
+pub struct Union<'a, T: 'a> {
+ a: Peekable<Iter<'a, T>>,
+ b: Peekable<Iter<'a, T>>,
+}
+
+impl<T: fmt::Debug> fmt::Debug for Union<'_, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("Union")
+ .field(&self.a)
+ .field(&self.b)
+ .finish()
+ }
+}
+
+// This constant is used by functions that compare two sets.
+// It estimates the relative size at which searching performs better
+// than iterating, based on the benchmarks in
+// https://github.com/ssomers/rust_bench_btreeset_intersection;
+// It's used to divide rather than multiply sizes, to rule out overflow,
+// and it's a power of two to make that division cheap.
+const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16;
+
+impl<T: Ord> BTreeSet<T> {
+ /// Makes a new `BTreeSet` with a reasonable choice of B.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # #![allow(unused_mut)]
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set: BTreeSet<i32> = BTreeSet::new();
+ /// ```
+
+ #[inline]
+ pub fn new() -> BTreeSet<T> {
+ BTreeSet {
+ map: BTreeMap::new(),
+ }
+ }
+
+ /// Constructs a double-ended iterator over a sub-range of elements in the set.
+ /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will
+ /// yield elements from min (inclusive) to max (exclusive).
+ /// The range may also be entered as `(Bound<T>, Bound<T>)`, so for example
+ /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
+ /// range from 4 to 10.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ /// use std::ops::Bound::Included;
+ ///
+ /// let mut set = BTreeSet::new();
+ /// set.insert(3);
+ /// set.insert(5);
+ /// set.insert(8);
+ /// for &elem in set.range((Included(&4), Included(&8))) {
+ /// println!("{}", elem);
+ /// }
+ /// assert_eq!(Some(&5), set.range(4..).next());
+ /// ```
+
+ #[inline]
+ pub fn range<K: ?Sized, R>(&self, range: R) -> Range<'_, T>
+ where
+ K: Ord,
+ T: Borrow<K>,
+ R: RangeBounds<K>,
+ {
+ Range {
+ iter: self.map.range(range),
+ }
+ }
+
+ /// Visits the values representing the difference,
+ /// i.e., the values that are in `self` but not in `other`,
+ /// in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ ///
+ /// let mut b = BTreeSet::new();
+ /// b.insert(2);
+ /// b.insert(3);
+ ///
+ /// let diff: Vec<_> = a.difference(&b).cloned().collect();
+ /// assert_eq!(diff, [1]);
+ /// ```
+
+ pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> {
+ if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+ // Self is bigger than or not much smaller than other set.
+ // Iterate both sets jointly, spotting matches along the way.
+ Difference {
+ inner: DifferenceInner::Stitch {
+ self_iter: self.iter(),
+ other_iter: other.iter().peekable(),
+ },
+ }
+ } else {
+ // Self is much smaller than other set, or both sets are empty.
+ // Iterate the small set, searching for matches in the large set.
+ Difference {
+ inner: DifferenceInner::Search {
+ self_iter: self.iter(),
+ other_set: other,
+ },
+ }
+ }
+ }
+
+ /// Visits the values representing the symmetric difference,
+ /// i.e., the values that are in `self` or in `other` but not in both,
+ /// in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ ///
+ /// let mut b = BTreeSet::new();
+ /// b.insert(2);
+ /// b.insert(3);
+ ///
+ /// let sym_diff: Vec<_> = a.symmetric_difference(&b).cloned().collect();
+ /// assert_eq!(sym_diff, [1, 3]);
+ /// ```
+
+ #[inline]
+ pub fn symmetric_difference<'a>(
+ &'a self,
+ other: &'a BTreeSet<T>,
+ ) -> SymmetricDifference<'a, T> {
+ SymmetricDifference {
+ a: self.iter().peekable(),
+ b: other.iter().peekable(),
+ }
+ }
+
+ /// Visits the values representing the intersection,
+ /// i.e., the values that are both in `self` and `other`,
+ /// in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ ///
+ /// let mut b = BTreeSet::new();
+ /// b.insert(2);
+ /// b.insert(3);
+ ///
+ /// let intersection: Vec<_> = a.intersection(&b).cloned().collect();
+ /// assert_eq!(intersection, [2]);
+ /// ```
+
+ pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>) -> Intersection<'a, T> {
+ let (small, other) = if self.len() <= other.len() {
+ (self, other)
+ } else {
+ (other, self)
+ };
+ if small.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+ // Small set is not much smaller than other set.
+ // Iterate both sets jointly, spotting matches along the way.
+ Intersection {
+ inner: IntersectionInner::Stitch {
+ small_iter: small.iter(),
+ other_iter: other.iter(),
+ },
+ }
+ } else {
+ // Big difference in number of elements, or both sets are empty.
+ // Iterate the small set, searching for matches in the large set.
+ Intersection {
+ inner: IntersectionInner::Search {
+ small_iter: small.iter(),
+ large_set: other,
+ },
+ }
+ }
+ }
+
+ /// Visits the values representing the union,
+ /// i.e., all the values in `self` or `other`, without duplicates,
+ /// in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ ///
+ /// let mut b = BTreeSet::new();
+ /// b.insert(2);
+ ///
+ /// let union: Vec<_> = a.union(&b).cloned().collect();
+ /// assert_eq!(union, [1, 2]);
+ /// ```
+
+ #[inline]
+ pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> Union<'a, T> {
+ Union {
+ a: self.iter().peekable(),
+ b: other.iter().peekable(),
+ }
+ }
+
+ /// Clears the set, removing all values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut v = BTreeSet::new();
+ /// v.insert(1);
+ /// v.clear();
+ /// assert!(v.is_empty());
+ /// ```
+
+ #[inline(always)]
+ pub fn clear(&mut self) {
+ self.map.clear()
+ }
+
+ /// Returns `true` if the set contains a value.
+ ///
+ /// The value may be any borrowed form of the set's value type,
+ /// but the ordering on the borrowed form *must* match the
+ /// ordering on the value type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert_eq!(set.contains(&1), true);
+ /// assert_eq!(set.contains(&4), false);
+ /// ```
+
+ #[inline(always)]
+ pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
+ where
+ T: Borrow<Q>,
+ Q: Ord,
+ {
+ self.map.contains_key(value)
+ }
+
+ /// Returns a reference to the value in the set, if any, that is equal to the given value.
+ ///
+ /// The value may be any borrowed form of the set's value type,
+ /// but the ordering on the borrowed form *must* match the
+ /// ordering on the value type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert_eq!(set.get(&2), Some(&2));
+ /// assert_eq!(set.get(&4), None);
+ /// ```
+
+ #[inline(always)]
+ pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
+ where
+ T: Borrow<Q>,
+ Q: Ord,
+ {
+ Recover::get(&self.map, value)
+ }
+
+ /// Returns `true` if `self` has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let a: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let mut b = BTreeSet::new();
+ ///
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(4);
+ /// assert_eq!(a.is_disjoint(&b), true);
+ /// b.insert(1);
+ /// assert_eq!(a.is_disjoint(&b), false);
+ /// ```
+
+ #[inline]
+ pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool {
+ self.intersection(other).next().is_none()
+ }
+
+ /// Returns `true` if the set is a subset of another,
+ /// i.e., `other` contains at least all the values in `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let sup: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// let mut set = BTreeSet::new();
+ ///
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(2);
+ /// assert_eq!(set.is_subset(&sup), true);
+ /// set.insert(4);
+ /// assert_eq!(set.is_subset(&sup), false);
+ /// ```
+
+ pub fn is_subset(&self, other: &BTreeSet<T>) -> bool {
+ // Same result as self.difference(other).next().is_none()
+ // but the 3 paths below are faster (in order: hugely, 20%, 5%).
+ if self.len() > other.len() {
+ false
+ } else if self.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
+ // Self is not much smaller than other set.
+ // Stolen from TreeMap
+ let mut x = self.iter();
+ let mut y = other.iter();
+ let mut a = x.next();
+ let mut b = y.next();
+ while a.is_some() {
+ if b.is_none() {
+ return false;
+ }
+
+ let a1 = a.unwrap();
+ let b1 = b.unwrap();
+
+ match b1.cmp(a1) {
+ Less => (),
+ Greater => return false,
+ Equal => a = x.next(),
+ }
+
+ b = y.next();
+ }
+ true
+ } else {
+ // Big difference in number of elements, or both sets are empty.
+ // Iterate the small set, searching for matches in the large set.
+ for next in self {
+ if !other.contains(next) {
+ return false;
+ }
+ }
+ true
+ }
+ }
+
+ /// Returns `true` if the set is a superset of another,
+ /// i.e., `self` contains at least all the values in `other`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let sub: BTreeSet<_> = [1, 2].iter().cloned().collect();
+ /// let mut set = BTreeSet::new();
+ ///
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(0);
+ /// set.insert(1);
+ /// assert_eq!(set.is_superset(&sub), false);
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.is_superset(&sub), true);
+ /// ```
+
+ #[inline(always)]
+ pub fn is_superset(&self, other: &BTreeSet<T>) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Adds a value to the set.
+ ///
+ /// If the set did not have this value present, `true` is returned.
+ ///
+ /// If the set did have this value present, `false` is returned, and the
+ /// entry is not updated. See the [module-level documentation] for more.
+ ///
+ /// [module-level documentation]: index.html#insert-and-complex-keys
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set = BTreeSet::new();
+ ///
+ /// assert_eq!(set.insert(2), true);
+ /// assert_eq!(set.insert(2), false);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+
+ #[inline]
+ pub fn try_insert(&mut self, value: T) -> Result<bool, TryReserveError> {
+ Ok(self.map.try_insert(value, ())?.is_none())
+ }
+
+ /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
+ /// one. Returns the replaced value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set = BTreeSet::new();
+ /// set.insert(Vec::<i32>::new());
+ ///
+ /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 0);
+ /// set.replace(Vec::with_capacity(10));
+ /// assert_eq!(set.get(&[][..]).unwrap().capacity(), 10);
+ /// ```
+
+ #[inline]
+ pub fn replace(&mut self, value: T) -> Result<Option<T>, TryReserveError> {
+ Ok(Recover::replace(&mut self.map, value)?)
+ }
+
+ /// Removes a value from the set. Returns whether the value was
+ /// present in the set.
+ ///
+ /// The value may be any borrowed form of the set's value type,
+ /// but the ordering on the borrowed form *must* match the
+ /// ordering on the value type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set = BTreeSet::new();
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.remove(&2), true);
+ /// assert_eq!(set.remove(&2), false);
+ /// ```
+
+ #[inline(always)]
+ pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
+ where
+ T: Borrow<Q>,
+ Q: Ord,
+ {
+ self.map.remove(value).is_some()
+ }
+
+ /// Removes and returns the value in the set, if any, that is equal to the given one.
+ ///
+ /// The value may be any borrowed form of the set's value type,
+ /// but the ordering on the borrowed form *must* match the
+ /// ordering on the value type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert_eq!(set.take(&2), Some(2));
+ /// assert_eq!(set.take(&2), None);
+ /// ```
+
+ #[inline(always)]
+ pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
+ where
+ T: Borrow<Q>,
+ Q: Ord,
+ {
+ Recover::take(&mut self.map, value)
+ }
+
+ /// Moves all elements from `other` into `Self`, leaving `other` empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ /// a.insert(3);
+ ///
+ /// let mut b = BTreeSet::new();
+ /// b.insert(3);
+ /// b.insert(4);
+ /// b.insert(5);
+ ///
+ /// a.append(&mut b);
+ ///
+ /// assert_eq!(a.len(), 5);
+ /// assert_eq!(b.len(), 0);
+ ///
+ /// assert!(a.contains(&1));
+ /// assert!(a.contains(&2));
+ /// assert!(a.contains(&3));
+ /// assert!(a.contains(&4));
+ /// assert!(a.contains(&5));
+ /// ```
+
+ #[inline(always)]
+ pub fn append(&mut self, other: &mut Self) {
+ self.map.append(&mut other.map);
+ }
+
+ /// Splits the collection into two at the given key. Returns everything after the given key,
+ /// including the key.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut a = BTreeSet::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ /// a.insert(3);
+ /// a.insert(17);
+ /// a.insert(41);
+ ///
+ /// let b = a.split_off(&3);
+ ///
+ /// assert_eq!(a.len(), 2);
+ /// assert_eq!(b.len(), 3);
+ ///
+ /// assert!(a.contains(&1));
+ /// assert!(a.contains(&2));
+ ///
+ /// assert!(b.contains(&3));
+ /// assert!(b.contains(&17));
+ /// assert!(b.contains(&41));
+ /// ```
+
+ #[inline]
+ pub fn try_split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Result<Self, TryReserveError>
+ where
+ T: Borrow<Q>,
+ {
+ Ok(BTreeSet {
+ map: self.map.split_off(key)?,
+ })
+ }
+}
+
+impl<T> BTreeSet<T> {
+ /// Gets an iterator that visits the values in the `BTreeSet` in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let set: BTreeSet<usize> = [1, 2, 3].iter().cloned().collect();
+ /// let mut set_iter = set.iter();
+ /// assert_eq!(set_iter.next(), Some(&1));
+ /// assert_eq!(set_iter.next(), Some(&2));
+ /// assert_eq!(set_iter.next(), Some(&3));
+ /// assert_eq!(set_iter.next(), None);
+ /// ```
+ ///
+ /// Values returned by the iterator are returned in ascending order:
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let set: BTreeSet<usize> = [3, 1, 2].iter().cloned().collect();
+ /// let mut set_iter = set.iter();
+ /// assert_eq!(set_iter.next(), Some(&1));
+ /// assert_eq!(set_iter.next(), Some(&2));
+ /// assert_eq!(set_iter.next(), Some(&3));
+ /// assert_eq!(set_iter.next(), None);
+ /// ```
+
+ #[inline(always)]
+ pub fn iter(&self) -> Iter<'_, T> {
+ Iter {
+ iter: self.map.keys(),
+ }
+ }
+
+ /// Returns the number of elements in the set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut v = BTreeSet::new();
+ /// assert_eq!(v.len(), 0);
+ /// v.insert(1);
+ /// assert_eq!(v.len(), 1);
+ /// ```
+
+ #[inline(always)]
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns `true` if the set contains no elements.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let mut v = BTreeSet::new();
+ /// assert!(v.is_empty());
+ /// v.insert(1);
+ /// assert!(!v.is_empty());
+ /// ```
+
+ #[inline(always)]
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl<T: Ord> FromIterator<T> for BTreeSet<T> {
+ #[inline]
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> BTreeSet<T> {
+ let mut set = BTreeSet::new();
+ set.extend(iter);
+ set
+ }
+}
+
+impl<T> IntoIterator for BTreeSet<T> {
+ type Item = T;
+ type IntoIter = IntoIter<T>;
+
+ /// Gets an iterator for moving out the `BTreeSet`'s contents.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
+ ///
+ /// let v: Vec<_> = set.into_iter().collect();
+ /// assert_eq!(v, [1, 2, 3, 4]);
+ /// ```
+ #[inline(always)]
+ fn into_iter(self) -> IntoIter<T> {
+ IntoIter {
+ iter: self.map.into_iter(),
+ }
+ }
+}
+
+impl<'a, T> IntoIterator for &'a BTreeSet<T> {
+ type Item = &'a T;
+ type IntoIter = Iter<'a, T>;
+
+ #[inline(always)]
+ fn into_iter(self) -> Iter<'a, T> {
+ self.iter()
+ }
+}
+
+impl<T: Ord> Extend<T> for BTreeSet<T> {
+ #[inline]
+ fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
+ iter.into_iter().for_each(move |elem| {
+ self.try_insert(elem).expect("Out of Mem");
+ });
+ }
+}
+
+impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BTreeSet<T> {
+ #[inline]
+ fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
+ self.extend(iter.into_iter().cloned());
+ }
+}
+
+impl<T: Ord> Default for BTreeSet<T> {
+ /// Makes an empty `BTreeSet<T>` with a reasonable choice of B.
+ #[inline(always)]
+ fn default() -> BTreeSet<T> {
+ BTreeSet::new()
+ }
+}
+
+impl<T: Ord + Clone> Sub<&BTreeSet<T>> for &BTreeSet<T> {
+ type Output = BTreeSet<T>;
+
+ /// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
+ /// let b: BTreeSet<_> = vec![3, 4, 5].into_iter().collect();
+ ///
+ /// let result = &a - &b;
+ /// let result_vec: Vec<_> = result.into_iter().collect();
+ /// assert_eq!(result_vec, [1, 2]);
+ /// ```
+ fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
+ self.difference(rhs).cloned().collect()
+ }
+}
+
+impl<T: Ord + Clone> BitXor<&BTreeSet<T>> for &BTreeSet<T> {
+ type Output = BTreeSet<T>;
+
+ /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
+ /// let b: BTreeSet<_> = vec![2, 3, 4].into_iter().collect();
+ ///
+ /// let result = &a ^ &b;
+ /// let result_vec: Vec<_> = result.into_iter().collect();
+ /// assert_eq!(result_vec, [1, 4]);
+ /// ```
+ fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
+ self.symmetric_difference(rhs).cloned().collect()
+ }
+}
+
+impl<T: Ord + Clone> BitAnd<&BTreeSet<T>> for &BTreeSet<T> {
+ type Output = BTreeSet<T>;
+
+ /// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
+ /// let b: BTreeSet<_> = vec![2, 3, 4].into_iter().collect();
+ ///
+ /// let result = &a & &b;
+ /// let result_vec: Vec<_> = result.into_iter().collect();
+ /// assert_eq!(result_vec, [2, 3]);
+ /// ```
+ fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
+ self.intersection(rhs).cloned().collect()
+ }
+}
+
+impl<T: Ord + Clone> BitOr<&BTreeSet<T>> for &BTreeSet<T> {
+ type Output = BTreeSet<T>;
+
+ /// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::BTreeSet;
+ ///
+ /// let a: BTreeSet<_> = vec![1, 2, 3].into_iter().collect();
+ /// let b: BTreeSet<_> = vec![3, 4, 5].into_iter().collect();
+ ///
+ /// let result = &a | &b;
+ /// let result_vec: Vec<_> = result.into_iter().collect();
+ /// assert_eq!(result_vec, [1, 2, 3, 4, 5]);
+ /// ```
+ fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
+ self.union(rhs).cloned().collect()
+ }
+}
+
+impl<T: Debug> Debug for BTreeSet<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_set().entries(self.iter()).finish()
+ }
+}
+
+impl<T> Clone for Iter<'_, T> {
+ #[inline(always)]
+ fn clone(&self) -> Self {
+ Iter {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+
+ #[inline(always)]
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next()
+ }
+
+ #[inline(always)]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+ #[inline(always)]
+ fn next_back(&mut self) -> Option<&'a T> {
+ self.iter.next_back()
+ }
+}
+
+impl<T> ExactSizeIterator for Iter<'_, T> {
+ #[inline(always)]
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+}
+
+impl<T> FusedIterator for Iter<'_, T> {}
+
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
+
+ #[inline]
+ fn next(&mut self) -> Option<T> {
+ self.iter.next().map(|(k, _)| k)
+ }
+
+ #[inline(always)]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<T> {
+ self.iter.next_back().map(|(k, _)| k)
+ }
+}
+
+impl<T> ExactSizeIterator for IntoIter<T> {
+ #[inline(always)]
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+}
+
+impl<T> FusedIterator for IntoIter<T> {}
+
+impl<T> Clone for Range<'_, T> {
+ #[inline(always)]
+ fn clone(&self) -> Self {
+ Range {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, T> Iterator for Range<'a, T> {
+ type Item = &'a T;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next().map(|(k, _)| k)
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Range<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a T> {
+ self.iter.next_back().map(|(k, _)| k)
+ }
+}
+
+impl<T> FusedIterator for Range<'_, T> {}
+
+/// Compares `x` and `y`, but return `short` if x is None and `long` if y is None
+fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering {
+ match (x, y) {
+ (None, _) => short,
+ (_, None) => long,
+ (Some(x1), Some(y1)) => x1.cmp(y1),
+ }
+}
+
+impl<T> Clone for Difference<'_, T> {
+ fn clone(&self) -> Self {
+ Difference {
+ inner: match &self.inner {
+ DifferenceInner::Stitch {
+ self_iter,
+ other_iter,
+ } => DifferenceInner::Stitch {
+ self_iter: self_iter.clone(),
+ other_iter: other_iter.clone(),
+ },
+ DifferenceInner::Search {
+ self_iter,
+ other_set,
+ } => DifferenceInner::Search {
+ self_iter: self_iter.clone(),
+ other_set,
+ },
+ },
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator for Difference<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<&'a T> {
+ match &mut self.inner {
+ DifferenceInner::Stitch {
+ self_iter,
+ other_iter,
+ } => {
+ let mut self_next = self_iter.next()?;
+ loop {
+ match other_iter
+ .peek()
+ .map_or(Less, |other_next| Ord::cmp(self_next, other_next))
+ {
+ Less => return Some(self_next),
+ Equal => {
+ self_next = self_iter.next()?;
+ other_iter.next();
+ }
+ Greater => {
+ other_iter.next();
+ }
+ }
+ }
+ }
+ DifferenceInner::Search {
+ self_iter,
+ other_set,
+ } => loop {
+ let self_next = self_iter.next()?;
+ if !other_set.contains(&self_next) {
+ return Some(self_next);
+ }
+ },
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (self_len, other_len) = match &self.inner {
+ DifferenceInner::Stitch {
+ self_iter,
+ other_iter,
+ } => (self_iter.len(), other_iter.len()),
+ DifferenceInner::Search {
+ self_iter,
+ other_set,
+ } => (self_iter.len(), other_set.len()),
+ };
+ (self_len.saturating_sub(other_len), Some(self_len))
+ }
+}
+
+impl<T: Ord> FusedIterator for Difference<'_, T> {}
+
+impl<T> Clone for SymmetricDifference<'_, T> {
+ fn clone(&self) -> Self {
+ SymmetricDifference {
+ a: self.a.clone(),
+ b: self.b.clone(),
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<&'a T> {
+ loop {
+ match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
+ Less => return self.a.next(),
+ Equal => {
+ self.a.next();
+ self.b.next();
+ }
+ Greater => return self.b.next(),
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, Some(self.a.len() + self.b.len()))
+ }
+}
+
+impl<T: Ord> FusedIterator for SymmetricDifference<'_, T> {}
+
+impl<T> Clone for Intersection<'_, T> {
+ fn clone(&self) -> Self {
+ Intersection {
+ inner: match &self.inner {
+ IntersectionInner::Stitch {
+ small_iter,
+ other_iter,
+ } => IntersectionInner::Stitch {
+ small_iter: small_iter.clone(),
+ other_iter: other_iter.clone(),
+ },
+ IntersectionInner::Search {
+ small_iter,
+ large_set,
+ } => IntersectionInner::Search {
+ small_iter: small_iter.clone(),
+ large_set,
+ },
+ },
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator for Intersection<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<&'a T> {
+ match &mut self.inner {
+ IntersectionInner::Stitch {
+ small_iter,
+ other_iter,
+ } => {
+ let mut small_next = small_iter.next()?;
+ let mut other_next = other_iter.next()?;
+ loop {
+ match Ord::cmp(small_next, other_next) {
+ Less => small_next = small_iter.next()?,
+ Greater => other_next = other_iter.next()?,
+ Equal => return Some(small_next),
+ }
+ }
+ }
+ IntersectionInner::Search {
+ small_iter,
+ large_set,
+ } => loop {
+ let small_next = small_iter.next()?;
+ if large_set.contains(&small_next) {
+ return Some(small_next);
+ }
+ },
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let min_len = match &self.inner {
+ IntersectionInner::Stitch { small_iter, .. } => small_iter.len(),
+ IntersectionInner::Search { small_iter, .. } => small_iter.len(),
+ };
+ (0, Some(min_len))
+ }
+}
+
+impl<T: Ord> FusedIterator for Intersection<'_, T> {}
+
+impl<T> Clone for Union<'_, T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Union {
+ a: self.a.clone(),
+ b: self.b.clone(),
+ }
+ }
+}
+
+impl<'a, T: Ord> Iterator for Union<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<&'a T> {
+ match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
+ Less => self.a.next(),
+ Equal => {
+ self.b.next();
+ self.a.next()
+ }
+ Greater => self.b.next(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let a_len = self.a.len();
+ let b_len = self.b.len();
+ (max(a_len, b_len), Some(a_len + b_len))
+ }
+}
+
+impl<T: Ord> FusedIterator for Union<'_, T> {}