use crate::{
default::{OrdStoredKey, OrdTotalOrder},
SortableBy, TotalOrder,
};
use alloc::vec::Vec;
use core::cmp::Ordering::{self, Equal, Greater, Less};
use core::cmp::{max, min};
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, FusedIterator, Peekable};
use core::mem::ManuallyDrop;
use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
use super::map::{BTreeMap, Keys};
use super::merge_iter::MergeIterInner;
use super::set_val::SetValZST;
use super::Recover;
use crate::polyfill::*;
pub struct BTreeSet<
T,
O = OrdTotalOrder<<T as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
map: BTreeMap<T, SetValZST, O, A>,
}
impl<T: Hash, O, A: Allocator + Clone> Hash for BTreeSet<T, O, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.map.hash(state)
}
}
impl<T: PartialEq, O, A: Allocator + Clone> PartialEq for BTreeSet<T, O, A> {
fn eq(&self, other: &BTreeSet<T, O, A>) -> bool {
self.map.eq(&other.map)
}
}
impl<T: Eq, O, A: Allocator + Clone> Eq for BTreeSet<T, O, A> {}
impl<T: PartialOrd, O, A: Allocator + Clone> PartialOrd for BTreeSet<T, O, A> {
fn partial_cmp(&self, other: &BTreeSet<T, O, A>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T: Ord, O, A: Allocator + Clone> Ord for BTreeSet<T, O, A> {
fn cmp(&self, other: &BTreeSet<T, O, A>) -> Ordering {
self.map.cmp(&other.map)
}
}
impl<T: Clone, O: Clone, A: Allocator + Clone> Clone for BTreeSet<T, O, A> {
fn clone(&self) -> Self {
BTreeSet { map: self.map.clone() }
}
fn clone_from(&mut self, other: &Self) {
self.map.clone_from(&other.map);
}
}
#[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> fmt::Debug for Iter<'_, T> {
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 + Clone = 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,
O = OrdTotalOrder<<T as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
inner: DifferenceInner<'a, T, O, A>,
order: &'a O,
}
enum DifferenceInner<'a, T: 'a, O, A: Allocator + Clone> {
Stitch {
self_iter: Iter<'a, T>,
other_iter: Peekable<Iter<'a, T>>,
},
Search {
self_iter: Iter<'a, T>,
other_set: &'a BTreeSet<T, O, A>,
},
Iterate(Iter<'a, T>), }
impl<T: Debug, O: TotalOrder, A: Allocator + Clone> Debug for DifferenceInner<'_, T, O, A> {
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: fmt::Debug, O: TotalOrder, A: Allocator + Clone> fmt::Debug for Difference<'_, T, O, A> {
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,
O = OrdTotalOrder<<T as OrdStoredKey>::OrdKeyType>,
>(MergeIterInner<Iter<'a, T>>, &'a O);
impl<T: fmt::Debug, O> fmt::Debug for SymmetricDifference<'_, T, O> {
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,
O = OrdTotalOrder<<T as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
inner: IntersectionInner<'a, T, O, A>,
order: &'a O,
}
enum IntersectionInner<'a, T: 'a, O, A: Allocator + Clone> {
Stitch {
a: Iter<'a, T>,
b: Iter<'a, T>,
},
Search {
small_iter: Iter<'a, T>,
large_set: &'a BTreeSet<T, O, A>,
},
Answer(Option<&'a T>), }
impl<T: Debug, O: TotalOrder, A: Allocator + Clone> Debug for IntersectionInner<'_, T, O, A> {
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: Debug, O: TotalOrder, A: Allocator + Clone> Debug for Intersection<'_, T, O, A> {
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, O = OrdTotalOrder<<T as OrdStoredKey>::OrdKeyType>>(
MergeIterInner<Iter<'a, T>>,
&'a O,
);
impl<T: fmt::Debug, O> fmt::Debug for Union<'_, T, O> {
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, O> BTreeSet<T, O> {
#[must_use]
pub const fn new(order: O) -> BTreeSet<T, O> {
BTreeSet { map: BTreeMap::new(order) }
}
}
impl<T, O, A: Allocator + Clone> BTreeSet<T, O, A> {
decorate_if! {
if #[cfg(feature = "btreemap_alloc")] {
pub
}
fn new_in(order: O, alloc: A) -> BTreeSet<T, O, A> {
BTreeSet { map: BTreeMap::new_in(order, alloc) }
}
}
pub fn range<K: ?Sized, R>(&self, range: R) -> Range<'_, T>
where
K: SortableBy<O>,
T: SortableBy<O>,
O: TotalOrder,
R: RangeBounds<K>,
{
Range { iter: self.map.range(range) }
}
pub fn difference<'a>(&'a self, other: &'a BTreeSet<T, O, A>) -> Difference<'a, T, O, A>
where
T: SortableBy<O>,
O: TotalOrder,
{
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()),
order: &self.map.order,
};
};
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()),
order: &self.map.order,
};
};
Difference {
inner: match (
self.map.order.cmp_any(self_min, other_max),
self.map.order.cmp_any(self_max, 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(),
},
},
order: &self.map.order,
}
}
pub fn symmetric_difference<'a>(
&'a self,
other: &'a BTreeSet<T, O, A>,
) -> SymmetricDifference<'a, T, O>
where
T: SortableBy<O>,
O: TotalOrder,
{
SymmetricDifference(MergeIterInner::new(self.iter(), other.iter()), &self.map.order)
}
pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T, O, A>) -> Intersection<'a, T, O, A>
where
T: SortableBy<O>,
O: TotalOrder,
{
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), order: &self.map.order };
};
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), order: &self.map.order };
};
Intersection {
inner: match (
self.map.order.cmp_any(self_min, other_max),
self.map.order.cmp_any(self_max, 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() },
},
order: &self.map.order,
}
}
pub fn union<'a>(&'a self, other: &'a BTreeSet<T, O, A>) -> Union<'a, T, O>
where
T: SortableBy<O>,
O: TotalOrder,
{
Union(MergeIterInner::new(self.iter(), other.iter()), &self.map.order)
}
pub fn clear(&mut self)
where
A: Clone,
O: Clone,
{
self.map.clear()
}
pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
where
T: SortableBy<O>,
Q: SortableBy<O>,
O: TotalOrder,
{
self.map.contains_key(value)
}
pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
where
T: SortableBy<O>,
Q: SortableBy<O>,
O: TotalOrder,
{
Recover::get(&self.map, value)
}
#[must_use]
pub fn is_disjoint(&self, other: &BTreeSet<T, O, A>) -> bool
where
T: SortableBy<O>,
O: TotalOrder,
{
self.intersection(other).next().is_none()
}
#[must_use]
pub fn is_subset(&self, other: &BTreeSet<T, O, A>) -> bool
where
T: SortableBy<O>,
O: TotalOrder,
{
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.map.order.cmp_any(self_min, other_min) {
Less => return false,
Equal => {
self_iter.next();
}
Greater => (),
}
match self.map.order.cmp_any(self_max, 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| self.map.order.cmp_any(self1, other1))
{
Less => return false,
Equal => self_next = self_iter.next(),
Greater => (),
}
}
}
true
}
#[must_use]
pub fn is_superset(&self, other: &BTreeSet<T, O, A>) -> bool
where
T: SortableBy<O>,
O: TotalOrder,
{
other.is_subset(self)
}
#[must_use]
pub fn first(&self) -> Option<&T>
where
T: SortableBy<O>,
O: TotalOrder,
{
self.map.first_key_value().map(|(k, _)| k)
}
#[must_use]
pub fn last(&self) -> Option<&T>
where
T: SortableBy<O>,
O: TotalOrder,
{
self.map.last_key_value().map(|(k, _)| k)
}
pub fn pop_first(&mut self) -> Option<T>
where
T: SortableBy<O>,
O: TotalOrder,
{
self.map.pop_first().map(|kv| kv.0)
}
pub fn pop_last(&mut self) -> Option<T>
where
T: SortableBy<O>,
O: TotalOrder,
{
self.map.pop_last().map(|kv| kv.0)
}
pub fn insert(&mut self, value: T) -> bool
where
T: SortableBy<O>,
O: TotalOrder,
{
self.map.insert(value, SetValZST::default()).is_none()
}
pub fn replace(&mut self, value: T) -> Option<T>
where
T: SortableBy<O>,
O: TotalOrder,
{
Recover::<T>::replace(&mut self.map, value)
}
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
where
T: SortableBy<O>,
Q: SortableBy<O>,
O: TotalOrder,
{
self.map.remove(value).is_some()
}
pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
where
T: SortableBy<O>,
Q: SortableBy<O>,
O: TotalOrder,
{
Recover::take(&mut self.map, value)
}
pub fn retain<F>(&mut self, mut f: F)
where
T: SortableBy<O>,
O: TotalOrder,
F: FnMut(&T) -> bool,
{
self.drain_filter(|v| !f(v));
}
pub fn append(&mut self, other: &mut Self)
where
T: SortableBy<O>,
O: Clone + TotalOrder,
A: Clone,
{
self.map.append(&mut other.map);
}
pub fn split_off<Q: ?Sized + SortableBy<O>>(&mut self, value: &Q) -> Self
where
T: SortableBy<O>,
O: TotalOrder + Clone,
A: Clone,
{
BTreeSet { map: self.map.split_off(value) }
}
decorate_if! {
if #[cfg(feature = "btree_drain_filter")] {
pub
}
fn drain_filter<'a, F>(&'a mut self, pred: F) -> DrainFilter<'a, T, F, A>
where
T: SortableBy<O>,
O: TotalOrder,
F: 'a + FnMut(&T) -> bool,
{
let (inner, alloc) = self.map.drain_filter_inner();
DrainFilter { pred, inner, alloc }
}
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { iter: self.map.keys() }
}
decorate_if! {
#[must_use]
pub
if #[cfg(feature = "const_btree_len")] { const }
fn len(&self) -> usize {
self.map.len()
}
}
decorate_if! {
#[must_use]
pub
if #[cfg(feature = "const_btree_len")] { const }
fn is_empty(&self) -> bool {
self.len() == 0
}
}
}
impl<T: SortableBy<O>, O: TotalOrder + Default> FromIterator<T> for BTreeSet<T, O> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> BTreeSet<T, O> {
let mut inputs: Vec<_> = iter.into_iter().collect();
if inputs.is_empty() {
return BTreeSet::default();
}
let order = O::default();
inputs.sort_by(|a, b| order.cmp_any(a, b));
BTreeSet::from_sorted_iter(inputs.into_iter(), order, Global)
}
}
impl<T: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> BTreeSet<T, O, A> {
fn from_sorted_iter<I: Iterator<Item = T>>(iter: I, order: O, alloc: A) -> BTreeSet<T, O, A> {
let iter = iter.map(|k| (k, SetValZST::default()));
let map = BTreeMap::bulk_build_from_sorted_iter(iter, order, alloc);
BTreeSet { map }
}
}
impl<T: SortableBy<O>, O: TotalOrder + Default, const N: usize> From<[T; N]> for BTreeSet<T, O> {
fn from(mut arr: [T; N]) -> Self {
if N == 0 {
return BTreeSet::default();
}
let order = O::default();
arr.sort_by(|a, b| order.cmp_any(a, b));
let iter = IntoIterator::into_iter(arr).map(|k| (k, SetValZST::default()));
let map = BTreeMap::bulk_build_from_sorted_iter(iter, order, Global);
BTreeSet { map }
}
}
impl<T, O, A: Allocator + Clone> IntoIterator for BTreeSet<T, O, 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, O: TotalOrder, A: Allocator + Clone> IntoIterator for &'a BTreeSet<T, O, A> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
decorate_if! {
if #[cfg(feature = "btree_drain_filter")] { pub }
struct DrainFilter<'a, T, F, A: Allocator + Clone = Global>
where
T: 'a,
F: 'a + FnMut(&T) -> bool,
{
pred: F,
inner: super::map::DrainFilterInner<'a, T, SetValZST>,
alloc: A,
}
}
impl<T, F, A: Allocator + Clone> Drop for DrainFilter<'_, T, F, A>
where
F: FnMut(&T) -> bool,
{
fn drop(&mut self) {
self.for_each(drop);
}
}
impl<T, F, A: Allocator + Clone> fmt::Debug for DrainFilter<'_, T, F, A>
where
T: fmt::Debug,
F: FnMut(&T) -> bool,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("DrainFilter").field(&self.inner.peek().map(|(k, _)| k)).finish()
}
}
impl<'a, T, F, A: Allocator + Clone> Iterator for DrainFilter<'_, T, F, A>
where
F: 'a + 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.clone()).map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, F, A: Allocator + Clone> FusedIterator for DrainFilter<'_, T, F, A> where
F: FnMut(&T) -> bool
{
}
impl<T: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> Extend<T> for BTreeSet<T, O, A> {
#[inline]
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
iter.into_iter().for_each(move |elem| {
self.insert(elem);
});
}
#[inline]
#[cfg(feature = "extend_one")]
fn extend_one(&mut self, elem: T) {
self.insert(elem);
}
}
impl<'a, T: 'a + SortableBy<O> + Copy, O: TotalOrder, A: Allocator + Clone> Extend<&'a T>
for BTreeSet<T, O, A>
{
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
}
#[inline]
#[cfg(feature = "extend_one")]
fn extend_one(&mut self, &elem: &'a T) {
self.insert(elem);
}
}
impl<T, O: Default> Default for BTreeSet<T, O> {
fn default() -> BTreeSet<T, O> {
BTreeSet::new(O::default())
}
}
impl<T: SortableBy<O> + Clone, O: TotalOrder + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, O, A>>
for &BTreeSet<T, O, A>
{
type Output = BTreeSet<T, O, A>;
fn sub(self, rhs: &BTreeSet<T, O, A>) -> BTreeSet<T, O, A> {
BTreeSet::from_sorted_iter(
self.difference(rhs).cloned(),
self.map.order.clone(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
}
}
impl<T: SortableBy<O> + Clone, O: TotalOrder + Clone, A: Allocator + Clone>
BitXor<&BTreeSet<T, O, A>> for &BTreeSet<T, O, A>
{
type Output = BTreeSet<T, O, A>;
fn bitxor(self, rhs: &BTreeSet<T, O, A>) -> BTreeSet<T, O, A> {
BTreeSet::from_sorted_iter(
self.symmetric_difference(rhs).cloned(),
self.map.order.clone(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
}
}
impl<T: SortableBy<O> + Clone, O: TotalOrder + Clone, A: Allocator + Clone>
BitAnd<&BTreeSet<T, O, A>> for &BTreeSet<T, O, A>
{
type Output = BTreeSet<T, O, A>;
fn bitand(self, rhs: &BTreeSet<T, O, A>) -> BTreeSet<T, O, A> {
BTreeSet::from_sorted_iter(
self.intersection(rhs).cloned(),
self.map.order.clone(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
}
}
impl<T: SortableBy<O> + Clone, O: TotalOrder + Clone, A: Allocator + Clone>
BitOr<&BTreeSet<T, O, A>> for &BTreeSet<T, O, A>
{
type Output = BTreeSet<T, O, A>;
fn bitor(self, rhs: &BTreeSet<T, O, A>) -> BTreeSet<T, O, A> {
BTreeSet::from_sorted_iter(
self.union(rhs).cloned(),
self.map.order.clone(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
}
}
impl<T: Debug, O, A: Allocator + Clone> Debug for BTreeSet<T, O, A> {
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> {
self.next()
}
fn max(mut self) -> Option<&'a T> {
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 + Clone> 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, A: Allocator + Clone> DoubleEndedIterator for IntoIter<T, A> {
fn next_back(&mut self) -> Option<T> {
self.iter.next_back().map(|(k, _)| k)
}
}
impl<T, A: Allocator + Clone> ExactSizeIterator for IntoIter<T, A> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T, A: Allocator + Clone> FusedIterator for IntoIter<T, A> {}
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> {
self.next()
}
fn max(mut self) -> Option<&'a T> {
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, O, A: Allocator + Clone> Clone for Difference<'_, T, O, 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()),
},
order: self.order,
}
}
}
impl<'a, T: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> Iterator
for Difference<'a, T, O, 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.order.cmp_any(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);
}
},
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: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> FusedIterator
for Difference<'_, T, O, A>
{
}
impl<T, O> Clone for SymmetricDifference<'_, T, O> {
fn clone(&self) -> Self {
SymmetricDifference(self.0.clone(), self.1)
}
}
impl<'a, T: SortableBy<O>, O: TotalOrder> Iterator for SymmetricDifference<'a, T, O> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let (a_next, b_next) = self.0.nexts(|&a, &b| self.1.cmp_any(a, b));
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: SortableBy<O>, O: TotalOrder> FusedIterator for SymmetricDifference<'_, T, O> {}
impl<T, O: Clone, A: Allocator + Clone> Clone for Intersection<'_, T, O, 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),
},
order: self.order,
}
}
}
impl<'a, T: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> Iterator
for Intersection<'a, T, O, 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 self.order.cmp_any(a_next, 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: SortableBy<O>, O: TotalOrder, A: Allocator + Clone> FusedIterator
for Intersection<'_, T, O, A>
{
}
impl<T, O> Clone for Union<'_, T, O> {
fn clone(&self) -> Self {
Union(self.0.clone(), self.1)
}
}
impl<'a, T: SortableBy<O>, O: TotalOrder> Iterator for Union<'a, T, O> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
let (a_next, b_next) = self.0.nexts(|&a, &b| self.1.cmp_any(a, b));
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: SortableBy<O>, O: TotalOrder> FusedIterator for Union<'_, T, O> {}
#[cfg(test)]
mod tests;