Skip to content

Commit

Permalink
Add as_(mut_)ptr and as_(mut_)slice to raw array pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
yotamofek committed Jan 10, 2024
1 parent 95613d1 commit 5456dd6
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
//
// Library features:
// tidy-alphabetical-start
#![feature(array_ptr_get)]
#![feature(char_indices_offset)]
#![feature(const_align_of_val)]
#![feature(const_align_of_val_raw)]
Expand Down
41 changes: 41 additions & 0 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,47 @@ impl<T> *const [T] {
}
}

impl<T, const N: usize> *const [T; N] {
/// Returns a raw pointer to the array's buffer.
///
/// This is equivalent to casting `self` to `*const T`, but more type-safe.
///
/// # Examples
///
/// ```rust
/// #![feature(array_ptr_get)]
/// use std::ptr;
///
/// let arr: *const [i8; 3] = ptr::null();
/// assert_eq!(arr.as_ptr(), ptr::null());
/// ```
#[inline]
#[unstable(feature = "array_ptr_get", issue = "119411")]
#[rustc_const_unstable(feature = "array_ptr_get", issue = "119411")]
pub const fn as_ptr(self) -> *const T {
self as *const T
}

/// Returns a raw pointer to a shared slice containing the entire array.
///
/// # Examples
///
/// ```
/// #![feature(array_ptr_get, slice_ptr_len)]
///
/// let arr: *const [i32; 3] = &[1, 2, 4] as *const [i32; 3];
/// let slice: *const [i32] = arr.as_slice();
/// assert_eq!(slice.len(), 3);
/// ```
#[inline]
#[unstable(feature = "array_ptr_get", issue = "119411")]
#[rustc_const_unstable(feature = "array_ptr_get", issue = "119411")]
pub const fn as_slice(self) -> *const [T] {
// SAFETY: `N` is the length of the array, so the pointer is always in-bounds.
unsafe { slice::from_raw_parts(self.as_ptr(), N) }
}
}

// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *const T {
Expand Down
42 changes: 42 additions & 0 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2195,6 +2195,48 @@ impl<T> *mut [T] {
}
}

impl<T, const N: usize> *mut [T; N] {
/// Returns a raw pointer to the array's buffer.
///
/// This is equivalent to casting `self` to `*const T`, but more type-safe.
///
/// # Examples
///
/// ```rust
/// #![feature(array_ptr_get)]
/// use std::ptr;
///
/// let arr: *mut [i8; 3] = ptr::null_mut();
/// assert_eq!(arr.as_mut_ptr(), ptr::null_mut());
/// ```
#[inline]
#[unstable(feature = "array_ptr_get", issue = "119411")]
pub fn as_mut_ptr(self) -> *mut T {
self as *mut T
}

/// Returns a raw pointer to a unique slice containing the entire array.
///
/// # Examples
///
/// ```
/// #![feature(array_ptr_get)]
///
/// let mut arr = [1, 2, 5];
/// let ptr: *mut [i32; 3] = &mut arr;
/// unsafe {
/// (&mut *ptr.as_mut_slice())[..2].copy_from_slice(&[3, 4]);
/// }
/// assert_eq!(arr, [3, 4, 5]);
/// ```
#[inline]
#[unstable(feature = "array_ptr_get", issue = "119411")]
pub fn as_mut_slice(self) -> *mut [T] {
// SAFETY: `N` is the length of the array, so the pointer is always in-bounds.
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), N) }
}
}

// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *mut T {
Expand Down

0 comments on commit 5456dd6

Please sign in to comment.