use std::marker::PhantomData;
use std::ops::Deref;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::DerefMut;
use std::slice::SliceIndex;
use crate::VectorizableTrait;
use crate::IntegerVector;
use crate::Serializer;
use crate::Serializable;
pub trait ContainerIndex
where
Self: From<Self::ValueType>
+ std::hash::Hash + std::cmp::Ord + std::cmp::PartialOrd + std::cmp::PartialEq
+ std::cmp::Eq + Default + Clone + Copy,
Self::ValueType: Sized + VectorizableTrait<IntegerVector>
{
type ValueType = u32;
fn index(&self) -> i32;
fn get_value(&self) -> Self::ValueType;
fn set_value(&mut self, v: Self::ValueType);
fn is_valid(&self) -> bool;
}
#[inline]
pub fn try_valid_id<T: ContainerIndex>(id: T) -> Option<T> {
Some(id).filter(|&x| x.is_valid())
}
#[macro_export]
macro_rules! make_typed_id {
($x:ident, $y:ty) => {
#[derive(Default, Clone, Copy, Debug)]
pub struct $x($y);
impl self::ContainerIndex for $x {
type ValueType = $y;
fn index(&self) -> i32 { (self.0 as i32) - 1 }
fn get_value(&self) -> Self::ValueType { self.0 }
fn set_value(&mut self, v: Self::ValueType) { self.0 = v; }
fn is_valid(&self) -> bool { self.0 != 0 }
}
impl $x { pub const fn const_new(v: $y) -> $x { $x(v) } }
impl From<u8> for $x { fn from(v: u8) -> $x { $x(v as $y) } }
impl From<u16> for $x { fn from(v: u16) -> $x { $x(v as $y) } }
impl From<u32> for $x { fn from(v: u32) -> $x { $x(v as $y) } }
impl From<i8> for $x { fn from(v: i8) -> $x { $x(v as $y) } }
impl From<i16> for $x { fn from(v: i16) -> $x { $x(v as $y) } }
impl From<i32> for $x { fn from(v: i32) -> $x { $x(v as $y) } }
impl std::hash::Hash for $x { fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.0.hash(state); } }
impl std::cmp::Ord for $x { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.0.cmp(&other.0) } }
impl std::cmp::PartialOrd for $x { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { self.0.partial_cmp(&other.0) } }
impl std::cmp::PartialEq for $x { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } }
impl std::cmp::Eq for $x {}
impl self::Serializable for $x {
fn serialize(&self, s: &mut self::Serializer) {
s.serialize_raw(&<$y>::to_le_bytes(self.0))
}
fn deserialize(&mut self, s: &mut self::Serializer) {
let len = self.serialized_size();
let (bytes, _) = s.deserialize_raw(len).split_at(len);
*self = $x(<$y>::from_le_bytes(bytes.try_into().unwrap()));
}
}
};
}
pub trait Container<I: ContainerIndex> {
fn size(&self) -> usize;
fn resize(&mut self, new_size: usize);
fn on_create(&mut self) -> I;
fn delete(&mut self, id: I);
}
#[derive(Default, Debug, Clone)]
pub struct TaggedVec<
K: Sized + ContainerIndex,
V: Sized,
> {
v: Vec<V>,
ph1: std::marker::PhantomData<K>,
ph2: std::marker::PhantomData<K::ValueType>,
}
impl<K, V> TaggedVec<K, V>
where
K: Sized + ContainerIndex,
V: Sized,
K::ValueType: Into<usize>
{
pub fn new() -> Self {
Self{ v: Vec::new(), ph1: PhantomData, ph2: PhantomData }
}
#[inline]
pub fn len(&self) -> usize {
self.v.len()
}
#[inline]
pub fn clear(&mut self) {
self.v.clear();
}
#[inline]
pub fn get(&self, key: K) -> &V {
&self.v[key.get_value().into()]
}
#[inline]
pub fn get_mut(&mut self, key: K) -> &mut V {
&mut self.v[key.get_value().into()]
}
#[inline]
pub fn set(&mut self, key: K, value: V) {
self.v[key.get_value().into()] = value;
}
#[inline]
pub fn resize(&mut self, new_size: usize, value: V) where V: Clone {
self.v.resize(new_size, value);
}
#[inline]
pub fn push(&mut self, value: V) -> K where K::ValueType: TryFrom<usize> {
self.v.push(value);
K::from(unsafe {
K::ValueType::try_from(self.len() - 1).unwrap_unchecked()
})
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &V> {
self.v.iter()
}
#[inline]
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut V> {
self.v.iter_mut()
}
}
impl<K, V> IntoIterator for TaggedVec<K, V>
where
K: Sized + ContainerIndex + From<u32>,
V: Sized,
K::ValueType: Into<usize>,
{
type IntoIter = <Vec<V> as IntoIterator>::IntoIter;
type Item = V;
fn into_iter(self) -> Self::IntoIter {
self.v.into_iter()
}
}
pub type TaggedMap<K, V> = std::collections::BTreeMap<K, V>;
#[derive(Clone, Copy, Debug)]
pub struct ZeroableArray<T, const N: usize>([T; N]);
impl<T: Serializable, const N: usize> Serializable for crate::ZeroableArray<T, N> {
fn serialize(&self, s: &mut Serializer) {
for item in self.iter() {
item.serialize(s);
}
}
fn deserialize(&mut self, s: &mut Serializer) {
for item in self.iter_mut() {
item.deserialize(s);
}
}
}
impl<T: Default, const N: usize> Default for ZeroableArray<T, N> {
fn default() -> Self {
Self(core::array::from_fn(|_| T::default()))
}
}
impl<T, const N: usize> AsMut<[T]> for ZeroableArray<T, N> {
fn as_mut(&mut self) -> &mut [T] {
&mut self.0[..]
}
}
impl<T, const N: usize> AsRef<[T]> for ZeroableArray<T, N> {
fn as_ref(&self) -> &[T] {
&self.0[..]
}
}
impl<T, const N: usize> Deref for ZeroableArray<T, N> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.0[..]
}
}
impl<T, const N: usize> DerefMut for ZeroableArray<T, N> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.0[..]
}
}
impl<T, const N: usize, I: SliceIndex<[T]>> Index<I> for ZeroableArray<T, N> {
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
Index::index(&self.0, index)
}
}
impl<T, const N: usize, I: SliceIndex<[T]>> IndexMut<I> for ZeroableArray<T, N> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut self.0, index)
}
}
#[repr(align(64))]
#[derive(Clone, Copy, Debug)]
pub struct CacheAlignedArray<T, const N: usize>(pub [T; N]);
impl<T: Serializable, const N: usize> Serializable for crate::CacheAlignedArray<T, N> {
fn serialize(&self, s: &mut Serializer) {
for item in self.iter() {
item.serialize(s);
}
}
fn deserialize(&mut self, s: &mut Serializer) {
for item in self.iter_mut() {
item.deserialize(s);
}
}
}
impl<T: Default, const N: usize> Default for CacheAlignedArray<T, N> {
fn default() -> Self {
Self(core::array::from_fn(|_| T::default()))
}
}
impl<T, const N: usize> AsMut<[T]> for CacheAlignedArray<T, N> {
fn as_mut(&mut self) -> &mut [T] {
&mut self.0[..]
}
}
impl<T, const N: usize> AsRef<[T]> for CacheAlignedArray<T, N> {
fn as_ref(&self) -> &[T] {
&self.0[..]
}
}
impl<T, const N: usize> Deref for CacheAlignedArray<T, N> {
type Target = [T];
fn deref(&self) -> &[T] {
&self.0[..]
}
}
impl<T, const N: usize> DerefMut for CacheAlignedArray<T, N> {
fn deref_mut(&mut self) -> &mut [T] {
&mut self.0[..]
}
}
impl<T, const N: usize, I: SliceIndex<[T]>> Index<I> for CacheAlignedArray<T, N> {
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
Index::index(&self.0, index)
}
}
impl<T, const N: usize, I: SliceIndex<[T]>> IndexMut<I> for CacheAlignedArray<T, N> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut self.0, index)
}
}
#[derive(Clone, Copy, Debug)]
pub struct FixedBitmap<const N: usize>([u32; N]);
impl<const N: usize> Default for FixedBitmap<N> {
fn default() -> Self {
Self(core::array::from_fn(|_| u32::default()))
}
}
impl<const N: usize> FixedBitmap<N> {
pub fn get(&self, index: usize) -> bool {
(self.0[index / 4] & (1 << (index % 4))) != 0
}
pub fn set(&mut self, index: usize) {
self.0[index / 4] |= 1 << (index % 4);
}
pub fn clear(&mut self, index: usize) {
self.0[index / 4] &= !(1 << (index % 4));
}
pub fn try_find_free(&self) -> Option<usize> {
for i in 0..N {
if self.0[i] != 0xffff_ffff {
for j in 0..32 {
if self.0[i] & (1 << j) == 0 {
return Some(i * 32 + j);
}
}
}
}
None
}
pub fn find_free(&self) -> usize {
self.try_find_free().expect("Couldn't find free")
}
}