use core::borrow::Borrow;
use core::fmt::{self, Debug};
use core::iter::FromIterator;
use core::ops::RangeBounds;
use core::ops::{BitAnd, BitOr, BitXor, Sub};
use crate::set_types::{
Difference, Intersection, IntoIter, Iter, Range, SymmetricDifference, Union,
};
use crate::tree::{SgError, SgTree};
#[derive(Default, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
pub struct SgSet<T: Ord + Default, const N: usize> {
pub(crate) bst: SgTree<T, (), N>,
}
impl<T: Ord + Default, const N: usize> SgSet<T, N> {
pub fn new() -> Self {
SgSet { bst: SgTree::new() }
}
#[doc(alias = "rebalance")]
#[doc(alias = "alpha")]
pub fn set_rebal_param(&mut self, alpha_num: f32, alpha_denom: f32) -> Result<(), SgError> {
self.bst.set_rebal_param(alpha_num, alpha_denom)
}
#[doc(alias = "rebalance")]
#[doc(alias = "alpha")]
pub fn rebal_param(&self) -> (f32, f32) {
self.bst.rebal_param()
}
pub fn capacity(&self) -> usize {
self.bst.capacity()
}
pub fn append(&mut self, other: &mut SgSet<T, N>)
where
T: Ord,
{
self.bst.append(&mut other.bst);
}
pub fn try_append(&mut self, other: &mut SgSet<T, N>) -> Result<(), SgError> {
self.bst.try_append(&mut other.bst)
}
pub fn insert(&mut self, value: T) -> bool
where
T: Ord,
{
self.bst.insert(value, ()).is_none()
}
pub fn try_insert(&mut self, value: T) -> Result<bool, SgError>
where
T: Ord,
{
match self.bst.try_insert(value, ()) {
Ok(opt_val) => Ok(opt_val.is_none()),
Err(_) => Err(SgError::StackCapacityExceeded),
}
}
pub fn try_extend<I: ExactSizeIterator + IntoIterator<Item = T>>(
&mut self,
iter: I,
) -> Result<(), SgError> {
if iter.len() <= (self.capacity() - self.len()) {
let map: crate::SgMap<T, (), N> = iter.into_iter().map(|e| (e, ())).collect();
self.bst.try_extend(map.into_iter())
} else {
Err(SgError::StackCapacityExceeded)
}
}
pub fn try_from_iter<I: ExactSizeIterator + IntoIterator<Item = T>>(
iter: I,
) -> Result<Self, SgError> {
match iter.len() <= SgTree::<T, (), N>::max_capacity() {
true => Ok(SgSet::from_iter(iter)),
false => Err(SgError::MaximumCapacityExceeded),
}
}
pub fn iter(&self) -> Iter<'_, T, N> {
Iter::new(self)
}
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.bst.remove(value).is_some()
}
pub fn split_off<Q>(&mut self, value: &Q) -> SgSet<T, N>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
SgSet {
bst: self.bst.split_off(value),
}
}
pub fn replace(&mut self, value: T) -> Option<T>
where
T: Ord,
{
let removed = self.bst.remove_entry(&value).map(|(k, _)| k);
self.insert(value);
removed
}
pub fn try_replace(&mut self, value: T) -> Result<Option<T>, SgError>
where
T: Ord,
{
let removed = self.bst.remove_entry(&value).map(|(k, _)| k);
self.try_insert(value)?;
Ok(removed)
}
pub fn take<Q>(&mut self, value: &Q) -> Option<T>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.bst.remove_entry(value).map(|(k, _)| k)
}
pub fn retain<F>(&mut self, mut f: F)
where
T: Ord,
F: FnMut(&T) -> bool,
{
self.bst.retain(|k, _| f(k));
}
pub fn get<Q>(&self, value: &Q) -> Option<&T>
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.bst.get_key_value(value).map(|(k, _)| k)
}
pub fn clear(&mut self) {
self.bst.clear()
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
T: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.bst.contains_key(value)
}
pub fn first(&self) -> Option<&T>
where
T: Ord,
{
self.bst.first_key()
}
pub fn pop_first(&mut self) -> Option<T>
where
T: Ord,
{
self.bst.pop_first().map(|(k, _)| k)
}
pub fn last(&self) -> Option<&T>
where
T: Ord,
{
self.bst.last_key()
}
pub fn pop_last(&mut self) -> Option<T>
where
T: Ord,
{
self.bst.pop_last().map(|(k, _)| k)
}
pub fn len(&self) -> usize {
self.bst.len()
}
pub fn range<K, R>(&self, range: R) -> Range<'_, T, N>
where
K: Ord + ?Sized,
T: Borrow<K> + Ord,
R: RangeBounds<K>,
{
SgTree::<T, (), N>::assert_valid_range(&range);
Range {
table: self,
node_idx_iter: self.bst.range_search(&range).into_iter(),
}
}
pub fn difference(&self, other: &SgSet<T, N>) -> Difference<T, N>
where
T: Ord,
{
Difference::new(self, other)
}
pub fn symmetric_difference<'a>(&'a self, other: &'a SgSet<T, N>) -> SymmetricDifference<T, N>
where
T: Ord,
{
SymmetricDifference::new(self, other)
}
pub fn intersection(&self, other: &SgSet<T, N>) -> Intersection<T, N>
where
T: Ord,
{
Intersection::new(self, other)
}
pub fn union<'a>(&'a self, other: &'a SgSet<T, N>) -> Union<T, N>
where
T: Ord,
{
Union::new(self, other)
}
pub fn is_empty(&self) -> bool {
self.bst.is_empty()
}
pub fn is_full(&self) -> bool {
self.bst.is_full()
}
pub fn is_disjoint(&self, other: &SgSet<T, N>) -> bool
where
T: Ord,
{
self.intersection(other).count() == 0
}
pub fn is_subset(&self, other: &SgSet<T, N>) -> bool
where
T: Ord,
{
self.intersection(other).count() == self.len()
}
pub fn is_superset(&self, other: &SgSet<T, N>) -> bool
where
T: Ord,
{
other.is_subset(self)
}
}
impl<T, const N: usize> Debug for SgSet<T, N>
where
T: Ord + Default + Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set()
.entries(self.bst.iter().map(|(k, _)| k))
.finish()
}
}
impl<T, const N: usize> From<[T; N]> for SgSet<T, N>
where
T: Ord + Default,
{
#[doc(alias = "tryfrom")]
#[doc(alias = "try_from")]
#[doc(alias = "TryFrom")]
fn from(arr: [T; N]) -> Self {
IntoIterator::into_iter(arr).collect()
}
}
impl<T, const N: usize> FromIterator<T> for SgSet<T, N>
where
T: Ord + Default,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut sgs = SgSet::new();
sgs.bst = SgTree::from_iter(iter.into_iter().map(|e| (e, ())));
sgs
}
}
impl<T, const N: usize> Extend<T> for SgSet<T, N>
where
T: Ord + Default,
{
fn extend<TreeIter: IntoIterator<Item = T>>(&mut self, iter: TreeIter) {
self.bst.extend(iter.into_iter().map(|e| (e, ())));
}
}
impl<'a, T, const N: usize> Extend<&'a T> for SgSet<T, N>
where
T: 'a + Ord + Default + Copy,
{
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
}
}
impl<'a, T: Ord + Default, const N: usize> IntoIterator for &'a SgSet<T, N> {
type Item = &'a T;
type IntoIter = Iter<'a, T, N>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T: Ord + Default, const N: usize> IntoIterator for SgSet<T, N> {
type Item = T;
type IntoIter = IntoIter<T, N>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
impl<T: Ord + Default + Clone, const N: usize> Sub<&SgSet<T, N>> for &SgSet<T, N> {
type Output = SgSet<T, N>;
fn sub(self, rhs: &SgSet<T, N>) -> SgSet<T, N> {
self.difference(rhs).cloned().collect()
}
}
impl<T: Ord + Default + Clone, const N: usize> BitAnd<&SgSet<T, N>> for &SgSet<T, N> {
type Output = SgSet<T, N>;
fn bitand(self, rhs: &SgSet<T, N>) -> SgSet<T, N> {
self.intersection(rhs).cloned().collect()
}
}
impl<T: Ord + Default + Clone, const N: usize> BitOr<&SgSet<T, N>> for &SgSet<T, N> {
type Output = SgSet<T, N>;
fn bitor(self, rhs: &SgSet<T, N>) -> SgSet<T, N> {
self.union(rhs).cloned().collect()
}
}
impl<T: Ord + Default + Clone, const N: usize> BitXor<&SgSet<T, N>> for &SgSet<T, N> {
type Output = SgSet<T, N>;
fn bitxor(self, rhs: &SgSet<T, N>) -> SgSet<T, N> {
self.symmetric_difference(rhs).cloned().collect()
}
}