1#[cfg(not(feature = "ferrocene_certified"))]
2use crate::num::NonZero;
3#[cfg(not(feature = "ferrocene_certified"))]
4use crate::ub_checks::assert_unsafe_precondition;
5#[cfg(not(feature = "ferrocene_certified"))]
6use crate::{cmp, fmt, hash, mem, num};
7#[cfg(feature = "ferrocene_certified")]
9use crate::{mem, ub_checks::assert_unsafe_precondition};
10
11#[unstable(feature = "ptr_alignment_type", issue = "102070")]
17#[cfg_attr(not(feature = "ferrocene_certified"), derive(Copy, Clone, PartialEq, Eq))]
18#[cfg_attr(feature = "ferrocene_certified", derive(Copy, Clone))]
19#[repr(transparent)]
20pub struct Alignment(AlignmentEnum);
21
22#[cfg(not(feature = "ferrocene_certified"))]
24const _: () = assert!(size_of::<Alignment>() == size_of::<usize>());
25#[cfg(not(feature = "ferrocene_certified"))]
26const _: () = assert!(align_of::<Alignment>() == align_of::<usize>());
27
28#[cfg(not(feature = "ferrocene_certified"))]
29fn _alignment_can_be_structurally_matched(a: Alignment) -> bool {
30 matches!(a, Alignment::MIN)
31}
32
33impl Alignment {
34 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
47 #[cfg(not(feature = "ferrocene_certified"))]
48 pub const MIN: Self = Self(AlignmentEnum::_Align1Shl0);
49
50 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
55 #[inline]
56 #[must_use]
57 #[cfg(not(feature = "ferrocene_certified"))]
58 pub const fn of<T>() -> Self {
59 const { Alignment::new(align_of::<T>()).unwrap() }
61 }
62
63 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
68 #[inline]
69 pub const fn new(align: usize) -> Option<Self> {
70 if align.is_power_of_two() {
71 Some(unsafe { Self::new_unchecked(align) })
73 } else {
74 None
75 }
76 }
77
78 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
87 #[inline]
88 #[track_caller]
89 pub const unsafe fn new_unchecked(align: usize) -> Self {
90 assert_unsafe_precondition!(
91 check_language_ub,
92 "Alignment::new_unchecked requires a power of two",
93 (align: usize = align) => align.is_power_of_two()
94 );
95
96 unsafe { mem::transmute::<usize, Alignment>(align) }
99 }
100
101 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
103 #[inline]
104 pub const fn as_usize(self) -> usize {
105 self.0 as usize
106 }
107
108 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
110 #[inline]
111 #[cfg(not(feature = "ferrocene_certified"))]
112 pub const fn as_nonzero(self) -> NonZero<usize> {
113 unsafe { mem::transmute::<Alignment, NonZero<usize>>(self) }
120 }
121
122 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
136 #[inline]
137 #[cfg(not(feature = "ferrocene_certified"))]
138 pub const fn log2(self) -> u32 {
139 self.as_nonzero().trailing_zeros()
140 }
141
142 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
166 #[inline]
167 #[cfg(not(feature = "ferrocene_certified"))]
168 pub const fn mask(self) -> usize {
169 !(unsafe { self.as_usize().unchecked_sub(1) })
171 }
172
173 #[cfg(not(feature = "ferrocene_certified"))]
175 pub(crate) const fn max(a: Self, b: Self) -> Self {
176 if a.as_usize() > b.as_usize() { a } else { b }
177 }
178}
179
180#[unstable(feature = "ptr_alignment_type", issue = "102070")]
181#[cfg(not(feature = "ferrocene_certified"))]
182impl fmt::Debug for Alignment {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184 write!(f, "{:?} (1 << {:?})", self.as_nonzero(), self.log2())
185 }
186}
187
188#[unstable(feature = "ptr_alignment_type", issue = "102070")]
189#[cfg(not(feature = "ferrocene_certified"))]
190impl TryFrom<NonZero<usize>> for Alignment {
191 type Error = num::TryFromIntError;
192
193 #[inline]
194 fn try_from(align: NonZero<usize>) -> Result<Alignment, Self::Error> {
195 align.get().try_into()
196 }
197}
198
199#[unstable(feature = "ptr_alignment_type", issue = "102070")]
200#[cfg(not(feature = "ferrocene_certified"))]
201impl TryFrom<usize> for Alignment {
202 type Error = num::TryFromIntError;
203
204 #[inline]
205 fn try_from(align: usize) -> Result<Alignment, Self::Error> {
206 Self::new(align).ok_or(num::TryFromIntError(()))
207 }
208}
209
210#[unstable(feature = "ptr_alignment_type", issue = "102070")]
211#[cfg(not(feature = "ferrocene_certified"))]
212impl From<Alignment> for NonZero<usize> {
213 #[inline]
214 fn from(align: Alignment) -> NonZero<usize> {
215 align.as_nonzero()
216 }
217}
218
219#[unstable(feature = "ptr_alignment_type", issue = "102070")]
220#[cfg(not(feature = "ferrocene_certified"))]
221impl From<Alignment> for usize {
222 #[inline]
223 fn from(align: Alignment) -> usize {
224 align.as_usize()
225 }
226}
227
228#[unstable(feature = "ptr_alignment_type", issue = "102070")]
229#[cfg(not(feature = "ferrocene_certified"))]
230impl cmp::Ord for Alignment {
231 #[inline]
232 fn cmp(&self, other: &Self) -> cmp::Ordering {
233 self.as_nonzero().get().cmp(&other.as_nonzero().get())
234 }
235}
236
237#[unstable(feature = "ptr_alignment_type", issue = "102070")]
238#[cfg(not(feature = "ferrocene_certified"))]
239impl cmp::PartialOrd for Alignment {
240 #[inline]
241 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
242 Some(self.cmp(other))
243 }
244}
245
246#[unstable(feature = "ptr_alignment_type", issue = "102070")]
247#[cfg(not(feature = "ferrocene_certified"))]
248impl hash::Hash for Alignment {
249 #[inline]
250 fn hash<H: hash::Hasher>(&self, state: &mut H) {
251 self.as_nonzero().hash(state)
252 }
253}
254
255#[unstable(feature = "ptr_alignment_type", issue = "102070")]
257#[rustc_const_unstable(feature = "const_default", issue = "143894")]
258#[cfg(not(feature = "ferrocene_certified"))]
259impl const Default for Alignment {
260 fn default() -> Alignment {
261 Alignment::MIN
262 }
263}
264
265#[cfg(target_pointer_width = "16")]
266#[cfg_attr(not(feature = "ferrocene_certified"), derive(Copy, Clone, PartialEq, Eq))]
267#[cfg_attr(feature = "ferrocene_certified", derive(Copy, Clone))]
268#[repr(u16)]
269enum AlignmentEnum {
270 _Align1Shl0 = 1 << 0,
271 _Align1Shl1 = 1 << 1,
272 _Align1Shl2 = 1 << 2,
273 _Align1Shl3 = 1 << 3,
274 _Align1Shl4 = 1 << 4,
275 _Align1Shl5 = 1 << 5,
276 _Align1Shl6 = 1 << 6,
277 _Align1Shl7 = 1 << 7,
278 _Align1Shl8 = 1 << 8,
279 _Align1Shl9 = 1 << 9,
280 _Align1Shl10 = 1 << 10,
281 _Align1Shl11 = 1 << 11,
282 _Align1Shl12 = 1 << 12,
283 _Align1Shl13 = 1 << 13,
284 _Align1Shl14 = 1 << 14,
285 _Align1Shl15 = 1 << 15,
286}
287
288#[cfg(target_pointer_width = "32")]
289#[cfg_attr(not(feature = "ferrocene_certified"), derive(Copy, Clone, PartialEq, Eq))]
290#[cfg_attr(feature = "ferrocene_certified", derive(Copy, Clone))]
291#[repr(u32)]
292enum AlignmentEnum {
293 _Align1Shl0 = 1 << 0,
294 _Align1Shl1 = 1 << 1,
295 _Align1Shl2 = 1 << 2,
296 _Align1Shl3 = 1 << 3,
297 _Align1Shl4 = 1 << 4,
298 _Align1Shl5 = 1 << 5,
299 _Align1Shl6 = 1 << 6,
300 _Align1Shl7 = 1 << 7,
301 _Align1Shl8 = 1 << 8,
302 _Align1Shl9 = 1 << 9,
303 _Align1Shl10 = 1 << 10,
304 _Align1Shl11 = 1 << 11,
305 _Align1Shl12 = 1 << 12,
306 _Align1Shl13 = 1 << 13,
307 _Align1Shl14 = 1 << 14,
308 _Align1Shl15 = 1 << 15,
309 _Align1Shl16 = 1 << 16,
310 _Align1Shl17 = 1 << 17,
311 _Align1Shl18 = 1 << 18,
312 _Align1Shl19 = 1 << 19,
313 _Align1Shl20 = 1 << 20,
314 _Align1Shl21 = 1 << 21,
315 _Align1Shl22 = 1 << 22,
316 _Align1Shl23 = 1 << 23,
317 _Align1Shl24 = 1 << 24,
318 _Align1Shl25 = 1 << 25,
319 _Align1Shl26 = 1 << 26,
320 _Align1Shl27 = 1 << 27,
321 _Align1Shl28 = 1 << 28,
322 _Align1Shl29 = 1 << 29,
323 _Align1Shl30 = 1 << 30,
324 _Align1Shl31 = 1 << 31,
325}
326
327#[cfg(target_pointer_width = "64")]
328#[cfg_attr(not(feature = "ferrocene_certified"), derive(Copy, Clone, PartialEq, Eq))]
329#[cfg_attr(feature = "ferrocene_certified", derive(Copy, Clone))]
330#[repr(u64)]
331enum AlignmentEnum {
332 _Align1Shl0 = 1 << 0,
333 _Align1Shl1 = 1 << 1,
334 _Align1Shl2 = 1 << 2,
335 _Align1Shl3 = 1 << 3,
336 _Align1Shl4 = 1 << 4,
337 _Align1Shl5 = 1 << 5,
338 _Align1Shl6 = 1 << 6,
339 _Align1Shl7 = 1 << 7,
340 _Align1Shl8 = 1 << 8,
341 _Align1Shl9 = 1 << 9,
342 _Align1Shl10 = 1 << 10,
343 _Align1Shl11 = 1 << 11,
344 _Align1Shl12 = 1 << 12,
345 _Align1Shl13 = 1 << 13,
346 _Align1Shl14 = 1 << 14,
347 _Align1Shl15 = 1 << 15,
348 _Align1Shl16 = 1 << 16,
349 _Align1Shl17 = 1 << 17,
350 _Align1Shl18 = 1 << 18,
351 _Align1Shl19 = 1 << 19,
352 _Align1Shl20 = 1 << 20,
353 _Align1Shl21 = 1 << 21,
354 _Align1Shl22 = 1 << 22,
355 _Align1Shl23 = 1 << 23,
356 _Align1Shl24 = 1 << 24,
357 _Align1Shl25 = 1 << 25,
358 _Align1Shl26 = 1 << 26,
359 _Align1Shl27 = 1 << 27,
360 _Align1Shl28 = 1 << 28,
361 _Align1Shl29 = 1 << 29,
362 _Align1Shl30 = 1 << 30,
363 _Align1Shl31 = 1 << 31,
364 _Align1Shl32 = 1 << 32,
365 _Align1Shl33 = 1 << 33,
366 _Align1Shl34 = 1 << 34,
367 _Align1Shl35 = 1 << 35,
368 _Align1Shl36 = 1 << 36,
369 _Align1Shl37 = 1 << 37,
370 _Align1Shl38 = 1 << 38,
371 _Align1Shl39 = 1 << 39,
372 _Align1Shl40 = 1 << 40,
373 _Align1Shl41 = 1 << 41,
374 _Align1Shl42 = 1 << 42,
375 _Align1Shl43 = 1 << 43,
376 _Align1Shl44 = 1 << 44,
377 _Align1Shl45 = 1 << 45,
378 _Align1Shl46 = 1 << 46,
379 _Align1Shl47 = 1 << 47,
380 _Align1Shl48 = 1 << 48,
381 _Align1Shl49 = 1 << 49,
382 _Align1Shl50 = 1 << 50,
383 _Align1Shl51 = 1 << 51,
384 _Align1Shl52 = 1 << 52,
385 _Align1Shl53 = 1 << 53,
386 _Align1Shl54 = 1 << 54,
387 _Align1Shl55 = 1 << 55,
388 _Align1Shl56 = 1 << 56,
389 _Align1Shl57 = 1 << 57,
390 _Align1Shl58 = 1 << 58,
391 _Align1Shl59 = 1 << 59,
392 _Align1Shl60 = 1 << 60,
393 _Align1Shl61 = 1 << 61,
394 _Align1Shl62 = 1 << 62,
395 _Align1Shl63 = 1 << 63,
396}