#![forbid(unsafe_code)]
use core::fmt;
use core::iter::FusedIterator;
use core::ops::BitOr;
use super::BBTreeSet;
use super::merge::{HeldSide, MergeSides};
use crate::allocator::Allocator;
use crate::inline_key::{Auto, InlineKeyStrategy};
#[must_use = "this returns the union as an iterator, \
without modifying either input set"]
pub struct Union<'a, T: 'a, S = Auto> {
sides: MergeSides<'a, T, S>,
held: HeldSide,
}
impl<'a, T: Ord, S: InlineKeyStrategy<T>> Iterator for Union<'a, T, S> {
type Item = &'a T;
#[inline(always)]
fn next(&mut self) -> Option<&'a T> {
let (step, held) = self.sides.next_step()?;
self.held = held;
Some(step.element())
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.sides.lens();
(a_len.max(b_len), Some(a_len + b_len))
}
fn fold<A, F>(self, accumulator: A, mut fold: F) -> A
where
F: FnMut(A, Self::Item) -> A,
{
self.sides
.fold_steps::<A, true, true>(accumulator, |accumulator, step| {
fold(accumulator, step.element())
})
}
fn min(mut self) -> Option<&'a T> {
self.next()
}
}
impl<T: Ord, S: InlineKeyStrategy<T>> FusedIterator for Union<'_, T, S> {}
impl<T, S> Clone for Union<'_, T, S> {
fn clone(&self) -> Self {
Self {
sides: self.sides.clone(),
held: self.held,
}
}
}
impl<T: fmt::Debug, S: InlineKeyStrategy<T>> fmt::Debug for Union<'_, T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Union")
.field(&self.sides.printed_as_merge_iter(self.held))
.finish()
}
}
impl<T, S: InlineKeyStrategy<T>, A: Allocator + Clone> BBTreeSet<T, S, A> {
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S>
where
T: Ord,
{
Union {
sides: MergeSides::new(self.iter(), other.iter()),
held: HeldSide::Neither,
}
}
}
impl<T: Ord + Clone, S: InlineKeyStrategy<T>, A: Allocator + Clone> BitOr<&BBTreeSet<T, S, A>>
for &BBTreeSet<T, S, A>
{
type Output = BBTreeSet<T, S, A>;
fn bitor(self, rhs: &BBTreeSet<T, S, A>) -> BBTreeSet<T, S, A> {
BBTreeSet::from_ascending(self.union(rhs).cloned(), self.allocator().clone())
}
}