aligned_bytes/
stack.rs

1//! Aligned wrappers
2
3use core::ops::{Deref, DerefMut};
4
5macro_rules! define_align_newtype {
6    {$($(#[$ctor_attr:meta])* $ctor:ident => { $(#[$id_attr:meta])* $id:ident: $align:tt },)+} => {
7        $(
8            $(#[$ctor_attr])*
9            pub const fn $ctor<T>(x: T)->$id<T>{
10                $id{ inner: x }
11            }
12
13            $(#[$id_attr])*
14            #[repr(align($align))]
15            #[derive(Debug, Clone, Copy)]
16            pub struct $id<T: ?Sized>{
17                inner: T
18            }
19
20            impl<T: ?Sized> Deref for $id<T> {
21                type Target = T;
22                fn deref(&self) -> &T {
23                    &self.inner
24                }
25            }
26
27            impl<T: ?Sized> DerefMut for $id<T> {
28                fn deref_mut(&mut self) -> &mut T {
29                    &mut self.inner
30                }
31            }
32
33            impl<T> $id<T> {
34                /// Consumes the aligned wrapper, returning the wrapped value.
35                pub fn into_inner(self) -> T {
36                    self.inner
37                }
38            }
39        )+
40
41        #[cfg(test)]
42        mod tests{
43            use super::*;
44
45            #[test]
46            fn check_aligned_wrappers(){
47                $(
48                    {
49                        let a = $ctor([0u8;1]);
50                        assert_eq!(core::mem::align_of_val(&a), $align);
51                        assert_eq!(a.as_ptr() as usize % $align, 0);
52                        assert_eq!(a.as_ref(), &[0u8]);
53
54                        let b = Box::new(a);
55                        assert_eq!(&*b as *const $id<[u8;1]> as usize % $align, 0);
56
57                        let c: &$id<[u8]> = &a;
58                        assert_eq!(c.as_ref(), &[0u8]);
59                    }
60                )+
61            }
62        }
63    };
64}
65
66define_align_newtype! {
67    /// Wraps a value with alignment of at least 2 bytes
68    align2 => {
69        /// A newtype with alignment of at least 2 bytes
70        Align2: 2
71    },
72    /// Wraps a value with alignment of at least 4 bytes
73    align4 =>  {
74        /// A newtype with alignment of at least 4 bytes
75        Align4: 4
76    },
77    /// Wraps a value with alignment of at least 8 bytes
78    align8 =>  {
79        /// A newtype with alignment of at least 8 bytes
80        Align8: 8
81    },
82    /// Wraps a value with alignment of at least 16 bytes
83    align16 => {
84        /// A newtype with alignment of at least 16 bytes
85        Align16: 16
86    },
87    /// Wraps a value with alignment of at least 32 bytes
88    align32 => {
89        /// A newtype with alignment of at least 32 bytes
90        Align32: 32
91    },
92    /// Wraps a value with alignment of at least 64 bytes
93    align64 => {
94        /// A newtype with alignment of at least 64 bytes
95        Align64: 64
96    },
97}