use std::{
borrow::Borrow,
fmt::{Debug, Formatter},
hash::{Hash, Hasher},
marker::PhantomData,
ops::{Deref, Range},
};
pub trait BlazeMapId: Copy {
type OrigType: 'static + Clone + Eq + Hash;
#[doc(hidden)]
type TypeInfoContainer: TypeInfoContainer<OrigType = Self::OrigType>;
#[doc(hidden)]
fn get_offset(self) -> usize;
#[doc(hidden)]
unsafe fn from_offset_unchecked(offset: usize) -> Self;
}
pub trait BlazeMapIdWrapper: BlazeMapId {
unsafe fn new(type_info_container: &Self::TypeInfoContainer, key: Self::OrigType) -> Self;
}
pub trait BlazeMapIdStatic: BlazeMapId {
#[inline]
#[must_use]
fn all_instances_iter() -> AllInstancesIter<Self> {
let num_elems = Self::static_container()
.capacity_info_provider()
.offset_capacity();
AllInstancesIter {
range: 0..num_elems,
phantom: PhantomData,
}
}
#[doc(hidden)]
fn static_container() -> &'static Self::TypeInfoContainer;
}
#[doc(hidden)]
pub trait WrapKey<I: BlazeMapId> {
fn wrap_key(&self, key: I::OrigType) -> I;
}
pub trait TypeInfoContainer: 'static {
type OrigType;
#[doc(hidden)]
fn capacity_info_provider(&self) -> impl Deref<Target = impl CapacityInfoProvider>;
#[doc(hidden)]
fn key_by_offset_provider(
&self,
) -> impl Deref<Target = impl KeyByOffsetProvider<Self::OrigType>>;
}
#[doc(hidden)]
pub trait CapacityInfoProvider {
fn offset_capacity(&self) -> usize;
}
#[doc(hidden)]
pub trait KeyByOffsetProvider<K> {
unsafe fn key_by_offset_unchecked(&self, offset: usize) -> impl Borrow<K>;
}
pub struct AllInstancesIter<T> {
pub(crate) range: Range<usize>,
pub(crate) phantom: PhantomData<T>,
}
impl<T> Clone for AllInstancesIter<T> {
#[inline]
fn clone(&self) -> Self {
Self {
range: self.range.clone(),
phantom: PhantomData,
}
}
}
impl<T> Debug for AllInstancesIter<T> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.range)
}
}
impl<T> PartialEq for AllInstancesIter<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.range == other.range
}
}
impl<T> Eq for AllInstancesIter<T> {}
impl<T> Hash for AllInstancesIter<T> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.range.hash(state);
}
}
impl<T> Iterator for AllInstancesIter<T>
where
T: BlazeMapId,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let next_offset = self.range.next()?;
Some(unsafe { T::from_offset_unchecked(next_offset) })
}
}
impl<T> DoubleEndedIterator for AllInstancesIter<T>
where
T: BlazeMapId,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let next_back_offset = self.range.next_back()?;
Some(unsafe { T::from_offset_unchecked(next_back_offset) })
}
}
impl<T> ExactSizeIterator for AllInstancesIter<T>
where
T: BlazeMapId,
{
#[inline]
fn len(&self) -> usize {
self.range.len()
}
}