use core::borrow::Borrow;
use core::cmp::Ordering::{self, Equal, Greater, Less};
use core::cmp::{max, min};
use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::{FusedIterator, Peekable};
use core::ops::RangeBounds;
use super::map::{infallible_cmp, into_ok, BTreeMap, CmpFn, Keys};
use super::merge_iter::MergeIterInner;
use super::set_val::SetValZST;
use super::Recover;
use crate::alloc::{AllocError, Allocator, Global};
use crate::clone::TryClone;
use crate::error::Error;
use crate::iter::{TryExtend, TryFromIteratorIn};
#[cfg(test)]
use crate::testing::*;
pub struct BTreeSet<T, A: Allocator = Global> {
map: BTreeMap<T, SetValZST, A>,
}
impl<T: Hash, A: Allocator> Hash for BTreeSet<T, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.map.hash(state)
}
}
impl<T: PartialEq, A: Allocator> PartialEq for BTreeSet<T, A> {
fn eq(&self, other: &BTreeSet<T, A>) -> bool {
self.map.eq(&other.map)
}
}
impl<T: Eq, A: Allocator> Eq for BTreeSet<T, A> {}
impl<T: PartialOrd, A: Allocator> PartialOrd for BTreeSet<T, A> {
fn partial_cmp(&self, other: &BTreeSet<T, A>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T: Ord, A: Allocator> Ord for BTreeSet<T, A> {
fn cmp(&self, other: &BTreeSet<T, A>) -> Ordering {
self.map.cmp(&other.map)
}
}
impl<T, A: Allocator + Clone> TryClone for BTreeSet<T, A>
where
T: TryClone,
{
fn try_clone(&self) -> Result<Self, Error> {
Ok(BTreeSet {
map: self.map.try_clone()?,
})
}
}
#[cfg(test)]
impl<T, A: Allocator + Clone> Clone for BTreeSet<T, A>
where
T: TryClone,
{
fn clone(&self) -> Self {
self.try_clone().abort()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, T: 'a> {
iter: Keys<'a, T, SetValZST>,
}
impl<T> fmt::Debug for Iter<'_, T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Iter").field(&self.iter.clone()).finish()
}
}
#[derive(Debug)]
pub struct IntoIter<T, A: Allocator = Global> {
iter: super::map::IntoIter<T, SetValZST, A>,
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug)]
pub struct Range<'a, T: 'a> {
iter: super::map::Range<'a, T, SetValZST>,
}
#[must_use = "this returns the difference as an iterator, \
without modifying either input set"]
pub struct Difference<'a, T: 'a, A: Allocator = Global> {
inner: DifferenceInner<'a, T, A>,
}
enum DifferenceInner<'a, T: 'a, A: Allocator> {
Stitch {
self_iter: Iter<'a, T>,
other_iter: Peekable<Iter<'a, T>>,
},
Search {
self_iter: Iter<'a, T>,
other_set: &'a BTreeSet<T, A>,
},
Iterate(Iter<'a, T>), }
impl<T, A: Allocator> fmt::Debug for DifferenceInner<'_, T, A>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DifferenceInner::Stitch {
self_iter,
other_iter,
} => f
.debug_struct("Stitch")
.field("self_iter", self_iter)
.field("other_iter", other_iter)
.finish(),
DifferenceInner::Search {
self_iter,
other_set,
} => f
.debug_struct("Search")
.field("self_iter", self_iter)
.field("other_iter", other_set)
.finish(),
DifferenceInner::Iterate(x) => f.debug_tuple("Iterate").field(x).finish(),
}
}
}
impl<T, A: Allocator> fmt::Debug for Difference<'_, T, A>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Difference").field(&self.inner).finish()
}
}
#[must_use = "this returns the difference as an iterator, \
without modifying either input set"]
pub struct SymmetricDifference<'a, T: 'a>(MergeIterInner<Iter<'a, T>>);
impl<T> fmt::Debug for SymmetricDifference<'_, T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("SymmetricDifference").field(&self.0).finish()
}
}
#[must_use = "this returns the intersection as an iterator, \
without modifying either input set"]
pub struct Intersection<'a, T: 'a, A: Allocator = Global> {
inner: IntersectionInner<'a, T, A>,
}
enum IntersectionInner<'a, T: 'a, A: Allocator> {
Stitch {
a: Iter<'a, T>,
b: Iter<'a, T>,
},
Search {
small_iter: Iter<'a, T>,
large_set: &'a BTreeSet<T, A>,
},
Answer(Option<&'a T>), }
impl<T, A: Allocator> fmt::Debug for IntersectionInner<'_, T, A>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IntersectionInner::Stitch { a, b } => f
.debug_struct("Stitch")
.field("a", a)
.field("b", b)
.finish(),
IntersectionInner::Search {
small_iter,
large_set,
} => f
.debug_struct("Search")
.field("small_iter", small_iter)
.field("large_set", large_set)
.finish(),
IntersectionInner::Answer(x) => f.debug_tuple("Answer").field(x).finish(),
}
}
}
impl<T, A: Allocator> fmt::Debug for Intersection<'_, T, A>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Intersection").field(&self.inner).finish()
}
}
#[must_use = "this returns the union as an iterator, \
without modifying either input set"]
pub struct Union<'a, T: 'a>(MergeIterInner<Iter<'a, T>>);
impl<T> fmt::Debug for Union<'_, T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Union").field(&self.0).finish()
}
}
const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16;
impl<T> BTreeSet<T> {
#[must_use]
pub const fn new() -> BTreeSet<T> {
BTreeSet {
map: BTreeMap::new(),
}
}
#[cfg(test)]
pub(crate) fn from<const N: usize>(values: [T; N]) -> Self
where
T: Ord,
{
Self::try_from(values).abort()
}
}
impl<T, A: Allocator> BTreeSet<T, A> {
pub fn new_in(alloc: A) -> BTreeSet<T, A> {
BTreeSet {
map: BTreeMap::new_in(alloc),
}
}
pub fn range<K, R>(&self, range: R) -> Range<'_, T>
where
K: ?Sized + Ord,
T: Borrow<K> + Ord,
R: RangeBounds<K>,
{
Range {
iter: self.map.range(range),
}
}
pub fn difference<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Difference<'a, T, A>
where
T: Ord,
{
let (self_min, self_max) =
if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) {
(self_min, self_max)
} else {
return Difference {
inner: DifferenceInner::Iterate(self.iter()),
};
};
let (other_min, other_max) =
if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) {
(other_min, other_max)
} else {
return Difference {
inner: DifferenceInner::Iterate(self.iter()),
};
};
Difference {
inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
(Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()),
(Equal, _) => {
let mut self_iter = self.iter();
self_iter.next();
DifferenceInner::Iterate(self_iter)
}
(_, Equal) => {
let mut self_iter = self.iter();
self_iter.next_back();
DifferenceInner::Iterate(self_iter)
}
_ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
DifferenceInner::Search {
self_iter: self.iter(),
other_set: other,
}
}
_ => DifferenceInner::Stitch {
self_iter: self.iter(),
other_iter: other.iter().peekable(),
},
},
}
}
pub fn symmetric_difference<'a>(
&'a self,
other: &'a BTreeSet<T, A>,
) -> SymmetricDifference<'a, T>
where
T: Ord,
{
SymmetricDifference(MergeIterInner::new(self.iter(), other.iter()))
}
pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Intersection<'a, T, A>
where
T: Ord,
{
let (self_min, self_max) =
if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) {
(self_min, self_max)
} else {
return Intersection {
inner: IntersectionInner::Answer(None),
};
};
let (other_min, other_max) =
if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) {
(other_min, other_max)
} else {
return Intersection {
inner: IntersectionInner::Answer(None),
};
};
Intersection {
inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
(Greater, _) | (_, Less) => IntersectionInner::Answer(None),
(Equal, _) => IntersectionInner::Answer(Some(self_min)),
(_, Equal) => IntersectionInner::Answer(Some(self_max)),
_ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
IntersectionInner::Search {
small_iter: self.iter(),
large_set: other,
}
}
_ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => {
IntersectionInner::Search {
small_iter: other.iter(),
large_set: self,
}
}
_ => IntersectionInner::Stitch {
a: self.iter(),
b: other.iter(),
},
},
}
}
pub fn union<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Union<'a, T>
where
T: Ord,
{
Union(MergeIterInner::new(self.iter(), other.iter()))
}
pub fn clear(&mut self) {
self.map.clear()
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
self.map.contains_key(value)
}
pub fn get<Q>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
into_ok(self.get_with(&mut (), value, infallible_cmp))
}
pub(crate) fn get_with<C: ?Sized, Q: ?Sized, E>(
&self,
cx: &mut C,
value: &Q,
cmp: CmpFn<C, Q, E>,
) -> Result<Option<&T>, E>
where
T: Borrow<Q>,
{
Recover::get(&self.map, cx, value, cmp)
}
#[must_use]
pub fn is_disjoint(&self, other: &BTreeSet<T, A>) -> bool
where
T: Ord,
{
self.intersection(other).next().is_none()
}
#[must_use]
pub fn is_subset(&self, other: &BTreeSet<T, A>) -> bool
where
T: Ord,
{
if self.len() > other.len() {
return false;
}
let (self_min, self_max) =
if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) {
(self_min, self_max)
} else {
return true; };
let (other_min, other_max) =
if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) {
(other_min, other_max)
} else {
return false; };
let mut self_iter = self.iter();
match self_min.cmp(other_min) {
Less => return false,
Equal => {
self_iter.next();
}
Greater => (),
}
match self_max.cmp(other_max) {
Greater => return false,
Equal => {
self_iter.next_back();
}
Less => (),
}
if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
for next in self_iter {
if !other.contains(next) {
return false;
}
}
} else {
let mut other_iter = other.iter();
other_iter.next();
other_iter.next_back();
let mut self_next = self_iter.next();
while let Some(self1) = self_next {
match other_iter.next().map_or(Less, |other1| self1.cmp(other1)) {
Less => return false,
Equal => self_next = self_iter.next(),
Greater => (),
}
}
}
true
}
#[must_use]
pub fn is_superset(&self, other: &BTreeSet<T, A>) -> bool
where
T: Ord,
{
other.is_subset(self)
}
#[must_use]
pub fn first(&self) -> Option<&T>
where
T: Ord,
{
self.map.first_key_value().map(|(k, _)| k)
}
#[must_use]
pub fn last(&self) -> Option<&T>
where
T: Ord,
{
self.map.last_key_value().map(|(k, _)| k)
}
pub fn pop_first(&mut self) -> Option<T>
where
T: Ord,
{
self.map.pop_first().map(|kv| kv.0)
}
pub fn pop_last(&mut self) -> Option<T>
where
T: Ord,
{
self.map.pop_last().map(|kv| kv.0)
}
pub fn try_insert(&mut self, value: T) -> Result<bool, AllocError>
where
T: Ord,
{
Ok(self.map.try_insert(value, SetValZST)?.is_none())
}
#[cfg(test)]
pub(crate) fn insert(&mut self, value: T) -> bool
where
T: Ord,
{
self.try_insert(value).abort()
}
pub fn try_replace(&mut self, value: T) -> Result<Option<T>, AllocError>
where
T: Ord,
{
into_ok(self.try_replace_with(&mut (), value, infallible_cmp))
}
#[cfg(test)]
pub(crate) fn replace(&mut self, value: T) -> Option<T>
where
T: Ord,
{
self.try_replace(value).abort()
}
pub(crate) fn try_replace_with<C: ?Sized, E>(
&mut self,
cx: &mut C,
value: T,
cmp: CmpFn<C, T, E>,
) -> Result<Result<Option<T>, AllocError>, E> {
Recover::try_replace(&mut self.map, cx, value, cmp)
}
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
self.map.remove(value).is_some()
}
pub fn take<Q>(&mut self, value: &Q) -> Option<T>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
into_ok(self.take_with(&mut (), value, infallible_cmp))
}
pub(crate) fn take_with<C: ?Sized, Q: ?Sized, E>(
&mut self,
cx: &mut C,
value: &Q,
cmp: CmpFn<C, Q, E>,
) -> Result<Option<T>, E>
where
T: Borrow<Q>,
{
Recover::take(&mut self.map, cx, value, cmp)
}
pub fn retain<F>(&mut self, mut f: F)
where
T: Ord,
F: FnMut(&T) -> bool,
{
self.extract_if(|v| !f(v)).for_each(drop);
}
pub fn try_append(&mut self, other: &mut Self) -> Result<(), AllocError>
where
T: Ord,
{
self.map.try_append(&mut other.map)
}
#[cfg(test)]
pub(crate) fn append(&mut self, other: &mut Self)
where
T: Ord,
{
self.try_append(other).abort()
}
pub fn try_split_off<Q>(&mut self, value: &Q) -> Result<Self, Error>
where
Q: ?Sized + Ord,
T: Borrow<Q> + Ord,
A: Clone,
{
Ok(BTreeSet {
map: self.map.try_split_off(value)?,
})
}
#[cfg(test)]
pub(crate) fn split_off<Q>(&mut self, value: &Q) -> Self
where
Q: ?Sized + Ord,
T: Borrow<Q> + Ord,
A: Clone,
{
self.try_split_off(value).abort()
}
pub fn extract_if<'a, F>(&'a mut self, pred: F) -> ExtractIf<'a, T, F, A>
where
T: Ord,
F: 'a + FnMut(&T) -> bool,
{
let (inner, alloc) = self.map.extract_if_inner();
ExtractIf { pred, inner, alloc }
}
pub fn iter(&self) -> Iter<'_, T> {
Iter {
iter: self.map.keys(),
}
}
#[must_use]
pub const fn len(&self) -> usize {
self.map.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<T, A: Allocator> IntoIterator for BTreeSet<T, A> {
type Item = T;
type IntoIter = IntoIter<T, A>;
fn into_iter(self) -> IntoIter<T, A> {
IntoIter {
iter: self.map.into_iter(),
}
}
}
impl<'a, T, A: Allocator> IntoIterator for &'a BTreeSet<T, A> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ExtractIf<'a, T, F, A: Allocator = Global>
where
T: 'a,
F: 'a + FnMut(&T) -> bool,
{
pred: F,
inner: super::map::ExtractIfInner<'a, T, SetValZST>,
alloc: &'a A,
}
impl<T, F, A: Allocator> fmt::Debug for ExtractIf<'_, T, F, A>
where
T: fmt::Debug,
F: FnMut(&T) -> bool,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("ExtractIf")
.field(&self.inner.peek().map(|(k, _)| k))
.finish()
}
}
impl<T, F, A: Allocator> Iterator for ExtractIf<'_, T, F, A>
where
F: FnMut(&T) -> bool,
{
type Item = T;
fn next(&mut self) -> Option<T> {
let pred = &mut self.pred;
let mut mapped_pred = |k: &T, _v: &mut SetValZST| pred(k);
self.inner
.next(&mut mapped_pred, self.alloc)
.map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, F, A: Allocator> FusedIterator for ExtractIf<'_, T, F, A> where F: FnMut(&T) -> bool {}
impl<T, A: Allocator> TryExtend<T> for BTreeSet<T, A>
where
T: Ord,
{
#[inline]
fn try_extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) -> Result<(), Error> {
for elem in iter {
self.try_insert(elem)?;
}
Ok(())
}
}
#[cfg(test)]
impl<T, A: Allocator> Extend<T> for BTreeSet<T, A>
where
T: Ord,
{
#[inline]
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
self.try_extend(iter).abort()
}
}
impl<'a, T, A: Allocator> TryExtend<&'a T> for BTreeSet<T, A>
where
T: 'a + Ord + Copy,
{
fn try_extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) -> Result<(), Error> {
self.try_extend(iter.into_iter().copied())
}
}
#[cfg(test)]
impl<'a, T, A: Allocator> Extend<&'a T> for BTreeSet<T, A>
where
T: 'a + Ord + Copy,
{
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.try_extend(iter).abort()
}
}
impl<T> Default for BTreeSet<T> {
fn default() -> BTreeSet<T> {
BTreeSet::new()
}
}
impl<T, A: Allocator> fmt::Debug for BTreeSet<T, A>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> Clone for Iter<'_, T> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn last(mut self) -> Option<&'a T> {
self.next_back()
}
fn min(mut self) -> Option<&'a T>
where
&'a T: Ord,
{
self.next()
}
fn max(mut self) -> Option<&'a T>
where
&'a T: Ord,
{
self.next_back()
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<&'a T> {
self.iter.next_back()
}
}
impl<T> ExactSizeIterator for Iter<'_, T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> FusedIterator for Iter<'_, T> {}
impl<T, A: Allocator> Iterator for IntoIter<T, A> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.iter.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T> Default for Iter<'_, T> {
fn default() -> Self {
Iter {
iter: Default::default(),
}
}
}
impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
fn next_back(&mut self) -> Option<T> {
self.iter.next_back().map(|(k, _)| k)
}
}
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
impl<T, A> Default for IntoIter<T, A>
where
A: Allocator + Default + Clone,
{
fn default() -> Self {
IntoIter {
iter: Default::default(),
}
}
}
impl<T> Clone for Range<'_, T> {
fn clone(&self) -> Self {
Range {
iter: self.iter.clone(),
}
}
}
impl<'a, T> Iterator for Range<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.iter.next().map(|(k, _)| k)
}
fn last(mut self) -> Option<&'a T> {
self.next_back()
}
fn min(mut self) -> Option<&'a T>
where
&'a T: Ord,
{
self.next()
}
fn max(mut self) -> Option<&'a T>
where
&'a T: Ord,
{
self.next_back()
}
}
impl<'a, T> DoubleEndedIterator for Range<'a, T> {
fn next_back(&mut self) -> Option<&'a T> {
self.iter.next_back().map(|(k, _)| k)
}
}
impl<T> FusedIterator for Range<'_, T> {}
impl<T> Default for Range<'_, T> {
fn default() -> Self {
Range {
iter: Default::default(),
}
}
}
impl<T, A: Allocator> Clone for Difference<'_, T, A> {
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,
},
DifferenceInner::Iterate(iter) => DifferenceInner::Iterate(iter.clone()),
},
}
}
}
impl<'a, T: Ord, A: Allocator> Iterator for Difference<'a, T, A> {
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| self_next.cmp(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);
}
},
DifferenceInner::Iterate(iter) => iter.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()),
DifferenceInner::Iterate(iter) => (iter.len(), 0),
};
(self_len.saturating_sub(other_len), Some(self_len))
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord, A: Allocator> FusedIterator for Difference<'_, T, A> {}
impl<T> Clone for SymmetricDifference<'_, T> {
fn clone(&self) -> Self {
SymmetricDifference(self.0.clone())
}
}
impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let (a_next, b_next) = self.0.nexts(Self::Item::cmp);
if a_next.and(b_next).is_none() {
return a_next.or(b_next);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.0.lens();
(0, Some(a_len + b_len))
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord> FusedIterator for SymmetricDifference<'_, T> {}
impl<T, A: Allocator> Clone for Intersection<'_, T, A> {
fn clone(&self) -> Self {
Intersection {
inner: match &self.inner {
IntersectionInner::Stitch { a, b } => IntersectionInner::Stitch {
a: a.clone(),
b: b.clone(),
},
IntersectionInner::Search {
small_iter,
large_set,
} => IntersectionInner::Search {
small_iter: small_iter.clone(),
large_set,
},
IntersectionInner::Answer(answer) => IntersectionInner::Answer(*answer),
},
}
}
}
impl<'a, T: Ord, A: Allocator> Iterator for Intersection<'a, T, A> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match &mut self.inner {
IntersectionInner::Stitch { a, b } => {
let mut a_next = a.next()?;
let mut b_next = b.next()?;
loop {
match a_next.cmp(b_next) {
Less => a_next = a.next()?,
Greater => b_next = b.next()?,
Equal => return Some(a_next),
}
}
}
IntersectionInner::Search {
small_iter,
large_set,
} => loop {
let small_next = small_iter.next()?;
if large_set.contains(small_next) {
return Some(small_next);
}
},
IntersectionInner::Answer(answer) => answer.take(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.inner {
IntersectionInner::Stitch { a, b } => (0, Some(min(a.len(), b.len()))),
IntersectionInner::Search { small_iter, .. } => (0, Some(small_iter.len())),
IntersectionInner::Answer(None) => (0, Some(0)),
IntersectionInner::Answer(Some(_)) => (1, Some(1)),
}
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord, A: Allocator> FusedIterator for Intersection<'_, T, A> {}
impl<T> Clone for Union<'_, T> {
fn clone(&self) -> Self {
Union(self.0.clone())
}
}
impl<'a, T: Ord> Iterator for Union<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
let (a_next, b_next) = self.0.nexts(Self::Item::cmp);
a_next.or(b_next)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.0.lens();
(max(a_len, b_len), Some(a_len + b_len))
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord> FusedIterator for Union<'_, T> {}
impl<T, A: Allocator> TryFromIteratorIn<T, A> for BTreeSet<T, A>
where
T: Ord,
{
#[inline]
fn try_from_iter_in<I>(iter: I, alloc: A) -> Result<Self, Error>
where
I: IntoIterator<Item = T>,
{
let mut this = BTreeSet::new_in(alloc);
for value in iter {
this.try_insert(value)?;
}
Ok(this)
}
}
#[cfg(test)]
impl<T> FromIterator<T> for BTreeSet<T>
where
T: Ord,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
Self::try_from_iter_in(iter, Global).abort()
}
}
impl<T, const N: usize> TryFrom<[T; N]> for BTreeSet<T>
where
T: Ord,
{
type Error = Error;
#[inline]
fn try_from(values: [T; N]) -> Result<Self, Self::Error> {
let mut this = BTreeSet::new();
for value in values {
this.try_insert(value)?;
}
Ok(this)
}
}
#[cfg(test)]
mod tests;