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}