use std::{borrow::Borrow, cmp::Ord};
use std::{cell, collections};
use super::{Atom, AtomProxy, StablePointer};
pub struct StableSet<T: StablePointer> {
set: cell::UnsafeCell<collections::BTreeSet<T>>,
}
impl<T> StableSet<T>
where
T: StablePointer + Ord,
{
pub fn new() -> Self {
StableSet {
set: cell::UnsafeCell::new(collections::BTreeSet::new()),
}
}
pub fn add_element<'a, 'b, U>(
&'a self,
element: &'b U,
) -> Atom<'a, <T as std::ops::Deref>::Target>
where
U: ?Sized + AtomProxy<T>,
T: Borrow<<U as AtomProxy<T>>::Compare>,
{
unsafe {
let name_cmp = element.to_compare();
let inner = &mut *self.set.get();
if let Some(b) = inner.get(name_cmp) {
let buf = &*(b as *const T);
Atom::new(buf.borrow())
} else {
inner.insert(element.to_owned());
let buf = &*(inner.get(name_cmp).unwrap() as *const T);
Atom::new(buf.borrow())
}
}
}
}