repr_offset/
alignment.rs

1//! Type-level encoding of `enum Alignment { Aligned, Unaligned }`
2
3/// A marker type representing that a `FieldOffset` is for an aligned field.
4#[derive(Debug, Copy, Clone)]
5pub struct Aligned;
6
7/// A marker type representing that a `FieldOffset` is for a (potentially) unaligned field.
8#[derive(Debug, Copy, Clone)]
9pub struct Unaligned;
10
11mod sealed {
12    use super::{Aligned, Unaligned};
13    pub trait Sealed {}
14
15    impl Sealed for Aligned {}
16    impl Sealed for Unaligned {}
17}
18use self::sealed::Sealed;
19
20/// Marker trait for types that represents the alignment of a `FieldOffset`.
21///
22/// This is only implemented by [`Aligned`] and [`Unaligned`]
23///
24/// [`Aligned`]:  ./struct.Aligned.html
25/// [`Unaligned`]: ./struct.Unaligned.html
26pub trait Alignment: Sealed {}
27
28impl Alignment for Aligned {}
29impl Alignment for Unaligned {}
30
31/// Combines two [`Alignment`] types,
32/// determines the return type of `FieldOffset + FieldOffset`.
33///
34/// [`Alignment`]: ./trait.Alignment.html
35/// [`FieldOffset + FieldOffset`]: ./struct.FieldOffset.html#impl-Add<FieldOffset<F%2C F2%2C A2>>
36pub type CombineAlignmentOut<Lhs, Rhs> = <Lhs as CombineAlignment<Rhs>>::Output;
37
38/// Trait that combines two [`Alignment`] types,
39/// determines the return type of `FieldOffset + FieldOffset`.
40///
41/// [`Alignment`]: ./trait.Alignment.html
42pub trait CombineAlignment<Rhs: Alignment> {
43    /// This is [`Aligned`] if both `Self` and the `Rhs` parameter are [`Aligned`],
44    /// otherwise it is [`Unaligned`].
45    ///
46    /// [`Alignment`]: ./trait.Alignment.html
47    /// [`Aligned`]:  ./struct.Aligned.html
48    /// [`Unaligned`]: ./struct.Unaligned.html
49    type Output: Alignment;
50}
51
52impl<A: Alignment> CombineAlignment<A> for Aligned {
53    type Output = A;
54}
55impl<A: Alignment> CombineAlignment<A> for Unaligned {
56    type Output = Unaligned;
57}
58
59macro_rules! tuple_impls {
60    (small=> $ty:ty = $output:ty ) => {
61        impl<Carry: Alignment> CombineAlignment<Carry> for $ty {
62            type Output = $output;
63        }
64    };
65    (large=>
66        $( ($t0:ident,$t1:ident,$t2:ident,$t3:ident,), )*
67        $($trailing:ident,)*
68    )=>{
69        #[allow(non_camel_case_types)]
70        impl<A: Alignment, $($t0,$t1,$t2,$t3,)* $($trailing,)* CombTuples >
71            CombineAlignment<A>
72        for ($($t0,$t1,$t2,$t3,)* $($trailing,)*)
73        where
74            ($($trailing,)*): CombineAlignment<A>,
75            $( ($t0,$t1,$t2,$t3): CombineAlignment<Aligned>, )*
76            (
77                $( CombineAlignmentOut<($t0,$t1,$t2,$t3), Aligned>, )*
78            ):CombineAlignment<
79                CombineAlignmentOut<($($trailing,)*), A>,
80                Output = CombTuples,
81            >,
82            CombTuples: Alignment,
83        {
84            type Output = CombTuples;
85        }
86    };
87}
88
89impl_all_trait_for_tuples! {
90    macro = tuple_impls,
91    true = Aligned,
92    false = Unaligned,
93}