dungeon_cell/marker_traits/
alignment.rs

1use core::panic::{RefUnwindSafe, UnwindSafe};
2
3use super::sealed::Sealed;
4
5/// Marker only implemented for [`Alignment`][crate::layout::Alignment].
6///
7/// Alignment values with a power of two from 1 up to 2²⁹ are allowed as
8/// given by the [rust reference](https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers).
9///
10/// This trait is [sealed](https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed)
11/// and cannot be implemented by external types.
12pub trait IsAlignment:
13    Sealed
14    + Sized
15    + Copy
16    + Clone
17    + Sync
18    + Send
19    + Unpin
20    + RefUnwindSafe
21    + UnwindSafe
22    + 'static
23{
24    /// Type of alignment marker.
25    type Marker: Send
26        + Sync
27        + Unpin
28        + Clone
29        + Copy
30        + RefUnwindSafe
31        + UnwindSafe
32        + 'static;
33
34    /// Instance of the associated [`Self::Marker`].
35    const MARKER_INSTANCE: Self::Marker;
36
37    /// Alignment of the associated [`Self::Marker`].
38    const VALUE: usize;
39}
40
41pub(crate) mod sealed {
42    use super::Sealed;
43    use crate::layout::Alignment;
44
45    macro_rules! impl_alignment_marker {
46        ($(($power:literal, $num:literal, $name:ident)),*) => {
47            $(
48                /// ZST to with given alignment.
49                #[repr(align($num))]
50                #[derive(Clone, Copy)]
51                pub struct $name;
52
53                // Implement the public version of the trait.
54                impl super::IsAlignment for Alignment<$num> {
55                    const VALUE: usize = $num;
56
57                    type Marker = $name;
58
59                    const MARKER_INSTANCE: $name = $name;
60                }
61
62                impl Sealed for Alignment<$num> {}
63            )*
64        }
65    }
66
67    // Implement `ValidAlignment` for all valid alignments.
68    //
69    // "The alignment value must be a power of two from 1 up to 2^29"
70    // https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers
71    impl_alignment_marker![
72        (0, 1, Marker0),
73        (1, 2, Marker1),
74        (2, 4, Marker2),
75        (3, 8, Marker3),
76        (4, 16, Marker4),
77        (5, 32, Marker5),
78        (6, 64, Marker6),
79        (7, 128, Marker7),
80        (8, 256, Marker8),
81        (9, 512, Marker9),
82        (10, 1024, Marker10),
83        (11, 2048, Marker11),
84        (12, 4096, Marker12),
85        (13, 8192, Marker13),
86        (14, 16384, Marker14),
87        (15, 32768, Marker15),
88        (16, 65536, Marker16),
89        (17, 131072, Marker17),
90        (18, 262144, Marker18),
91        (19, 524288, Marker19),
92        (20, 1048576, Marker20),
93        (21, 2097152, Marker21),
94        (22, 4194304, Marker22),
95        (23, 8388608, Marker23),
96        (24, 16777216, Marker24),
97        (25, 33554432, Marker25),
98        (26, 67108864, Marker26),
99        (27, 134217728, Marker27),
100        (28, 268435456, Marker28),
101        (29, 536870912, Marker29)
102    ];
103}