diff options
Diffstat (limited to 'ecs/src/tuple.rs')
| -rw-r--r-- | ecs/src/tuple.rs | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/ecs/src/tuple.rs b/ecs/src/tuple.rs deleted file mode 100644 index 1434592..0000000 --- a/ecs/src/tuple.rs +++ /dev/null @@ -1,212 +0,0 @@ -use std::any::TypeId; -use std::mem::{transmute_copy, ManuallyDrop}; - -use paste::paste; -use seq_macro::seq; -use util_macros::sub; - -/// Used to append a element to a tuple type. -pub trait With<OtherElem> -{ - type With; -} - -/// Used to remove the last element of a tuple type. -/// -/// For example: `(u32, String, PathBuf)` becomes `(u32, String)`. -pub trait WithoutLast -{ - type Return; -} - -/// Used to make all elements of a tuple type wrapped in [`Option`]. -pub trait IntoInOptions -{ - type InOptions: WithOptionElements; - - fn into_in_options(self) -> Self::InOptions; -} - -/// A tuple with all elements wrapped in [`Option`]. -pub trait WithOptionElements -{ - fn take<Element: 'static>(&mut self) -> TakeOptionElementResult<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; -} - -/// The result of trying to [`take`] a element from a implementation of -/// [`WithOptionElements`]. -/// -/// [`take`]: WithOptionElements::take -pub enum TakeOptionElementResult<Element> -{ - /// The element was succesfully taken. - Found(Element), - - /// The element is not a element of the tuple. - NotFound, - - /// The element has already been taken - AlreadyTaken, -} - -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 - }; -} - -pub trait Pop: WithoutLast -{ - type LastElem; - - fn pop(self) -> (<Self as WithoutLast>::Return, Self::LastElem); -} - -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<OtherElem, #(Elem~I,)*> With<OtherElem> for (#(Elem~I,)*) - { - type With = (#(Elem~I,)* OtherElem,); - } - - impl<#(Elem~I,)*> WithoutLast for (#(Elem~I,)*) - { - type Return = all_except_last!(start #(Elem~I)*); - } - - impl<#(Element~I: 'static,)*> IntoInOptions for (#(Element~I,)*) - { - type InOptions = (#(Option<Element~I>,)*); - - fn into_in_options(self) -> Self::InOptions - { - #![allow(clippy::unused_unit)] - (#(Some(self.I),)*) - } - } - - impl<#(Element~I: 'static,)*> WithOptionElements for (#(Option<Element~I>,)*) - { - fn take<Element: 'static>(&mut self) - -> TakeOptionElementResult<Element> - { - #( - if TypeId::of::<Element~I>() == TypeId::of::<Element>() { - let input = match self.I.take() { - Some(input) => ManuallyDrop::new(input), - None => { - return TakeOptionElementResult::AlreadyTaken; - } - }; - - return TakeOptionElementResult::Found( - // SAFETY: It can be transmuted safely since it is the - // same type and the type is 'static - unsafe { transmute_copy(&input) } - ); - } - )* - - TakeOptionElementResult::NotFound - } - } - - 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); - } - } - - impl<#(Elem~I,)*> Pop for (#(Elem~I,)*) - { - type LastElem = sub!($cnt - 1, elem_type_by_index); - - fn pop(self) -> (<Self as WithoutLast>::Return, Self::LastElem) - { - ( - all_except_last!(start #((self.I))*), - sub!($cnt - 1, elem_by_index, (self)) - ) - } - } - }); - }; -} - -seq!(N in 0..16 { - impl_tuple_traits!(N); -}); |
