conquer_util/
align.rs

1//! Transparent thin wrapper types for artificially increasing the alignment of
2//! the wrapped type.
3
4use core::borrow::{Borrow, BorrowMut};
5use core::convert::{AsMut, AsRef};
6
7macro_rules! impl_align {
8    ($(struct align($align:expr) $wrapper:ident; $comment:expr)*) => {
9        $(
10            #[doc = $comment]
11            #[derive(Copy, Clone, Debug, Default, Hash, Eq, Ord, PartialEq, PartialOrd)]
12            #[repr(align($align))]
13            pub struct $wrapper<T> {
14                /// The aligned inner value.
15                pub aligned: T,
16            }
17
18            impl<T> $wrapper<T> {
19                /// Creates a new aligned value.
20                #[inline]
21                pub const fn new(aligned: T) -> Self {
22                    Self { aligned }
23                }
24
25                /// Returns a shared reference to the aligned value.
26                #[inline]
27                pub const fn get(&self) -> &T {
28                    &self.aligned
29                }
30
31                /// Returns a mutable reference to the aligned value.
32                #[inline]
33                pub fn get_mut(&mut self) -> &mut T {
34                    &mut self.aligned
35                }
36            }
37
38            impl<T> AsRef<T> for $wrapper<T> {
39                #[inline]
40                fn as_ref(&self) -> &T {
41                    &self.aligned
42                }
43            }
44
45            impl<T> AsMut<T> for $wrapper<T> {
46                #[inline]
47                fn as_mut(&mut self) -> &mut T {
48                    &mut self.aligned
49                }
50            }
51
52            impl<T> Borrow<T> for $wrapper<T> {
53                #[inline]
54                fn borrow(&self) -> &T {
55                    &self.aligned
56                }
57            }
58
59            impl<T> BorrowMut<T> for $wrapper<T> {
60                #[inline]
61                fn borrow_mut(&mut self) -> &mut T {
62                    &mut self.aligned
63                }
64            }
65        )*
66    };
67}
68
69impl_align! {
70    struct align(2)          Aligned2;    "A thin wrapper type with an alignment of at least 2B."
71    struct align(4)          Aligned4;    "A thin wrapper type with an alignment of at least 4B."
72    struct align(8)          Aligned8;    "A thin wrapper type with an alignment of at least 8B."
73    struct align(16)         Aligned16;   "A thin wrapper type with an alignment of at least 16B."
74    struct align(32)         Aligned32;   "A thin wrapper type with an alignment of at least 32B."
75    struct align(64)         Aligned64;   "A thin wrapper type with an alignment of at least 64B."
76    struct align(128)        Aligned128;  "A thin wrapper type with an alignment of at least 128B."
77    struct align(256)        Aligned256;  "A thin wrapper type with an alignment of at least 256B."
78    struct align(512)        Aligned512;  "A thin wrapper type with an alignment of at least 512B."
79    struct align(1024)       Aligned1024; "A thin wrapper type with an alignment of at least 1kB."
80    struct align(2048)       Aligned2048; "A thin wrapper type with an alignment of at least 2kB."
81    struct align(4096)       Aligned4096; "A thin wrapper type with an alignment of at least 4kB."
82    struct align(0x2000)     Aligned8k;   "A thin wrapper type with an alignment of at least 8kB."
83    struct align(0x4000)     Aligned16k;  "A thin wrapper type with an alignment of at least 16kB."
84    struct align(0x8000)     Aligned32k;  "A thin wrapper type with an alignment of at least 32kB."
85    struct align(0x10000)    Aligned64k;  "A thin wrapper type with an alignment of at least 64kB."
86    struct align(0x20000)    Aligned128k; "A thin wrapper type with an alignment of at least 128kB."
87    struct align(0x40000)    Aligned256k; "A thin wrapper type with an alignment of at least 256kB."
88    struct align(0x80000)    Aligned512k; "A thin wrapper type with an alignment of at least 512kB."
89    struct align(0x100000)   Aligned1M;   "A thin wrapper type with an alignment of at least 1MB."
90    struct align(0x200000)   Aligned2M;   "A thin wrapper type with an alignment of at least 2MB."
91    struct align(0x400000)   Aligned4M;   "A thin wrapper type with an alignment of at least 4MB."
92    struct align(0x800000)   Aligned8M;   "A thin wrapper type with an alignment of at least 8MB."
93    struct align(0x1000000)  Aligned16M;  "A thin wrapper type with an alignment of at least 16MB."
94    struct align(0x2000000)  Aligned32M;  "A thin wrapper type with an alignment of at least 32MB."
95    struct align(0x4000000)  Aligned64M;  "A thin wrapper type with an alignment of at least 64MB."
96    struct align(0x8000000)  Aligned128M; "A thin wrapper type with an alignment of at least 128MB."
97    struct align(0x10000000) Aligned256M; "A thin wrapper type with an alignment of at least 256MB."
98    struct align(0x20000000) Aligned512M; "A thin wrapper type with an alignment of at least 512MB."
99}
100
101#[cfg(test)]
102mod tests {
103    use core::mem;
104
105    use super::*;
106
107    #[test]
108    fn alignments() {
109        assert_eq!(mem::align_of::<Aligned8<u8>>(), 8);
110        assert_eq!(mem::align_of::<Aligned16<u8>>(), 16);
111        assert_eq!(mem::align_of::<Aligned32<u8>>(), 32);
112        assert_eq!(mem::align_of::<Aligned64<u8>>(), 64);
113        assert_eq!(mem::align_of::<Aligned128<u8>>(), 128);
114        assert_eq!(mem::align_of::<Aligned256<u8>>(), 256);
115        assert_eq!(mem::align_of::<Aligned512<u8>>(), 512);
116        assert_eq!(mem::align_of::<Aligned1024<u8>>(), 1024);
117        assert_eq!(mem::align_of::<Aligned2048<u8>>(), 2048);
118        assert_eq!(mem::align_of::<Aligned4096<u8>>(), 4096);
119    }
120
121    #[test]
122    fn construct_and_deref() {
123        let value = Aligned8::new(255u8);
124        assert_eq!(value.aligned, 255);
125
126        let value = Aligned64::new(1u8);
127        assert_eq!(value.aligned, 1);
128    }
129}