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::marker::PhantomData;
use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
use crate::OSBTreeMap;
use crate::osbtree_map::{ExtractIfInner, IntoKeys, Keys, Range as MapRange};
mod capacity;
mod order_statistic;
pub struct OSBTreeSet<T> {
map: OSBTreeMap<T, ()>,
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, T: 'a> {
inner: Keys<'a, T, ()>,
}
pub struct IntoIter<T> {
inner: IntoKeys<T, ()>,
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Range<'a, T: 'a> {
inner: MapRange<'a, T, ()>,
}
#[must_use = "this returns the difference as an iterator, \
without modifying either input set"]
pub struct Difference<'a, T: 'a> {
inner: DifferenceInner<'a, T>,
}
#[must_use = "this returns the symmetric difference as an iterator, \
without modifying either input set"]
pub struct SymmetricDifference<'a, T: 'a> {
inner: MergeIterInner<Iter<'a, T>>,
}
#[must_use = "this returns the intersection as an iterator, \
without modifying either input set"]
pub struct Intersection<'a, T: 'a> {
inner: IntersectionInner<'a, T>,
}
#[must_use = "this returns the union as an iterator, \
without modifying either input set"]
pub struct Union<'a, T: 'a> {
inner: MergeIterInner<Iter<'a, T>>,
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ExtractIf<'a, T, R, F> {
pred: F,
inner: ExtractIfInner<'a, T, (), R>,
}
enum DifferenceInner<'a, T: 'a> {
Stitch {
self_iter: Iter<'a, T>,
other_iter: Peekable<Iter<'a, T>>,
},
Search {
self_iter: Iter<'a, T>,
other_set: &'a OSBTreeSet<T>,
},
Iterate(Iter<'a, T>),
}
enum IntersectionInner<'a, T: 'a> {
Stitch {
a: Iter<'a, T>,
b: Iter<'a, T>,
},
Search {
small_iter: Iter<'a, T>,
large_set: &'a OSBTreeSet<T>,
},
Answer(Option<&'a T>),
}
const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16;
struct MergeIterInner<I: Iterator> {
a: I,
b: I,
peeked: Option<Peeked<I>>,
}
#[derive(Clone, Debug)]
enum Peeked<I: Iterator> {
A(I::Item),
B(I::Item),
}
impl<I: Iterator> Clone for MergeIterInner<I>
where
I: Clone,
I::Item: Clone,
{
fn clone(&self) -> Self {
MergeIterInner {
a: self.a.clone(),
b: self.b.clone(),
peeked: self.peeked.clone(),
}
}
}
impl<I: Iterator> fmt::Debug for MergeIterInner<I>
where
I: fmt::Debug,
I::Item: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MergeIterInner").field("a", &self.a).field("b", &self.b).field("peeked", &self.peeked).finish()
}
}
impl<T: fmt::Debug> fmt::Debug for DifferenceInner<'_, T> {
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_set", other_set).finish(),
DifferenceInner::Iterate(iter) => f.debug_tuple("Iterate").field(iter).finish(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for IntersectionInner<'_, T> {
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(answer) => f.debug_tuple("Answer").field(answer).finish(),
}
}
}
impl<I: Iterator> MergeIterInner<I> {
fn new(a: I, b: I) -> Self {
MergeIterInner {
a,
b,
peeked: None,
}
}
fn nexts<Cmp: Fn(&I::Item, &I::Item) -> Ordering>(&mut self, cmp: Cmp) -> (Option<I::Item>, Option<I::Item>)
where
I: FusedIterator,
{
let a_next = match self.peeked.take() {
Some(Peeked::A(a)) => Some(a),
Some(Peeked::B(b)) => {
self.peeked = Some(Peeked::B(b));
self.a.next()
}
None => self.a.next(),
};
let b_next = match self.peeked.take() {
Some(Peeked::B(b)) => Some(b),
Some(Peeked::A(a)) => {
self.peeked = Some(Peeked::A(a));
self.b.next()
}
None => self.b.next(),
};
match (a_next, b_next) {
(None, None) => (None, None),
(Some(a), None) => (Some(a), None),
(None, Some(b)) => (None, Some(b)),
(Some(a), Some(b)) => match cmp(&a, &b) {
Less => {
self.peeked = Some(Peeked::B(b));
(Some(a), None)
}
Greater => {
self.peeked = Some(Peeked::A(a));
(None, Some(b))
}
Equal => (Some(a), Some(b)),
},
}
}
fn lens(&self) -> (usize, usize)
where
I: ExactSizeIterator,
{
match &self.peeked {
Some(Peeked::A(_)) => (1 + self.a.len(), self.b.len()),
Some(Peeked::B(_)) => (self.a.len(), 1 + self.b.len()),
None => (self.a.len(), self.b.len()),
}
}
}
impl<T> OSBTreeSet<T> {
#[must_use]
pub const fn new() -> OSBTreeSet<T> {
OSBTreeSet {
map: OSBTreeMap::new(),
}
}
pub fn range<K, R>(&self, range: R) -> Range<'_, T>
where
K: ?Sized + Ord,
T: Borrow<K> + Ord + Clone,
R: RangeBounds<K>,
{
Range {
inner: self.map.range(range),
}
}
pub fn difference<'a>(&'a self, other: &'a OSBTreeSet<T>) -> Difference<'a, T>
where
T: Ord + Clone,
{
let (Some(self_min), Some(self_max)) = (self.first(), self.last()) else {
return Difference {
inner: DifferenceInner::Iterate(self.iter()),
};
};
let (Some(other_min), Some(other_max)) = (other.first(), other.last()) else {
return Difference {
inner: DifferenceInner::Iterate(self.iter()),
};
};
if self_max < other_min || other_max < self_min {
return Difference {
inner: DifferenceInner::Iterate(self.iter()),
};
}
let self_len = self.len();
let other_len = other.len();
if other_len > ITER_PERFORMANCE_TIPPING_SIZE_DIFF * self_len {
Difference {
inner: DifferenceInner::Search {
self_iter: self.iter(),
other_set: other,
},
}
} else {
Difference {
inner: DifferenceInner::Stitch {
self_iter: self.iter(),
other_iter: other.iter().peekable(),
},
}
}
}
pub fn symmetric_difference<'a>(&'a self, other: &'a OSBTreeSet<T>) -> SymmetricDifference<'a, T>
where
T: Ord,
{
SymmetricDifference {
inner: MergeIterInner::new(self.iter(), other.iter()),
}
}
pub fn intersection<'a>(&'a self, other: &'a OSBTreeSet<T>) -> Intersection<'a, T>
where
T: Ord + Clone,
{
let (Some(self_min), Some(self_max)) = (self.first(), self.last()) else {
return Intersection {
inner: IntersectionInner::Answer(None),
};
};
let (Some(other_min), Some(other_max)) = (other.first(), other.last()) else {
return Intersection {
inner: IntersectionInner::Answer(None),
};
};
if self_max < other_min || other_max < self_min {
return Intersection {
inner: IntersectionInner::Answer(None),
};
}
let self_len = self.len();
let other_len = other.len();
if self_len > ITER_PERFORMANCE_TIPPING_SIZE_DIFF * other_len {
Intersection {
inner: IntersectionInner::Search {
small_iter: other.iter(),
large_set: self,
},
}
} else if other_len > ITER_PERFORMANCE_TIPPING_SIZE_DIFF * self_len {
Intersection {
inner: IntersectionInner::Search {
small_iter: self.iter(),
large_set: other,
},
}
} else {
Intersection {
inner: IntersectionInner::Stitch {
a: self.iter(),
b: other.iter(),
},
}
}
}
pub fn union<'a>(&'a self, other: &'a OSBTreeSet<T>) -> Union<'a, T>
where
T: Ord,
{
Union {
inner: 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 + Clone,
Q: ?Sized + Ord,
{
self.map.contains_key(value)
}
pub fn get<Q>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q> + Ord + Clone,
Q: ?Sized + Ord,
{
self.map.get_key_value(value).map(|(k, ())| k)
}
#[must_use]
pub fn is_disjoint(&self, other: &OSBTreeSet<T>) -> bool
where
T: Ord + Clone,
{
if self.len() <= other.len() {
self.iter().all(|v| !other.contains(v))
} else {
other.iter().all(|v| !self.contains(v))
}
}
#[must_use]
pub fn is_subset(&self, other: &OSBTreeSet<T>) -> bool
where
T: Ord + Clone,
{
self.len() <= other.len() && self.iter().all(|v| other.contains(v))
}
#[must_use]
pub fn is_superset(&self, other: &OSBTreeSet<T>) -> bool
where
T: Ord + Clone,
{
other.is_subset(self)
}
#[must_use]
pub fn first(&self) -> Option<&T>
where
T: Ord + Clone,
{
self.map.first_key_value().map(|(k, ())| k)
}
#[must_use]
pub fn last(&self) -> Option<&T>
where
T: Ord + Clone,
{
self.map.last_key_value().map(|(k, ())| k)
}
pub fn pop_first(&mut self) -> Option<T>
where
T: Clone + Ord,
{
self.map.pop_first().map(|(k, ())| k)
}
pub fn pop_last(&mut self) -> Option<T>
where
T: Clone + Ord,
{
self.map.pop_last().map(|(k, ())| k)
}
pub fn insert(&mut self, value: T) -> bool
where
T: Clone + Ord,
{
self.map.insert(value, ()).is_none()
}
pub fn replace(&mut self, value: T) -> Option<T>
where
T: Clone + Ord,
{
let existing = self.map.remove_entry(&value).map(|(k, ())| k);
self.map.insert(value, ());
existing
}
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
T: Borrow<Q> + Clone + Ord,
Q: ?Sized + Ord,
{
self.map.remove(value).is_some()
}
pub fn take<Q>(&mut self, value: &Q) -> Option<T>
where
T: Borrow<Q> + Clone + Ord,
Q: ?Sized + Ord,
{
self.map.remove_entry(value).map(|(k, ())| k)
}
pub fn retain<F>(&mut self, mut f: F)
where
T: Clone + Ord,
F: FnMut(&T) -> bool,
{
self.map.retain(|k, ()| f(k));
}
pub fn append(&mut self, other: &mut Self)
where
T: Clone + Ord,
{
self.map.append(&mut other.map);
}
#[allow(clippy::return_self_not_must_use)]
pub fn split_off<Q: Ord>(&mut self, value: &Q) -> Self
where
T: Borrow<Q> + Clone + Ord,
{
OSBTreeSet {
map: self.map.split_off(value),
}
}
pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, T, R, F>
where
T: Clone + Ord,
R: RangeBounds<T>,
F: FnMut(&T) -> bool,
{
ExtractIf {
pred,
inner: self.map.extract_if_inner(range),
}
}
pub fn iter(&self) -> Iter<'_, T> {
Iter {
inner: self.map.keys(),
}
}
#[must_use]
pub const fn len(&self) -> usize {
self.map.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.map.is_empty()
}
}
impl<T: Hash> Hash for OSBTreeSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.map.hash(state);
}
}
impl<T: PartialEq> PartialEq for OSBTreeSet<T> {
fn eq(&self, other: &OSBTreeSet<T>) -> bool {
self.map == other.map
}
}
impl<T: Eq> Eq for OSBTreeSet<T> {}
impl<T: PartialOrd> PartialOrd for OSBTreeSet<T> {
fn partial_cmp(&self, other: &OSBTreeSet<T>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T: Ord> Ord for OSBTreeSet<T> {
fn cmp(&self, other: &OSBTreeSet<T>) -> Ordering {
self.map.cmp(&other.map)
}
}
impl<T: Clone + Ord> Clone for OSBTreeSet<T> {
fn clone(&self) -> Self {
OSBTreeSet {
map: self.map.clone(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for OSBTreeSet<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> Default for OSBTreeSet<T> {
fn default() -> Self {
OSBTreeSet::new()
}
}
impl<T: Ord + Clone> FromIterator<T> for OSBTreeSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut set = OSBTreeSet::new();
set.extend(iter);
set
}
}
impl<T: Ord + Clone> Extend<T> for OSBTreeSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for value in iter {
self.insert(value);
}
}
}
impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for OSBTreeSet<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
for &value in iter {
self.insert(value);
}
}
}
impl<T: Ord + Clone> Sub<&OSBTreeSet<T>> for &OSBTreeSet<T> {
type Output = OSBTreeSet<T>;
fn sub(self, rhs: &OSBTreeSet<T>) -> OSBTreeSet<T> {
self.difference(rhs).cloned().collect()
}
}
impl<T: Ord + Clone> BitXor<&OSBTreeSet<T>> for &OSBTreeSet<T> {
type Output = OSBTreeSet<T>;
fn bitxor(self, rhs: &OSBTreeSet<T>) -> OSBTreeSet<T> {
self.symmetric_difference(rhs).cloned().collect()
}
}
impl<T: Ord + Clone> BitAnd<&OSBTreeSet<T>> for &OSBTreeSet<T> {
type Output = OSBTreeSet<T>;
fn bitand(self, rhs: &OSBTreeSet<T>) -> OSBTreeSet<T> {
self.intersection(rhs).cloned().collect()
}
}
impl<T: Ord + Clone> BitOr<&OSBTreeSet<T>> for &OSBTreeSet<T> {
type Output = OSBTreeSet<T>;
fn bitor(self, rhs: &OSBTreeSet<T>) -> OSBTreeSet<T> {
self.union(rhs).cloned().collect()
}
}
impl<T: Ord + Clone, const N: usize> From<[T; N]> for OSBTreeSet<T> {
fn from(arr: [T; N]) -> Self {
arr.into_iter().collect()
}
}
impl<T: Clone + Ord> IntoIterator for OSBTreeSet<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter {
inner: self.map.into_keys(),
}
}
}
impl<'a, T> IntoIterator for &'a OSBTreeSet<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
fn last(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.inner.next_back()
}
}
impl<T> ExactSizeIterator for Iter<'_, T> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<T> FusedIterator for Iter<'_, T> {}
impl<T> Clone for Iter<'_, T> {
fn clone(&self) -> Self {
Iter {
inner: self.inner.clone(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Iter").field("inner", &self.inner).finish()
}
}
impl<T> Default for Iter<'_, T> {
fn default() -> Self {
Iter {
inner: Keys::default(),
}
}
}
impl<T: Clone + Ord> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T: Clone + Ord> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back()
}
}
impl<T: Clone + Ord> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<T: Clone + Ord> FusedIterator for IntoIter<T> {}
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IntoIter").field("inner", &self.inner).finish()
}
}
impl<T> Default for IntoIter<T> {
fn default() -> Self {
IntoIter {
inner: IntoKeys::default(),
}
}
}
impl<'a, T> Iterator for Range<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next().map(|(k, ())| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, T> DoubleEndedIterator for Range<'a, T> {
fn next_back(&mut self) -> Option<&'a T> {
self.inner.next_back().map(|(k, ())| k)
}
}
impl<T> FusedIterator for Range<'_, T> {}
impl<T> Clone for Range<'_, T> {
fn clone(&self) -> Self {
Range {
inner: self.inner.clone(),
}
}
}
impl<T> Default for Range<'_, T> {
fn default() -> Self {
Range {
inner: MapRange::default(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for Range<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Range").field("inner", &self.inner).finish()
}
}
impl<'a, T: Ord + Clone> 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,
} => loop {
let self_next = self_iter.next()?;
loop {
match other_iter.peek() {
None => return Some(self_next),
Some(&other_next) => match self_next.cmp(other_next) {
Less => return Some(self_next),
Equal => {
other_iter.next();
break;
}
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 (lower, upper) = match &self.inner {
DifferenceInner::Stitch {
self_iter,
other_iter,
} => {
let self_len = self_iter.len();
let other_len = other_iter.len();
(self_len.saturating_sub(other_len), self_len)
}
DifferenceInner::Search {
self_iter,
..
} => {
(0, self_iter.len())
}
DifferenceInner::Iterate(iter) => {
let len = iter.len();
(len, len)
}
};
(lower, Some(upper))
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord + Clone> FusedIterator for Difference<'_, T> {}
impl<T> Clone for Difference<'_, T> {
fn clone(&self) -> Self {
Difference {
inner: match &self.inner {
DifferenceInner::Stitch {
self_iter,
other_iter,
} => DifferenceInner::Stitch {
self_iter: self_iter.clone(),
other_iter: other_iter.clone(),
},
DifferenceInner::Search {
self_iter,
other_set,
} => DifferenceInner::Search {
self_iter: self_iter.clone(),
other_set,
},
DifferenceInner::Iterate(iter) => DifferenceInner::Iterate(iter.clone()),
},
}
}
}
impl<T: fmt::Debug> fmt::Debug for Difference<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Difference").field("inner", &self.inner).finish()
}
}
impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match self.inner.nexts(core::cmp::Ord::cmp) {
(None, None) => return None,
(Some(a), None) => return Some(a),
(None, Some(b)) => return Some(b),
(Some(_), Some(_)) => {
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.inner.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> Clone for SymmetricDifference<'_, T> {
fn clone(&self) -> Self {
SymmetricDifference {
inner: self.inner.clone(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for SymmetricDifference<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SymmetricDifference").field("inner", &self.inner).finish()
}
}
impl<'a, T: Ord + Clone> Iterator for Intersection<'a, T> {
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(Some(_)) => (1, Some(1)),
IntersectionInner::Answer(None) => (0, Some(0)),
}
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord + Clone> FusedIterator for Intersection<'_, T> {}
impl<T> Clone for Intersection<'_, T> {
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<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Intersection").field("inner", &self.inner).finish()
}
}
impl<'a, T: Ord> Iterator for Union<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
match self.inner.nexts(core::cmp::Ord::cmp) {
(None, None) => None,
(Some(a), None | Some(_)) => Some(a),
(None, Some(b)) => Some(b),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.inner.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> Clone for Union<'_, T> {
fn clone(&self) -> Self {
Union {
inner: self.inner.clone(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for Union<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Union").field("inner", &self.inner).finish()
}
}
impl<T, R, F> fmt::Debug for ExtractIf<'_, T, R, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExtractIf").finish_non_exhaustive()
}
}
impl<T, R, F> Iterator for ExtractIf<'_, T, R, F>
where
R: RangeBounds<T>,
F: FnMut(&T) -> bool,
T: Clone + Ord,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let pred = &mut self.pred;
self.inner.next(&mut |k, ()| pred(k)).map(|(k, ())| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, R, F> FusedIterator for ExtractIf<'_, T, R, F>
where
R: RangeBounds<T>,
F: FnMut(&T) -> bool,
T: Clone + Ord,
{
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn intersection_answer_some_size_hint() {
let set: OSBTreeSet<i32> = [1].into_iter().collect();
let value = set.first().expect("set contains one value");
let mut intersection = Intersection {
inner: IntersectionInner::Answer(Some(value)),
};
assert_eq!(intersection.size_hint(), (1, Some(1)));
assert_eq!(intersection.next(), Some(&1));
assert_eq!(intersection.next(), None);
}
}