use crate::check_covariance;
use crate::prelude::*;
use core::hash::Hash;
use deser::*;
use ser::*;
macro_rules! impl_type_hash {
($($t:ident),*) => {
impl<$($t: TypeHash,)*> TypeHash for ($($t,)*)
{
fn type_hash(
hasher: &mut impl core::hash::Hasher,
) {
"(".hash(hasher);
$(
<$t>::type_hash(hasher);
)*
")".hash(hasher);
}
}
}
}
macro_rules! impl_tuples {
($($t:ident),*) => {
unsafe impl<T: ZeroCopy> CopyType for ($($t,)*) {
type Copy = Zero;
}
impl<T: AlignHash> AlignHash for ($($t,)*)
{
fn align_hash(
hasher: &mut impl core::hash::Hasher,
offset_of: &mut usize,
) {
$(
<$t>::align_hash(hasher, offset_of);
)*
}
}
impl<T: AlignTo> AlignTo for ($($t,)*)
{
fn align_to() -> usize {
let mut align_to = 0;
$(if align_to < <$t>::align_to() {
align_to = <$t>::align_to();
})*
align_to
}
}
impl<T: ZeroCopy> SerInner for ($($t,)*) {
type SerType = Self;
const IS_ZERO_COPY: bool = true;
#[inline(always)]
unsafe fn _ser_inner(&self, backend: &mut impl WriteWithNames) -> ser::Result<()> {
ser_zero(backend, self)
}
}
impl<T: ZeroCopy> DeserInner for ($($t,)*) {
check_covariance!();
type DeserType<'a> = &'a ($($t,)*);
unsafe fn _deser_full_inner(backend: &mut impl ReadWithPos) -> deser::Result<Self> {
unsafe { deser_full_zero::<($($t,)*)>(backend) }
}
unsafe fn _deser_eps_inner<'a>(
backend: &mut SliceWithPos<'a>,
) -> deser::Result<Self::DeserType<'a>> {
unsafe { deser_eps_zero::<($($t,)*)>(backend) }
}
}
};
}
macro_rules! impl_tuples_muncher {
($ty:ident, $($t:ident),*) => {
impl_tuples!($ty, $($t),*);
impl_tuples_muncher!($($t),*);
};
($ty:ident) => {
impl_tuples!($ty);
};
() => {};
}
impl_tuples_muncher!(T, T, T, T, T, T, T, T, T, T, T, T);
macro_rules! impl_type_hash_muncher {
($ty:ident, $($t:ident),*) => {
impl_type_hash!($ty, $($t),*);
impl_type_hash_muncher!($($t),*);
};
($ty:ident) => {
impl_type_hash!($ty);
};
() => {};
}
impl_type_hash_muncher!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);