Skip to content

Instantly share code, notes, and snippets.

@zohnannor
Created January 1, 2023 16:33
Show Gist options
  • Save zohnannor/9f19e43b8990daa130a54cdde2984035 to your computer and use it in GitHub Desktop.
Save zohnannor/9f19e43b8990daa130a54cdde2984035 to your computer and use it in GitHub Desktop.
trait Tuple<const ARITY: usize> {
fn hashes(&self) -> [u64; ARITY];
}
// trait TupleHasType<T> {}
macro_rules! impl_tuples {
// tt counter
(@count ) => { 0 };
(@count $odd:tt $($a:tt $b:tt)*) => { (impl_tuples!(@count $($a)*) << 1) | 1 };
(@count $($a:tt $even:tt)*) => { impl_tuples!(@count $($a)*) << 1 };
// // end
// (@hastype [] $cur:tt []) => {
// const _:() = { stringify!(start [] $cur []); };
// impl<$cur> TupleHasType<$cur> for ($cur,) {}
// };
// (@hastype [$($walked:tt)+] $cur:tt []) => {
// const _:() = { stringify!(end [$($walked),+] $cur []); };
// impl<$($walked),+, $cur> TupleHasType<$cur> for ($($walked),+, $cur) {}
// };
// // middle
// (@hastype [$($walked:tt)+] $cur:tt [$next:tt $($rest:tt)*]) => {
// const _:() = { stringify!(middle [$($walked),+] $cur [$next $($rest),*]); };
// impl<$($walked),+, $cur, $next, $($rest),*> TupleHasType<$cur> for ($($walked),+, $cur, $next, $($rest),*) {}
// impl_tuples! { @hastype [$($walked)+ $cur] $next [$($rest)*] }
// };
// // start
// (@hastype [] $cur:tt [$next:tt $($rest:tt)*]) => {
// const _:() = { stringify!(start [] $cur [$next $($rest),*]); };
// impl<$cur, $next, $($rest),*> TupleHasType<$cur> for ($cur, $next, $($rest),*) {}
// impl_tuples! { @hastype [$cur] $next [$($rest)*] }
// };
// impl
() => {
impl Tuple<0> for () {
fn hashes(&self) -> [u64; 0] {
[]
}
}
};
($ta:tt $($ty:tt)*) => {
#[allow(non_snake_case)]
impl<$ta: Hash, $($ty: Hash),*> Tuple<{impl_tuples!{ @count $ta $($ty)* }}> for ($ta, $($ty),*) {
#[inline]
fn hashes(&self) -> [u64; impl_tuples!{ @count $ta $($ty)* }] {
let ($ta, $($ty),*) = self;
let mut arr = unsafe {
MaybeUninit::<[
MaybeUninit<_>;
impl_tuples!{ @count $ta $($ty)* }
]>::uninit().assume_init()
};
let mut it = arr.iter_mut();
it.next().unwrap().write({
let mut state = DefaultHasher::new();
$ta.hash(&mut state);
state.finish()
});
$(
it.next().unwrap().write({
let mut state = DefaultHasher::new();
$ty.hash(&mut state);
state.finish()
});
)*
arr.map(|i| unsafe { i.assume_init() })
}
}
// impl_tuples! { @hastype [] $ta [$($ty)*] }
impl_tuples! { $($ty)* }
};
}
impl_tuples! { A B C D E F G H I J K L M N O P Q R S T U V W X Y Z }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment