@@ -42,6 +42,7 @@ impl Alignment {
42
42
/// This provides the same numerical value as [`mem::align_of`],
43
43
/// but in an `Alignment` instead of a `usize`.
44
44
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
45
+ #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
45
46
#[ inline]
46
47
pub const fn of < T > ( ) -> Self {
47
48
// SAFETY: rustc ensures that type alignment is always a power of two.
@@ -53,6 +54,7 @@ impl Alignment {
53
54
///
54
55
/// Note that `0` is not a power of two, nor a valid alignment.
55
56
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
57
+ #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
56
58
#[ inline]
57
59
pub const fn new ( align : usize ) -> Option < Self > {
58
60
if align. is_power_of_two ( ) {
@@ -98,6 +100,7 @@ impl Alignment {
98
100
99
101
/// Returns the alignment as a [`NonZeroUsize`]
100
102
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
103
+ #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
101
104
#[ inline]
102
105
pub const fn as_nonzero ( self ) -> NonZeroUsize {
103
106
// SAFETY: All the discriminants are non-zero.
@@ -118,10 +121,42 @@ impl Alignment {
118
121
/// assert_eq!(Alignment::new(1024).unwrap().log2(), 10);
119
122
/// ```
120
123
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
124
+ #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
121
125
#[ inline]
122
- pub fn log2 ( self ) -> u32 {
126
+ pub const fn log2 ( self ) -> u32 {
123
127
self . as_nonzero ( ) . trailing_zeros ( )
124
128
}
129
+
130
+ /// Returns a bit mask that can be used to match this alignment.
131
+ ///
132
+ /// This is equivalent to `!(self.as_usize() - 1)`.
133
+ ///
134
+ /// # Examples
135
+ ///
136
+ /// ```
137
+ /// #![feature(ptr_alignment_type)]
138
+ /// #![feature(ptr_mask)]
139
+ /// use std::ptr::{Alignment, NonNull};
140
+ ///
141
+ /// #[repr(align(1))] struct Align1(u8);
142
+ /// #[repr(align(2))] struct Align2(u16);
143
+ /// #[repr(align(4))] struct Align4(u32);
144
+ /// let one = <NonNull<Align1>>::dangling().as_ptr();
145
+ /// let two = <NonNull<Align2>>::dangling().as_ptr();
146
+ /// let four = <NonNull<Align4>>::dangling().as_ptr();
147
+ ///
148
+ /// assert_eq!(four.mask(Alignment::of::<Align1>().mask()), four);
149
+ /// assert_eq!(four.mask(Alignment::of::<Align2>().mask()), four);
150
+ /// assert_eq!(four.mask(Alignment::of::<Align4>().mask()), four);
151
+ /// assert_ne!(one.mask(Alignment::of::<Align4>().mask()), one);
152
+ /// ```
153
+ #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
154
+ #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
155
+ #[ inline]
156
+ pub const fn mask ( self ) -> usize {
157
+ // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
158
+ !( unsafe { self . as_usize ( ) . unchecked_sub ( 1 ) } )
159
+ }
125
160
}
126
161
127
162
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
@@ -193,6 +228,14 @@ impl hash::Hash for Alignment {
193
228
}
194
229
}
195
230
231
+ /// Returns [`Alignment::MIN`], which is valid for any type.
232
+ #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
233
+ impl Default for Alignment {
234
+ fn default ( ) -> Alignment {
235
+ Alignment :: MIN
236
+ }
237
+ }
238
+
196
239
#[ cfg( target_pointer_width = "16" ) ]
197
240
type AlignmentEnum = AlignmentEnum16 ;
198
241
#[ cfg( target_pointer_width = "32" ) ]
0 commit comments