about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2021-11-22 02:08:59 -0800
committerScott McMurray <scottmcm@users.noreply.github.com>2021-11-22 02:08:59 -0800
commit875e01e6166d4b5dea370023564703968a3cd92a (patch)
treeab5c788464b1eca2908e35e687a3192401ca96c9
parentf7c48297ce21ac0dc5b36ff730377bdb7be6ece4 (diff)
downloadrust-875e01e6166d4b5dea370023564703968a3cd92a.tar.gz
rust-875e01e6166d4b5dea370023564703968a3cd92a.zip
Add `<*{const|mut} T>::{to|from}_bits`
Named based on the floating-point methods of the same name, as those are also about returning the *representation* of the value.
-rw-r--r--library/core/src/ptr/const_ptr.rs48
-rw-r--r--library/core/src/ptr/mut_ptr.rs49
2 files changed, 97 insertions, 0 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 344b483662a..03f17e0697c 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -48,6 +48,54 @@ impl<T: ?Sized> *const T {
         self as _
     }
 
+    /// Casts a pointer to its raw bits.
+    ///
+    /// This is equivalent to `as usize`, but is more specific to enhance readability.
+    /// The inverse method is [`Self::from_bits`].
+    ///
+    /// In particular, `*p as usize` and `p as usize` will both compile for
+    /// pointers to numeric types but do very different things, so using this
+    /// helps emphasize that reading the bits was intentional.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// let array = [13, 42];
+    /// let p0: *const i32 = &array[0];
+    /// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
+    /// let p1: *const i32 = &array[1];
+    /// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn to_bits(self) -> usize
+    where
+        T: Sized,
+    {
+        self as usize
+    }
+
+    /// Creates a pointer from its raw bits.
+    ///
+    /// This is equivalent to `as *const T`, but is more specific to enhance readability.
+    /// The inverse method is [`Self::to_bits`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// use std::ptr::NonNull;
+    /// let dangling: *const u8 = NonNull::dangling().as_ptr();
+    /// assert_eq!(<*const u8>::from_bits(1), dangling);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn from_bits(bits: usize) -> Self
+    where
+        T: Sized,
+    {
+        bits as Self
+    }
+
     /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts`].
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index f3b2bdfefe5..5a5ce5ee121 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -47,6 +47,55 @@ impl<T: ?Sized> *mut T {
         self as _
     }
 
+    /// Casts a pointer to its raw bits.
+    ///
+    /// This is equivalent to `as usize`, but is more specific to enhance readability.
+    /// The inverse method is [`Self::from_bits`].
+    ///
+    /// In particular, `*p as usize` and `p as usize` will both compile for
+    /// pointers to numeric types but do very different things, so using this
+    /// helps emphasize that reading the bits was intentional.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// let mut array = [13, 42];
+    /// let mut it = array.iter_mut();
+    /// let p0: *mut i32 = it.next().unwrap();
+    /// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0);
+    /// let p1: *mut i32 = it.next().unwrap();
+    /// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn to_bits(self) -> usize
+    where
+        T: Sized,
+    {
+        self as usize
+    }
+
+    /// Creates a pointer from its raw bits.
+    ///
+    /// This is equivalent to `as *mut T`, but is more specific to enhance readability.
+    /// The inverse method is [`Self::to_bits`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ptr_to_from_bits)]
+    /// use std::ptr::NonNull;
+    /// let dangling: *mut u8 = NonNull::dangling().as_ptr();
+    /// assert_eq!(<*mut u8>::from_bits(1), dangling);
+    /// ```
+    #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
+    pub fn from_bits(bits: usize) -> Self
+    where
+        T: Sized,
+    {
+        bits as Self
+    }
+
     /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts_mut`].