diff options
| author | oliver-giersch <oliver.giersch@gmail.com> | 2020-07-31 10:07:18 +0200 |
|---|---|---|
| committer | David Tolnay <dtolnay@gmail.com> | 2020-08-03 04:17:45 -0700 |
| commit | 6c81556a36ac5507fe1f9cd8ee699e6fa2b11077 (patch) | |
| tree | 4682d764a6627fc03ce611e926fc44c14e205722 | |
| parent | 66b97dca3c8ab51f8af7b2db7ae4c8061fbf5e9b (diff) | |
| download | rust-6c81556a36ac5507fe1f9cd8ee699e6fa2b11077.tar.gz rust-6c81556a36ac5507fe1f9cd8ee699e6fa2b11077.zip | |
adds [*mut|*const] ptr::set_ptr_value
| -rw-r--r-- | library/core/src/ptr/const_ptr.rs | 32 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 32 |
2 files changed, 64 insertions, 0 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a2acc239bd3..a16970e9fd1 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -656,6 +656,38 @@ impl<T: ?Sized> *const T { self.wrapping_offset((count as isize).wrapping_neg()) } + /// Sets the pointer value to `ptr`. + /// + /// In case `self` is a (fat) pointer to an unsized type, this operation + /// will only affect the pointer part, whereas for (thin) pointers to + /// sized types, this has the same effect as a simple assignment. + /// + /// # Examples + /// + /// This function is primarily useful for allowing byte-wise pointer + /// arithmetic on potentially fat pointers: + /// + /// ``` + /// #![feature(set_ptr_value)] + /// # use core::fmt::Debug; + /// let arr: [i32; 3] = [1, 2, 3]; + /// let mut ptr = &arr[0] as *const dyn Debug; + /// let thin = ptr as *const u8; + /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); + /// assert_eq!(unsafe { *(ptr as *const i32) }, 3); + /// ``` + #[unstable(feature = "set_ptr_value", issue = "75091")] + #[inline] + pub fn set_ptr_value(mut self, val: *const ()) -> Self { + let thin = &mut self as *mut *const T as *mut *const (); + // SAFETY: In case of a thin pointer, this operations is identical + // to a simple assignment. In case of a fat pointer, with the current + // fat pointer layout implementation, the first field of such a + // pointer is always the data pointer, which is likewise assigned. + unsafe { *thin = val }; + self + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 17fa90ecc08..b47f90c5996 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -712,6 +712,38 @@ impl<T: ?Sized> *mut T { self.wrapping_offset((count as isize).wrapping_neg()) } + /// Sets the pointer value to `ptr`. + /// + /// In case `self` is a (fat) pointer to an unsized type, this operation + /// will only affect the pointer part, whereas for (thin) pointers to + /// sized types, this has the same effect as a simple assignment. + /// + /// # Examples + /// + /// This function is primarily useful for allowing byte-wise pointer + /// arithmetic on potentially fat pointers: + /// + /// ``` + /// #![feature(set_ptr_value)] + /// # use core::fmt::Debug; + /// let mut arr: [i32; 3] = [1, 2, 3]; + /// let mut ptr = &mut arr[0] as *mut dyn Debug; + /// let thin = ptr as *mut u8; + /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); + /// assert_eq!(unsafe { *(ptr as *mut i32) }, 3); + /// ``` + #[unstable(feature = "set_ptr_value", issue = "75091")] + #[inline] + pub fn set_ptr_value(mut self, val: *mut ()) -> Self { + let thin = &mut self as *mut *mut T as *mut *mut (); + // SAFETY: In case of a thin pointer, this operations is identical + // to a simple assignment. In case of a fat pointer, with the current + // fat pointer layout implementation, the first field of such a + // pointer is always the data pointer, which is likewise assigned. + unsafe { *thin = val }; + self + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// |
