Skip to content

Commit 8d7e33b

Browse files
bjoernagergitbot
authored and
gitbot
committed
Add 'into_array' conversion destructors for 'Box', 'Rc', and 'Arc';
1 parent 7ceb062 commit 8d7e33b

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

alloc/src/boxed.rs

+20
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,26 @@ impl<T> Box<[T]> {
761761
};
762762
unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) }
763763
}
764+
765+
/// Converts the boxed slice into a boxed array.
766+
///
767+
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
768+
///
769+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
770+
#[unstable(feature = "slice_as_array", issue = "133508")]
771+
#[inline]
772+
#[must_use]
773+
pub fn into_array<const N: usize>(self) -> Option<Box<[T; N]>> {
774+
if self.len() == N {
775+
let ptr = Self::into_raw(self) as *mut [T; N];
776+
777+
// 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.
778+
let me = unsafe { Box::from_raw(ptr) };
779+
Some(me)
780+
} else {
781+
None
782+
}
783+
}
764784
}
765785

766786
impl<T, A: Allocator> Box<[T], A> {

alloc/src/rc.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,26 @@ impl<T> Rc<[T]> {
10841084
))
10851085
}
10861086
}
1087+
1088+
/// Converts the reference-counted slice into a reference-counted array.
1089+
///
1090+
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
1091+
///
1092+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1093+
#[unstable(feature = "slice_as_array", issue = "133508")]
1094+
#[inline]
1095+
#[must_use]
1096+
pub fn into_array<const N: usize>(self) -> Option<Rc<[T; N]>> {
1097+
if self.len() == N {
1098+
let ptr = Self::into_raw(self) as *const [T; N];
1099+
1100+
// 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.
1101+
let me = unsafe { Rc::from_raw(ptr) };
1102+
Some(me)
1103+
} else {
1104+
None
1105+
}
1106+
}
10871107
}
10881108

10891109
impl<T, A: Allocator> Rc<[T], A> {

alloc/src/sync.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,26 @@ impl<T> Arc<[T]> {
12031203
))
12041204
}
12051205
}
1206+
1207+
/// Converts the reference-counted slice into a reference-counted array.
1208+
///
1209+
/// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type.
1210+
///
1211+
/// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
1212+
#[unstable(feature = "slice_as_array", issue = "133508")]
1213+
#[inline]
1214+
#[must_use]
1215+
pub fn into_array<const N: usize>(self) -> Option<Arc<[T; N]>> {
1216+
if self.len() == N {
1217+
let ptr = Self::into_raw(self) as *const [T; N];
1218+
1219+
// 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.
1220+
let me = unsafe { Arc::from_raw(ptr) };
1221+
Some(me)
1222+
} else {
1223+
None
1224+
}
1225+
}
12061226
}
12071227

12081228
impl<T, A: Allocator> Arc<[T], A> {

0 commit comments

Comments
 (0)