zone-alloc 0.4.4

Containers for zone-based data allocation.
Documentation
#[cfg(not(feature = "std"))]
extern crate alloc;

#[cfg(feature = "std")]
extern crate core;

#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::{
    borrow::Borrow,
    ops::{
        Deref,
        DerefMut,
    },
};

use hashbrown::HashMap;

/// Trait for the key type of keyed registries.
pub trait Key = core::cmp::Eq + core::hash::Hash;

/// The internal container for a registry type, which associates zone-allocated data with a key
/// (which may or may not be generated by the caller).
pub(crate) trait RegistryContainer<K, V> {
    type Item;
    fn new() -> Self;
    fn with_capacity(size: usize) -> Self;
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool;
    fn reserve(&mut self, additional: usize);
    fn get<'a, 'b>(&'a self, key: &K) -> Option<&'b V>
    where
        'a: 'b;
    #[allow(unused)]
    fn get_mut<'a, 'b>(&'a mut self, key: &K) -> Option<&'b mut V>
    where
        'a: 'b;
}

/// The internal container for a keyed registry type, which associates zone-allocated data with a
/// caller-specified key.
pub(crate) trait KeyedRegistryContainer<K, V>:
    RegistryContainer<K, V, Item = (K, V)>
{
    #[allow(unused)]
    fn contains_key<R>(&self, key: &R) -> bool
    where
        K: Borrow<R>,
        R: Key + ?Sized;
    fn get<'a, 'b, R>(&'a self, key: &R) -> Option<&'b V>
    where
        'a: 'b,
        K: Borrow<R>,
        R: Key + ?Sized;
    #[allow(unused)]
    fn get_mut<'a, 'b, R>(&'a mut self, key: &R) -> Option<&'b mut V>
    where
        'a: 'b,
        K: Borrow<R>,
        R: Key + ?Sized;
}

impl<T> RegistryContainer<usize, T> for Vec<T> {
    type Item = T;

    fn new() -> Self {
        Vec::new()
    }

    fn with_capacity(size: usize) -> Self {
        Vec::with_capacity(size)
    }

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }

    fn reserve(&mut self, additional: usize) {
        self.reserve(additional)
    }

    fn get<'a, 'b>(&'a self, key: &usize) -> Option<&'b T>
    where
        'a: 'b,
    {
        self.deref().get(*key)
    }

    fn get_mut<'a, 'b>(&'a mut self, key: &usize) -> Option<&'b mut T>
    where
        'a: 'b,
    {
        self.deref_mut().get_mut(*key)
    }
}

impl<K, V> RegistryContainer<K, V> for HashMap<K, V>
where
    K: Key,
{
    type Item = (K, V);

    fn new() -> Self {
        HashMap::new()
    }

    fn with_capacity(size: usize) -> Self {
        HashMap::with_capacity(size)
    }

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.is_empty()
    }

    fn reserve(&mut self, additional: usize) {
        self.reserve(additional)
    }

    fn get<'a, 'b>(&'a self, key: &K) -> Option<&'b V>
    where
        'a: 'b,
    {
        self.get(key)
    }

    fn get_mut<'a, 'b>(&'a mut self, key: &K) -> Option<&'b mut V>
    where
        'a: 'b,
    {
        self.get_mut(key)
    }
}

impl<K, V> KeyedRegistryContainer<K, V> for HashMap<K, V>
where
    K: Key,
{
    fn contains_key<R>(&self, key: &R) -> bool
    where
        K: Borrow<R>,
        R: Key + ?Sized,
    {
        self.contains_key(key)
    }

    fn get<'a, 'b, R>(&'a self, key: &R) -> Option<&'b V>
    where
        'a: 'b,
        K: Borrow<R>,
        R: Key + ?Sized,
    {
        self.get(key)
    }

    fn get_mut<'a, 'b, R>(&'a mut self, key: &R) -> Option<&'b mut V>
    where
        'a: 'b,
        K: Borrow<R>,
        R: Key + ?Sized,
    {
        self.get_mut(key)
    }
}