Rollup merge of #134379 - bjoernager:slice-as-array, r=dtolnay
Add `into_array` conversion destructors for `Box`, `Rc`, and `Arc`. Tracking issue: #133508 This PR adds the `into_array` destructor for `alloc::boxed::Box<[T]>`, `alloc::rc::Rc<[T]>`, and `alloc::sync::Arc<[T]>`. Note that this PR assumes the initial proposal of these functions returning `Option`. It is still an open question whether this should instead be `Result`. We can, however, easily change this in a follow-up PR with the necessary consensus.
This commit is contained in:
commit
b618af13cf
3 changed files with 60 additions and 0 deletions
|
|
@ -761,6 +761,26 @@ impl<T> Box<[T]> {
|
|||
};
|
||||
unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) }
|
||||
}
|
||||
|
||||
/// Converts the boxed slice into a boxed array.
|
||||
///
|
||||
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
|
||||
///
|
||||
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
|
||||
#[unstable(feature = "slice_as_array", issue = "133508")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn into_array<const N: usize>(self) -> Option<Box<[T; N]>> {
|
||||
if self.len() == N {
|
||||
let ptr = Self::into_raw(self) as *mut [T; N];
|
||||
|
||||
// SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
|
||||
let me = unsafe { Box::from_raw(ptr) };
|
||||
Some(me)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> Box<[T], A> {
|
||||
|
|
|
|||
|
|
@ -1084,6 +1084,26 @@ impl<T> Rc<[T]> {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the reference-counted slice into a reference-counted array.
|
||||
///
|
||||
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
|
||||
///
|
||||
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
|
||||
#[unstable(feature = "slice_as_array", issue = "133508")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn into_array<const N: usize>(self) -> Option<Rc<[T; N]>> {
|
||||
if self.len() == N {
|
||||
let ptr = Self::into_raw(self) as *const [T; N];
|
||||
|
||||
// SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
|
||||
let me = unsafe { Rc::from_raw(ptr) };
|
||||
Some(me)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> Rc<[T], A> {
|
||||
|
|
|
|||
|
|
@ -1203,6 +1203,26 @@ impl<T> Arc<[T]> {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts the reference-counted slice into a reference-counted array.
|
||||
///
|
||||
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
|
||||
///
|
||||
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
|
||||
#[unstable(feature = "slice_as_array", issue = "133508")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn into_array<const N: usize>(self) -> Option<Arc<[T; N]>> {
|
||||
if self.len() == N {
|
||||
let ptr = Self::into_raw(self) as *const [T; N];
|
||||
|
||||
// SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length.
|
||||
let me = unsafe { Arc::from_raw(ptr) };
|
||||
Some(me)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> Arc<[T], A> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue