// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface // to TreeMap
usecrate::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};
/// 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)]
pubstruct 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
/// 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
/// 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)]
/// 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
/// 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
/// 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
pubstruct 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>,
},
}
/// 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
// 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(); /// ```
/// 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()); /// ```
/// 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]); /// ```
pubfn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> { ifself.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]); /// ```
/// 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]); /// ```
pubfn intersection<'a>(&'a self, other: &'a BTreeSet<T>) -> Intersection<'a, T> { let (small, other) = ifself.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]); /// ```
/// 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); /// ```
/// 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); /// ```
/// 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); /// ```
/// 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); /// ```
pubfn 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%). ifself.len() > other.len() { false
} elseifself.len() > other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF { // Self is not much smaller than other set. // Stolen from TreeMap letmut x = self.iter(); letmut y = other.iter(); letmut a = x.next(); letmut b = y.next(); while a.is_some() { if b.is_none() { returnfalse;
}
let a1 = a.unwrap(); let b1 = b.unwrap();
match b1.cmp(a1) {
Less => (),
Greater => returnfalse,
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 inself { if !other.contains(next) { returnfalse;
}
} 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); /// ```
/// 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); /// ```
/// 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); /// ```
/// 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); /// ```
/// 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); /// ```
/// 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)); /// ```
/// 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); /// ```
/// 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()); /// ```
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()
}
}
/// 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),
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.