viffy 0.1.5

SoA + SIMD automata generator
Documentation
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);
	}
    /// Pushes a new value into the given list, returns the ID of the value
    /// just pushed
    #[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()
	}
}

//#[derive(Default, Clone)]
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")
	}
}