xref: /linux/rust/kernel/mem.rs (revision bb29b957eaaa15be33243550d9ee576c2d601669)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Basic utilities for dealing with memory, values, and types.
4 
5 // TODO: `Alignment` should be moved here as well, Rust moved it upstream in 1.96.
6 pub use crate::ptr::Alignment;
7 
8 /// Trait indicating that [`Align<N>`] is a valid alignment.
9 pub trait ValidAlign {
10     #[doc(hidden)]
11     type Repr: Copy;
12 }
13 
14 /// Zero-sized type that provides the alignment specified via the generic parameter.
15 ///
16 /// # Examples
17 ///
18 /// ```
19 /// # use kernel::mem::Align;
20 /// const ALIGN: usize = 128;
21 /// struct MyStruct {
22 ///     _align: Align<ALIGN>,
23 /// }
24 /// assert_eq!(align_of::<MyStruct>(), ALIGN);
25 /// ```
26 #[repr(transparent)]
27 #[derive(Default, Clone, Copy)]
28 pub struct Align<const N: usize>([<Self as ValidAlign>::Repr; 0])
29 where
30     Self: ValidAlign;
31 
32 impl<const N: usize> Align<N>
33 where
34     Self: ValidAlign,
35 {
36     /// Create a new [`Align<N>`].
37     #[inline]
38     pub const fn new() -> Self {
39         Align([])
40     }
41 }
42 
43 macro_rules! impl_align {
44     () => {};
45     ($a:literal $($rest:literal)*) => {
46         const _: () = {
47             #[repr(align($a))]
48             #[derive(Clone, Copy)]
49             pub struct Repr;
50 
51             impl ValidAlign for Align<$a> {
52                 type Repr = Repr;
53             }
54         };
55 
56         impl_align!($($rest)*);
57     }
58 }
59 
60 impl_align!(1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536);
61 
62 impl<const N: usize> core::fmt::Debug for Align<N>
63 where
64     Self: ValidAlign,
65 {
66     #[inline]
67     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
68         write!(f, "Align<{N}>")
69     }
70 }
71