#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::marker::PhantomData;
use crate::{
BorrowError,
ElementRef,
ElementRefMut,
Handle,
Registry,
};
pub trait StrongHandle: From<Handle> {
fn handle(&self) -> Handle;
}
#[derive(Default)]
pub struct StrongRegistry<H, T> {
registry: Registry<T>,
phantom_handle: PhantomData<H>,
}
impl<H, T> StrongRegistry<H, T>
where
H: StrongHandle,
{
pub fn new() -> Self {
Self {
registry: Registry::new(),
phantom_handle: PhantomData,
}
}
pub fn with_capacity(size: usize) -> Self {
Self {
registry: Registry::with_capacity(size),
phantom_handle: PhantomData,
}
}
pub fn is_empty(&self) -> bool {
self.registry.is_empty()
}
pub fn len(&self) -> usize {
self.registry.len()
}
pub fn register(&self, value: T) -> H {
H::from(self.registry.register(value))
}
pub fn register_extend<I>(&self, iterable: I) -> (H, H)
where
I: IntoIterator<Item = T>,
{
let (a, b) = self.registry.register_extend(iterable);
(H::from(a), H::from(b))
}
pub fn reserve(&self, additional: usize) {
self.registry.reserve(additional)
}
pub fn into_vec(self) -> Vec<T> {
self.registry.into_vec()
}
pub fn iter(&self) -> impl Iterator<Item = Result<ElementRef<T>, BorrowError>> {
self.registry.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = Result<ElementRefMut<T>, BorrowError>> {
self.registry.iter_mut()
}
pub fn get_unchecked(&self, handle: H) -> ElementRef<T> {
self.registry.get_unchecked(handle.handle())
}
pub fn get(&self, handle: H) -> Result<ElementRef<T>, BorrowError> {
self.registry.get(handle.handle())
}
pub fn get_mut_unchecked(&self, handle: H) -> ElementRefMut<T> {
self.registry.get_mut_unchecked(handle.handle())
}
pub fn get_mut(&self, handle: H) -> Result<ElementRefMut<T>, BorrowError> {
self.registry.get_mut(handle.handle())
}
pub fn safe_to_drop(&mut self) -> bool {
self.registry.safe_to_drop()
}
}
#[cfg(test)]
mod strong_registry_test {
use core::cell::Cell;
use crate::{
Handle,
StrongHandle,
StrongRegistry,
};
struct DropCounter<'c>(&'c Cell<u32>);
impl<'c> Drop for DropCounter<'c> {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct NodeHandle(Handle);
impl From<Handle> for NodeHandle {
fn from(value: Handle) -> Self {
Self(value)
}
}
impl StrongHandle for NodeHandle {
fn handle(&self) -> Handle {
self.0
}
}
struct Node<'d, T> {
parent: Option<NodeHandle>,
value: T,
#[allow(dead_code)]
drop_counter: DropCounter<'d>,
}
impl<'a, 'd, T> Node<'d, T> {
pub fn new(parent: Option<NodeHandle>, value: T, drop_counter: DropCounter<'d>) -> Self {
Self {
parent,
value,
drop_counter,
}
}
}
#[test]
fn works_exactly_like_registry() {
let drop_counter = Cell::new(0);
{
let registry = StrongRegistry::with_capacity(2);
assert!(registry.is_empty());
let mut handle = registry.register(Node::new(None, 1, DropCounter(&drop_counter)));
assert_eq!(registry.len(), 1);
assert!(!registry.is_empty());
handle = registry.register(Node::new(Some(handle), 2, DropCounter(&drop_counter)));
assert_eq!(registry.len(), 2);
handle = registry.register(Node::new(Some(handle), 3, DropCounter(&drop_counter)));
assert_eq!(registry.len(), 3);
handle = registry.register(Node::new(Some(handle), 4, DropCounter(&drop_counter)));
assert_eq!(registry.len(), 4);
let mut node = registry.get(handle).unwrap();
assert_eq!(node.value, 4);
node = registry.get(node.parent.unwrap()).unwrap();
assert_eq!(node.value, 3);
node = registry.get(node.parent.unwrap()).unwrap();
assert_eq!(node.value, 2);
node = registry.get(node.parent.unwrap()).unwrap();
assert_eq!(node.value, 1);
assert_eq!(node.parent, None);
assert_eq!(drop_counter.get(), 0);
}
assert_eq!(drop_counter.get(), 4);
}
}