aligned_utils/
stack.rs

1//! Aligned newtypes
2//!
3//! ```
4//! use aligned_utils::stack::Align8;
5//! let mut arr = Align8([1, 2, 3]);
6//! let bytes: &[u8] = &*arr;
7//! ```
8//!
9
10use core::ops::{Deref, DerefMut};
11
12macro_rules! define_align_newtype {
13    ($($(#[$id_attr:meta])* $id:ident: $align:tt,)+) => {
14        $(
15            $(#[$id_attr])*
16            #[repr(align($align))]
17            #[derive(Debug, Clone, Copy)]
18            pub struct $id<T: ?Sized>(pub T);
19
20            impl<T: ?Sized> Deref for $id<T> {
21                type Target = T;
22                fn deref(&self) -> &T {
23                    &self.0
24                }
25            }
26
27            impl<T: ?Sized> DerefMut for $id<T> {
28                fn deref_mut(&mut self) -> &mut T {
29                    &mut self.0
30                }
31            }
32        )+
33
34        #[cfg(test)]
35        mod tests{
36            use super::*;
37
38            #[test]
39            fn check_aligned_wrappers(){
40                $(
41                    {
42                        let a = $id([0_u8;1]);
43                        assert_eq!(core::mem::align_of_val(&a), $align);
44                        assert_eq!(a.as_ptr() as usize % $align, 0);
45                        assert_eq!(a.as_ref(), &[0_u8]);
46
47                        #[cfg(feature="alloc")]
48                        {
49                            let b = alloc::boxed::Box::new(a);
50                            let p: *const $id<[u8;1]> = &*b;
51                            assert_eq!(p as usize % $align, 0);
52                        }
53
54                        let c: &$id<[u8]> = &a;
55                        assert_eq!(c.as_ref(), &[0_u8]);
56                    }
57                )+
58            }
59        }
60    };
61}
62
63define_align_newtype! (
64    /// A newtype with alignment of at least 2 bytes
65    Align2: 2,
66    /// A newtype with alignment of at least 4 bytes
67    Align4: 4,
68    /// A newtype with alignment of at least 8 bytes
69    Align8: 8,
70    /// A newtype with alignment of at least 16 bytes
71    Align16: 16,
72    /// A newtype with alignment of at least 32 bytes
73    Align32: 32,
74    /// A newtype with alignment of at least 64 bytes
75    Align64: 64,
76    /// A newtype with alignment of at least 128 bytes
77    Align128: 128,
78    /// A newtype with alignment of at least 256 bytes
79    Align256: 256,
80    /// A newtype with alignment of at least 512 bytes
81    Align512: 512,
82    /// A newtype with alignment of at least 1024 bytes
83    Align1024: 1024,
84    /// A newtype with alignment of at least 2048 bytes
85    Align2048: 2048,
86    /// A newtype with alignment of at least 4096 bytes
87    Align4096: 4096,
88);