use crate::{
iter::{AAIntoIter, AAIter},
node::{AANode, TraverseStep}
};
use alloc::vec::Vec;
use core::{
borrow::Borrow,
cmp::Ordering,
fmt::{self, Debug},
iter::FromIterator,
mem
};
#[derive(Clone)]
pub struct AATreeSet<T> {
root: AANode<T>,
len: usize
}
impl<T> Default for AATreeSet<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Debug> Debug for AATreeSet<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("[")?;
for (i, v) in self.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
v.fmt(f)?;
}
f.write_str("]")
}
}
impl<T: PartialEq> PartialEq for AATreeSet<T> {
fn eq(&self, other: &Self) -> bool {
self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
}
}
impl<T: Eq> Eq for AATreeSet<T> {}
impl<T: PartialOrd> PartialOrd for AATreeSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl<T: Ord> Ord for AATreeSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl<T> AATreeSet<T> {
pub const fn new() -> Self {
Self {
root: AANode::new(),
len: 0
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn clear(&mut self) {
self.root = AANode::new();
self.len = 0;
}
pub fn iter(&self) -> AAIter<'_, T, &T> {
self.into_iter()
}
}
impl<T: Ord> AATreeSet<T> {
pub fn insert(&mut self, value: T) -> bool {
let inserted = self.root.insert(value);
if inserted {
self.len += 1;
}
inserted
}
pub fn append(&mut self, other: &mut Self) {
self.extend(mem::take(other));
}
pub fn first(&self) -> Option<&T> {
self.root
.traverse(|_| TraverseStep::Left, |content, sub| sub.or(Some(content)))
}
pub fn last(&self) -> Option<&T> {
self.root.traverse(
|_| TraverseStep::Right,
|content, sub| sub.or(Some(content))
)
}
pub fn pop_first(&mut self) -> Option<T> {
self.root.remove_successor().inspect(|_| self.len -= 1)
}
pub fn pop_last(&mut self) -> Option<T> {
self.root.remove_predecessor().inspect(|_| self.len -= 1)
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized
{
self.root
.traverse(
|content| match content.borrow().cmp(value) {
Ordering::Greater => TraverseStep::Left,
Ordering::Less => TraverseStep::Right,
Ordering::Equal => TraverseStep::Value(Some(()))
},
|_, sub| sub
)
.is_some()
}
pub fn first_at_or_after<Q>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized
{
self.root.traverse(
|content| match content.borrow().cmp(value) {
Ordering::Greater => TraverseStep::Left,
Ordering::Less => TraverseStep::Right,
Ordering::Equal => TraverseStep::Value(Some(content))
},
|content, sub| match sub {
None if content.borrow() > value => Some(content),
sub => sub
}
)
}
pub fn last_at_or_before<Q>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized
{
self.root.traverse(
|content| match content.borrow().cmp(value) {
Ordering::Greater => TraverseStep::Left,
Ordering::Less => TraverseStep::Right,
Ordering::Equal => TraverseStep::Value(Some(content))
},
|content, sub| match sub {
None if content.borrow() < value => Some(content),
sub => sub
}
)
}
pub fn remove<Q>(&mut self, x: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized
{
self.root.remove(x).inspect(|_| self.len -= 1).is_some()
}
pub fn take<Q>(&mut self, x: &Q) -> Option<T>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized
{
self.root.remove(x).inspect(|_| self.len -= 1)
}
}
impl<T: Ord> FromIterator<T> for AATreeSet<T> {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>
{
let mut set = Self::new();
for value in iter {
set.insert(value);
}
set
}
}
impl<T: Ord, const N: usize> From<[T; N]> for AATreeSet<T> {
fn from(array: [T; N]) -> Self {
array.into_iter().collect()
}
}
impl<T: Ord> From<Vec<T>> for AATreeSet<T> {
fn from(vec: Vec<T>) -> Self {
vec.into_iter().collect()
}
}
impl<T: Ord> Extend<T> for AATreeSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for value in iter {
self.insert(value);
}
}
}
impl<'a, T: Ord + Copy + 'a> Extend<&'a T> for AATreeSet<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied())
}
}
impl<T> IntoIterator for AATreeSet<T> {
type Item = T;
type IntoIter = AAIntoIter<T, T>;
fn into_iter(self) -> Self::IntoIter {
AAIntoIter::new(self.root, self.len)
}
}
impl<'a, T> IntoIterator for &'a AATreeSet<T> {
type Item = &'a T;
type IntoIter = AAIter<'a, T, &'a T>;
fn into_iter(self) -> Self::IntoIter {
AAIter::new(&self.root, self.len)
}
}