diff options
| author | ltdk <usr@ltdk.xyz> | 2023-08-26 12:02:45 -0400 |
|---|---|---|
| committer | ltdk <usr@ltdk.xyz> | 2023-11-18 00:05:28 -0500 |
| commit | 114873dc19d2c46f0090a7485218b1fb202648fc (patch) | |
| tree | d2e1f56dd53784a3bd367dabe5858432b3fbd29a /library/core/src/ptr/alignment.rs | |
| parent | 547ace805166137052b2b76ee6770ef7cc8aa7c1 (diff) | |
| download | rust-114873dc19d2c46f0090a7485218b1fb202648fc.tar.gz rust-114873dc19d2c46f0090a7485218b1fb202648fc.zip | |
impl more traits for ptr::Alignment, add mask method
Diffstat (limited to 'library/core/src/ptr/alignment.rs')
| -rw-r--r-- | library/core/src/ptr/alignment.rs | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index bbf7199fffa..e578d2257f6 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -42,6 +42,7 @@ impl Alignment { /// This provides the same numerical value as [`mem::align_of`], /// but in an `Alignment` instead of a `usize`. #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn of<T>() -> Self { // SAFETY: rustc ensures that type alignment is always a power of two. @@ -53,6 +54,7 @@ impl Alignment { /// /// Note that `0` is not a power of two, nor a valid alignment. #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn new(align: usize) -> Option<Self> { if align.is_power_of_two() { @@ -98,6 +100,7 @@ impl Alignment { /// Returns the alignment as a [`NonZeroUsize`] #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] pub const fn as_nonzero(self) -> NonZeroUsize { // SAFETY: All the discriminants are non-zero. @@ -118,10 +121,42 @@ impl Alignment { /// assert_eq!(Alignment::new(1024).unwrap().log2(), 10); /// ``` #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] - pub fn log2(self) -> u32 { + pub const fn log2(self) -> u32 { self.as_nonzero().trailing_zeros() } + + /// Returns a bit mask that can be used to match this alignment. + /// + /// This is equivalent to `!(self.as_usize() - 1)`. + /// + /// # Examples + /// + /// ``` + /// #![feature(ptr_alignment_type)] + /// #![feature(ptr_mask)] + /// use std::ptr::{Alignment, NonNull}; + /// + /// #[repr(align(1))] struct Align1(u8); + /// #[repr(align(2))] struct Align2(u16); + /// #[repr(align(4))] struct Align4(u32); + /// let one = <NonNull<Align1>>::dangling().as_ptr(); + /// let two = <NonNull<Align2>>::dangling().as_ptr(); + /// let four = <NonNull<Align4>>::dangling().as_ptr(); + /// + /// assert_eq!(four.mask(Alignment::of::<Align1>().mask()), four); + /// assert_eq!(four.mask(Alignment::of::<Align2>().mask()), four); + /// assert_eq!(four.mask(Alignment::of::<Align4>().mask()), four); + /// assert_ne!(one.mask(Alignment::of::<Align4>().mask()), one); + /// ``` + #[unstable(feature = "ptr_alignment_type", issue = "102070")] + #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")] + #[inline] + pub const fn mask(self) -> usize { + // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow. + !(unsafe { self.as_usize().unchecked_sub(1) }) + } } #[unstable(feature = "ptr_alignment_type", issue = "102070")] @@ -193,6 +228,14 @@ impl hash::Hash for Alignment { } } +/// Returns [`Alignment::MIN`], which is valid for any type. +#[unstable(feature = "ptr_alignment_type", issue = "102070")] +impl Default for Alignment { + fn default() -> Alignment { + Alignment::MIN + } +} + #[cfg(target_pointer_width = "16")] type AlignmentEnum = AlignmentEnum16; #[cfg(target_pointer_width = "32")] |
