use crate::alloc::Allocator;
use std::borrow::Borrow;
use std::cmp::{Ordering, max, min};
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::iter::{FusedIterator, Peekable};
use std::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
use super::merge_iter::MergeIterInner;
use crate::collections::btree_map as map;
pub use map::{CustomTuning, DefaultTuning, Tuning, UnorderedKeyError};
mod entry;
pub use entry::{Entry, OccupiedEntry, VacantEntry};
const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16;
pub struct BTreeSet<T, A: Tuning = DefaultTuning> {
map: map::BTreeMap<T, (), A>,
}
impl<T> BTreeSet<T> {
#[must_use]
pub const fn new() -> BTreeSet<T> {
BTreeSet {
map: map::BTreeMap::new(),
}
}
#[must_use]
pub const fn new_in<AL>(a: AL) -> BTreeSet<T, CustomTuning<AL>>
where
AL: Allocator + Clone,
{
BTreeSet {
map: map::BTreeMap::with_tuning(CustomTuning::new_in_def(a)),
}
}
}
impl<T, A: Tuning> BTreeSet<T, A> {
#[must_use]
pub const fn with_tuning(atune: A) -> Self {
Self {
map: map::BTreeMap::with_tuning(atune),
}
}
pub const fn len(&self) -> usize {
self.map.len()
}
pub const fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn insert(&mut self, value: T) -> bool
where
T: Ord,
{
self.map.insert(value, ()).is_none()
}
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,
{
self.map.remove_entry(value).map(|(k, _)| k)
}
pub fn replace(&mut self, value: T) -> Option<T>
where
T: Ord,
{
let result = self.map.remove_entry(&value).map(|(k, _v)| k);
self.insert(value);
result
}
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,
{
self.map.get_key_value(value).map(|(k, _)| k)
}
#[inline]
pub fn get_or_insert(&mut self, value: T) -> &T
where
T: Ord,
{
self.map.entry(value).insert_entry(()).into_key()
}
#[inline]
pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
F: FnOnce(&Q) -> T,
{
let mut cursor = self.lower_bound_mut(Bound::Included(value));
if let Some(vr) = cursor.peek_next()
&& vr.borrow() == value
{
} else {
let v = f(value);
cursor.insert_after_unchecked(v);
};
unsafe { cursor.into() }
}
pub fn retain<F>(&mut self, mut f: F)
where
T: Ord,
F: FnMut(&T) -> bool,
{
self.map.retain(|k, _| f(k));
}
#[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 extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F, A>
where
T: Ord,
F: FnMut(&T) -> bool,
{
let source = self.lower_bound_mut(Bound::Unbounded);
ExtractIf { source, pred }
}
pub fn split_off<Q: ?Sized + Ord>(&mut self, value: &Q) -> Self
where
T: Borrow<Q> + Ord,
A: Clone,
{
BTreeSet {
map: self.map.split_off(value),
}
}
pub fn append(&mut self, other: &mut Self)
where
T: Ord,
A: Clone,
{
self.map.append(&mut other.map);
}
pub fn iter(&self) -> Iter<'_, T> {
Iter {
iter: self.map.keys(),
}
}
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 intersection<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Intersection<'a, T, A>
where
T: Ord,
{
if let Some(self_min) = self.first()
&& let Some(self_max) = self.last()
&& let Some(other_min) = other.first()
&& let Some(other_max) = other.last()
{
Intersection {
inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
(Ordering::Greater, _) | (_, Ordering::Less) => IntersectionInner::Answer(None),
(Ordering::Equal, _) => IntersectionInner::Answer(Some(self_min)),
(_, Ordering::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(),
},
},
}
} else {
Intersection {
inner: IntersectionInner::Answer(None),
}
}
}
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 difference<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Difference<'a, T, A>
where
T: Ord,
{
if let Some(self_min) = self.first()
&& let Some(self_max) = self.last()
&& let Some(other_min) = other.first()
&& let Some(other_max) = other.last()
{
Difference {
inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) {
(Ordering::Greater, _) | (_, Ordering::Less) => {
DifferenceInner::Iterate(self.iter())
}
(Ordering::Equal, _) => {
let mut self_iter = self.iter();
self_iter.next();
DifferenceInner::Iterate(self_iter)
}
(_, Ordering::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(),
},
},
}
} else {
Difference {
inner: DifferenceInner::Iterate(self.iter()),
}
}
}
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()))
}
#[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_superset(&self, other: &BTreeSet<T, A>) -> bool
where
T: Ord,
{
other.is_subset(self)
}
#[must_use]
pub fn is_subset(&self, other: &BTreeSet<T, A>) -> bool
where
T: Ord,
{
if self.len() > other.len() {
return false; }
let (Some(self_min), Some(self_max)) = (self.first(), self.last()) else {
return true; };
let (Some(other_min), Some(other_max)) = (other.first(), other.last()) else {
return false; };
let mut self_iter = self.iter();
match self_min.cmp(other_min) {
Ordering::Less => return false, Ordering::Equal => {
self_iter.next(); }
Ordering::Greater => {} };
match self_max.cmp(other_max) {
Ordering::Greater => return false, Ordering::Equal => {
self_iter.next_back(); }
Ordering::Less => {} };
if self_iter.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF {
self_iter.all(|e| other.contains(e))
} else {
let mut other_iter = other.iter();
{
other_iter.next();
other_iter.next_back();
}
self_iter.all(|self1| {
for other1 in other_iter.by_ref() {
match other1.cmp(self1) {
Ordering::Less => continue, Ordering::Equal => return true, Ordering::Greater => return false, }
}
false
})
}
}
pub fn lower_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, T, A>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
Cursor {
inner: self.map.lower_bound(bound),
}
}
pub fn upper_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, T, A>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
Cursor {
inner: self.map.upper_bound(bound),
}
}
pub fn lower_bound_mut<Q>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
CursorMut {
inner: self.map.lower_bound_mut(bound),
}
}
pub fn upper_bound_mut<Q>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
where
T: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
CursorMut {
inner: self.map.upper_bound_mut(bound),
}
}
fn from_sorted_iter<I: Iterator<Item = T>>(iter: I, tuning: A) -> BTreeSet<T, A>
where
T: Ord,
{
let mut set = BTreeSet::with_tuning(tuning);
let save = set.map.set_seq(true);
{
let mut cursor = set.lower_bound_mut(Bound::Unbounded);
for e in iter {
cursor.insert_before_unchecked(e)
}
}
set.map.set_seq(save);
set
}
#[inline]
pub fn entry(&mut self, value: T) -> Entry<'_, T, A>
where
T: Ord,
{
match self.map.entry(value) {
map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
}
}
}
impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
fn from(arr: [T; N]) -> Self {
let mut result = BTreeSet::new();
for e in arr {
result.insert(e);
}
result
}
}
impl<T> Default for BTreeSet<T> {
fn default() -> BTreeSet<T> {
BTreeSet::new()
}
}
impl<T: Hash, A: Tuning> Hash for BTreeSet<T, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.map.hash(state)
}
}
impl<T: PartialEq, A: Tuning> PartialEq for BTreeSet<T, A> {
fn eq(&self, other: &BTreeSet<T, A>) -> bool {
self.map.eq(&other.map)
}
}
impl<T: Eq, A: Tuning> Eq for BTreeSet<T, A> {}
impl<T: PartialOrd, A: Tuning> 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: Tuning> Ord for BTreeSet<T, A> {
fn cmp(&self, other: &BTreeSet<T, A>) -> Ordering {
self.map.cmp(&other.map)
}
}
impl<T: Clone, A: Tuning> Clone for BTreeSet<T, A> {
fn clone(&self) -> Self {
BTreeSet {
map: self.map.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
self.map.clone_from(&source.map);
}
}
impl<T: Debug, A: Tuning> Debug for BTreeSet<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.map.iter()).finish()
}
}
impl<T: Ord> FromIterator<T> for BTreeSet<T> {
fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> BTreeSet<T> {
let mut result = BTreeSet::new();
for k in iter {
result.insert(k);
}
result
}
}
impl<T, A: Tuning> 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: Tuning> 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 Iter<'a, T: 'a> {
iter: map::Keys<'a, T, ()>,
}
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).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: Tuning> 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()
}
}
#[derive(Debug)]
pub struct IntoIter<T, A: Tuning = DefaultTuning> {
iter: map::IntoIter<T, (), A>,
}
impl<T, A: Tuning> DoubleEndedIterator for IntoIter<T, A> {
fn next_back(&mut self) -> Option<T> {
self.iter.next_back().map(|(k, _)| k)
}
}
impl<T, A: Tuning> ExactSizeIterator for IntoIter<T, A> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T, A: Tuning> FusedIterator for IntoIter<T, A> {}
#[derive(Clone)]
pub struct Cursor<'a, K: 'a, A: Tuning = DefaultTuning> {
inner: map::Cursor<'a, K, (), A>,
}
impl<K: Debug> Debug for Cursor<'_, K> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Cursor")
}
}
impl<'a, K, A: Tuning> Cursor<'a, K, A> {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&K> {
self.inner.next().map(|(k, _)| k)
}
pub fn prev(&mut self) -> Option<&K> {
self.inner.prev().map(|(k, _)| k)
}
pub fn peek_next(&self) -> Option<&K> {
self.inner.peek_next().map(|(k, _)| k)
}
pub fn peek_prev(&self) -> Option<&K> {
self.inner.peek_prev().map(|(k, _)| k)
}
}
pub struct CursorMutKey<'a, T: 'a, A: Tuning = DefaultTuning> {
inner: map::CursorMutKey<'a, T, (), A>,
}
impl<K: Debug, A: Tuning> Debug for CursorMutKey<'_, K, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CursorMutKey")
}
}
impl<'a, T: Ord, A: Tuning> CursorMutKey<'a, T, A> {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&mut T> {
self.inner.next().map(|(k, _)| k)
}
pub fn prev(&mut self) -> Option<&mut T> {
self.inner.prev().map(|(k, _)| k)
}
pub fn peek_next(&mut self) -> Option<&mut T> {
self.inner.peek_next().map(|(k, _)| k)
}
pub fn peek_prev(&mut self) -> Option<&mut T> {
self.inner.peek_prev().map(|(k, _)| k)
}
pub fn insert_after_unchecked(&mut self, value: T) {
self.inner.insert_after_unchecked(value, ())
}
pub fn insert_before_unchecked(&mut self, value: T) {
self.inner.insert_before_unchecked(value, ())
}
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_after(value, ())
}
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_before(value, ())
}
pub fn remove_next(&mut self) -> Option<T> {
self.inner.remove_next().map(|(k, _)| k)
}
pub fn remove_prev(&mut self) -> Option<T> {
self.inner.remove_prev().map(|(k, _)| k)
}
}
pub struct CursorMut<'a, T: 'a, A: Tuning = DefaultTuning> {
inner: map::CursorMut<'a, T, (), A>,
}
impl<K: Debug, A: Tuning> Debug for CursorMut<'_, K, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CursorMutKey")
}
}
impl<'a, T: Ord, A: Tuning> CursorMut<'a, T, A> {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&T> {
self.inner.next().map(|(k, _)| k)
}
pub fn prev(&mut self) -> Option<&T> {
self.inner.prev().map(|(k, _)| k)
}
pub fn peek_next(&mut self) -> Option<&T> {
self.inner.peek_next().map(|(k, _)| k)
}
pub fn peek_prev(&mut self) -> Option<&T> {
self.inner.peek_prev().map(|(k, _)| k)
}
pub fn insert_after_unchecked(&mut self, value: T) {
self.inner.insert_after_unchecked(value, ())
}
pub fn insert_before_unchecked(&mut self, value: T) {
self.inner.insert_before_unchecked(value, ())
}
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_after(value, ())
}
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_before(value, ())
}
pub fn remove_next(&mut self) -> Option<T> {
self.inner.remove_next().map(|(k, _)| k)
}
pub fn remove_prev(&mut self) -> Option<T> {
self.inner.remove_prev().map(|(k, _)| k)
}
pub fn with_mutable_key(self) -> CursorMutKey<'a, T, A> {
CursorMutKey {
inner: self.inner.with_mutable_key(),
}
}
unsafe fn into(self) -> &'a T {
unsafe { self.inner.into_mut_key() }
}
}
pub struct ExtractIf<'a, K, F, A: Tuning = DefaultTuning>
where
F: FnMut(&K) -> bool,
{
source: CursorMut<'a, K, A>,
pred: F,
}
impl<K, A: Tuning, F> fmt::Debug for ExtractIf<'_, K, F, A>
where
K: Ord + fmt::Debug,
F: FnMut(&K) -> bool,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("ExtractIf")
.finish_non_exhaustive()
}
}
impl<'a, K, A: Tuning, F> Iterator for ExtractIf<'a, K, F, A>
where
K: Ord,
F: FnMut(&K) -> bool,
{
type Item = K;
fn next(&mut self) -> Option<Self::Item> {
loop {
let k = self.source.peek_next()?;
if (self.pred)(k) {
return self.source.remove_next();
}
self.source.next();
}
}
}
impl<'a, K, A: Tuning, F> FusedIterator for ExtractIf<'a, K, F, A>
where
K: Ord,
F: FnMut(&K) -> bool,
{
}
#[allow(clippy::large_enum_variant)]
#[must_use = "this returns the intersection as an iterator, \
without modifying either input set"]
pub struct Intersection<'a, T: 'a, A: Tuning = DefaultTuning> {
inner: IntersectionInner<'a, T, A>,
}
#[allow(clippy::large_enum_variant)]
enum IntersectionInner<'a, T: 'a, A: Tuning = DefaultTuning> {
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<'a, T: Ord, A: Tuning> 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) {
Ordering::Less => a_next = a.next()?,
Ordering::Greater => b_next = b.next()?,
Ordering::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()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug)]
pub struct Range<'a, T: 'a> {
iter: map::Range<'a, T, ()>,
}
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(),
}
}
}
#[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> fmt::Debug for SymmetricDifference<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("SymmetricDifference").field(&self.0).finish()
}
}
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> {}
#[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> fmt::Debug for Union<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Union").field(&self.0).finish()
}
}
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> {}
#[must_use = "this returns the difference as an iterator, \
without modifying either input set"]
pub struct Difference<'a, T: 'a, A: Tuning> {
inner: DifferenceInner<'a, T, A>,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
enum DifferenceInner<'a, T: 'a, A: Tuning> {
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: Tuning> 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: Tuning> 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(Ordering::Less, |other_next| self_next.cmp(other_next))
{
Ordering::Less => return Some(self_next),
Ordering::Equal => {
self_next = self_iter.next()?;
other_iter.next();
}
Ordering::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: Tuning> FusedIterator for Difference<'_, T, A> {}
impl<T: Ord + Clone, A: Tuning> BitAnd<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T, A>;
fn bitand(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.intersection(rhs).cloned(), self.map.get_tuning())
}
}
impl<T: Ord + Clone, A: Tuning> BitOr<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T, A>;
fn bitor(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.union(rhs).cloned(), self.map.get_tuning())
}
}
impl<T: Ord + Clone, A: Tuning> BitXor<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T, A>;
fn bitxor(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(
self.symmetric_difference(rhs).cloned(),
self.map.get_tuning(),
)
}
}
impl<T: Ord + Clone, A: Tuning> Sub<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T, A>;
fn sub(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.difference(rhs).cloned(), self.map.get_tuning())
}
}
impl<T: Ord, A: Tuning> Extend<T> for BTreeSet<T, A> {
#[inline]
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
iter.into_iter().for_each(move |elem| {
self.insert(elem);
});
}
}
impl<'a, T: 'a + Ord + Copy, A: Tuning> Extend<&'a T> for BTreeSet<T, A> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
}
}
#[cfg(test)]
mod tests;