diff options
| author | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
| commit | 8022e8998290b067b8aa0cb9cba8ba410826bdab (patch) | |
| tree | 7171e79ce530e03079046ee8fd12167160c45480 /ecs/src/tuple.rs | |
| parent | 412cee02c252f91bcf0b70a3f5cc5fca6d2b4c62 (diff) | |
chore: rename ecs* crates to engine-ecs*
Diffstat (limited to 'ecs/src/tuple.rs')
| -rw-r--r-- | ecs/src/tuple.rs | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/ecs/src/tuple.rs b/ecs/src/tuple.rs deleted file mode 100644 index def25a0..0000000 --- a/ecs/src/tuple.rs +++ /dev/null @@ -1,238 +0,0 @@ -use std::any::TypeId; - -use paste::paste; -use seq_macro::seq; -use util_macros::sub; - -pub trait Tuple: sealed::Sealed -{ - /// `Self` with the given type added as the last element. - /// - /// `(String, i32, u8)::WithElementAtEnd<Path> = (String, i32, u8, Path)` - /// - /// # Important note - /// If `Self` has 16 elements, this will be `()`. The reason for this is that the - /// `Tuple` trait is only implemented for tuples with up to and including 16 elements. - type WithElementAtEnd<NewElem>: Tuple; - - /// `Self` without the last element. - /// - /// `(u16, AtomicU8)::WithoutLastElement = (u16,)` - type WithoutLastElement: Tuple; - - /// The last element of `Self`. - type LastElement; - - /// Self with all elements wrapped in [`Option`]. - type InOptions: Tuple; - - /// Pops the last element from this tuple, returning the new tuple and the popped - /// element. - fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement); - - /// Converts this tuple so that all elements are wrapped in [`Option`]. - fn into_in_options(self) -> Self::InOptions; -} - -/// A tuple with element types that all have the lifetime `'static`. -pub trait WithAllElemLtStatic: Tuple + sealed::Sealed -{ - /// Returns the element at the given index. - fn get_mut<Element: 'static>(&mut self, index: usize) -> Option<&mut Element>; -} - -/// Using the type system, reduces the elements of a tuple to a single one. Each element -/// determines itself how it is handled. -pub trait Reduce<Operation> -{ - type Out; -} - -pub trait ReduceElement<Accumulator, Operation> -{ - type Return; -} - -macro_rules! tuple_reduce_elem_tuple { - (overflow) => { - () - }; - - ($index: tt) => { - paste! { - [<Elem $index>]::Return - } - }; -} - -macro_rules! elem_type_by_index { - (overflow) => { - () - }; - - ($index: tt) => { - paste! { - [<Elem $index>] - } - }; -} - -macro_rules! elem_by_index { - (overflow) => { - () - }; - - ($index: tt, $self: ident) => { - $self.$index - }; -} - -macro_rules! all_except_last { - (start $($rest: tt)*) => { - all_except_last!(@[] $($rest)*) - }; - - (@[$($included_elem: ident,)*] $elem: ident $($rest: tt)+) => { - all_except_last!(@[$($included_elem,)* $elem,] $($rest)*) - }; - - (@[$($included_elem: expr,)*] ($elem: expr) $($rest: tt)+) => { - all_except_last!(@[$($included_elem,)* $elem,] $($rest)*) - }; - - (@[$($included_elem: ident,)*] $elem: ident) => { - ($($included_elem,)*) - }; - - (@[$($included_elem: expr,)*] $elem: expr) => { - ($($included_elem,)*) - }; - - (@[]) => { - () - }; -} - -macro_rules! impl_tuple_traits { - ($cnt: tt) => { - seq!(I in 0..$cnt { - impl<#(Elem~I,)*> Tuple for (#(Elem~I,)*) - { - type WithElementAtEnd<NewElem> = (#(Elem~I,)* NewElem,); - - type WithoutLastElement = all_except_last!(start #(Elem~I)*); - - type LastElement = sub!($cnt - 1, elem_type_by_index); - - type InOptions = (#(Option<Elem~I>,)*); - - fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement) - { - ( - all_except_last!(start #((self.I))*), - sub!($cnt - 1, elem_by_index, (self)) - ) - } - - fn into_in_options(self) -> Self::InOptions - { - #![allow(clippy::unused_unit)] - (#(Some(self.I),)*) - } - } - - impl<#(Elem~I: 'static,)*> WithAllElemLtStatic for (#(Elem~I,)*) - { - fn get_mut<Element: 'static>(&mut self, index: usize) -> Option<&mut Element> - { - match index { - #( - I => { - assert!(TypeId::of::<Element>() == TypeId::of::<Elem~I>()); - - // SAFETY: It is checked above that the type is correct - Some(unsafe { &mut *(&raw mut self.I).cast::<Element>() }) - } - )* - _ => None - } - } - } - - impl<#(Elem~I,)*> sealed::Sealed for (#(Elem~I,)*) - { - } - - paste! { - impl<Operation, #(Elem~I,)*> Reduce<Operation> for (#(Elem~I,)*) - where - #( - Elem~I: ReduceElement< - sub!(I - 1, tuple_reduce_elem_tuple), Operation - >, - )* - { - type Out = sub!($cnt - 1, tuple_reduce_elem_tuple); - } - } - }); - }; -} - -seq!(N in 0..16 { - impl_tuple_traits!(N); -}); - -seq!(I in 0..16 { - impl<#(Elem~I,)*> Tuple for (#(Elem~I,)*) - { - type WithElementAtEnd<NewElem> = (); - - type WithoutLastElement = all_except_last!(start #(Elem~I)*); - - type LastElement = Elem15; - - type InOptions = (#(Option<Elem~I>,)*); - - fn pop_last(self) -> (Self::WithoutLastElement, Self::LastElement) - { - ( - all_except_last!(start #((self.I))*), - self.15 - ) - } - - fn into_in_options(self) -> Self::InOptions - { - #![allow(clippy::unused_unit)] - (#(Some(self.I),)*) - } - } - - impl<#(Elem~I: 'static,)*> WithAllElemLtStatic for (#(Elem~I,)*) - { - fn get_mut<Element: 'static>(&mut self, index: usize) -> Option<&mut Element> - { - match index { - #( - I => { - assert!(TypeId::of::<Element>() == TypeId::of::<Elem~I>()); - - // SAFETY: It is checked above that the type is correct - Some(unsafe { &mut *(&raw mut self.I).cast::<Element>() }) - } - )* - _ => None - } - } - } - - impl<#(Elem~I,)*> sealed::Sealed for (#(Elem~I,)*) - { - } -}); - -mod sealed -{ - pub trait Sealed {} -} |
