fn rc_slice_to_vec<T>(rc: Rc<[T]>) -> Result<Vec<T>, Rc<[T]>> {
use std::mem::ManuallyDrop;
if Rc::strong_count(&rc) != 1 {
return Err(rc);
}
let len = rc.len();
let mut v = Vec::with_capacity(len);
let rc_raw = Rc::into_raw(rc);
unsafe {
// SAFETY:
// * rc_raw is trivially valid for a read of `len * size_of::<T>()`
// * the pointer derived from `v` is trivially valid for a write of
// the same number of bytes
// * both pointers are properly aligned, they're derived from types
// that can hold `T`
// * the regions are from different allocations so they can't overlap
std::ptr::copy_nonoverlapping(
rc_raw.cast::<T>(),
v.spare_capacity_mut().as_mut_ptr() as *mut T, // ≙ MaybeUninit::slice_as_mut_ptr
len
);
// SAFETY:
// * `len` is the capacity we requested so it's <= capacity
// * we've initialized the elements 0..len
v.set_len(len);
// SAFETY:
// * `ManuallyDrop<T>` has the same size and alignment as `T`
// * `rc_raw` is derived from `rc` which is a `Rc`
// * elements are wrapped in `ManuallyDrop` so `T`s `Drop` implementation
// is not invoked (we've moved the elements to `v`)
Rc::decrement_strong_count(rc_raw as *const [ManuallyDrop<T>]);
}
Ok(v)
}
1条答案
按热度按时间ilmyapht1#
没有内置函数,但可以使用下面的代码:
字符串
Playground