// 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 { map: BTreeMap, } /// 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 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 { iter: map::IntoIter, } /// 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>, }, Search { self_iter: Iter<'a, T>, other_set: &'a BTreeSet, }, } impl 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>, b: Peekable>, } impl 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, }, } impl 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>, b: Peekable>, } impl 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 BTreeSet { /// Makes a new `BTreeSet` with a reasonable choice of B. /// /// # Examples /// /// ``` /// # #![allow(unused_mut)] /// use std::collections::BTreeSet; /// /// let mut set: BTreeSet = BTreeSet::new(); /// ``` #[inline] pub fn new() -> BTreeSet { 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, Bound)`, 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(&self, range: R) -> Range<'_, T> where K: Ord, T: Borrow, R: RangeBounds, { 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) -> 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, ) -> 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) -> 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) -> 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(&self, value: &Q) -> bool where T: Borrow, 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(&self, value: &Q) -> Option<&T> where T: Borrow, 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) -> 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) -> 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) -> 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 { 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::::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, 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(&mut self, value: &Q) -> bool where T: Borrow, 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(&mut self, value: &Q) -> Option where T: Borrow, 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(&mut self, key: &Q) -> Result where T: Borrow, { Ok(BTreeSet { map: self.map.split_off(key)?, }) } } impl BTreeSet { /// Gets an iterator that visits the values in the `BTreeSet` in ascending order. /// /// # Examples /// /// ``` /// use std::collections::BTreeSet; /// /// let set: BTreeSet = [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 = [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 FromIterator for BTreeSet { #[inline] fn from_iter>(iter: I) -> BTreeSet { let mut set = BTreeSet::new(); set.extend(iter); set } } impl IntoIterator for BTreeSet { type Item = T; type IntoIter = IntoIter; /// Gets an iterator for moving out the `BTreeSet`'s contents. /// /// # Examples /// /// ``` /// use std::collections::BTreeSet; /// /// let set: BTreeSet = [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 { IntoIter { iter: self.map.into_iter(), } } } impl<'a, T> IntoIterator for &'a BTreeSet { type Item = &'a T; type IntoIter = Iter<'a, T>; #[inline(always)] fn into_iter(self) -> Iter<'a, T> { self.iter() } } impl Extend for BTreeSet { #[inline] fn extend>(&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 { #[inline] fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } } impl Default for BTreeSet { /// Makes an empty `BTreeSet` with a reasonable choice of B. #[inline(always)] fn default() -> BTreeSet { BTreeSet::new() } } impl Sub<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the difference of `self` and `rhs` as a new `BTreeSet`. /// /// # 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) -> BTreeSet { self.difference(rhs).cloned().collect() } } impl BitXor<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet`. /// /// # 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) -> BTreeSet { self.symmetric_difference(rhs).cloned().collect() } } impl BitAnd<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the intersection of `self` and `rhs` as a new `BTreeSet`. /// /// # 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) -> BTreeSet { self.intersection(rhs).cloned().collect() } } impl BitOr<&BTreeSet> for &BTreeSet { type Output = BTreeSet; /// Returns the union of `self` and `rhs` as a new `BTreeSet`. /// /// # 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) -> BTreeSet { self.union(rhs).cloned().collect() } } impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() } } impl 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) { 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 ExactSizeIterator for Iter<'_, T> { #[inline(always)] fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for Iter<'_, T> {} impl Iterator for IntoIter { type Item = T; #[inline] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } #[inline(always)] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|(k, _)| k) } } impl ExactSizeIterator for IntoIter { #[inline(always)] fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for IntoIter {} impl 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 FusedIterator for Range<'_, T> {} /// Compares `x` and `y`, but return `short` if x is None and `long` if y is None fn cmp_opt(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 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) { 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 FusedIterator for Difference<'_, T> {} impl 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) { (0, Some(self.a.len() + self.b.len())) } } impl FusedIterator for SymmetricDifference<'_, T> {} impl 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) { 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 FusedIterator for Intersection<'_, T> {} impl 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) { let a_len = self.a.len(); let b_len = self.b.len(); (max(a_len, b_len), Some(a_len + b_len)) } } impl FusedIterator for Union<'_, T> {}