about summary refs log tree commit diff
path: root/library/core/src/ptr/alignment.rs
diff options
context:
space:
mode:
authorltdk <usr@ltdk.xyz>2023-08-26 12:02:45 -0400
committerltdk <usr@ltdk.xyz>2023-11-18 00:05:28 -0500
commit114873dc19d2c46f0090a7485218b1fb202648fc (patch)
treed2e1f56dd53784a3bd367dabe5858432b3fbd29a /library/core/src/ptr/alignment.rs
parent547ace805166137052b2b76ee6770ef7cc8aa7c1 (diff)
downloadrust-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.rs45
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")]