Add functions to allocate zeroed Arc and Rc (#283)

These require rustc 1.82
This commit is contained in:
Alphyr 2024-11-12 20:42:04 +01:00 committed by GitHub
parent af8d110201
commit 13f4ae0cdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 0 deletions

View File

@ -47,6 +47,8 @@ transparentwrapper_extra = []
const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
alloc_uninit = [] # MSRV 1.82.0: support `zeroed_*rc*`
# Do not use if you can avoid it, because this is **unsound**!!!!
unsound_ptr_pod_impl = []
@ -61,6 +63,7 @@ latest_stable_rust = [
# Keep this list sorted.
"aarch64_simd",
"align_offset",
"alloc_uninit",
"const_zeroed",
"derive",
"min_const_generics",

View File

@ -149,6 +149,38 @@ pub fn zeroed_slice_box<T: Zeroable>(length: usize) -> Box<[T]> {
try_zeroed_slice_box(length).unwrap()
}
/// Allocates a `Arc<T>` with all contents being zeroed out.
#[cfg(all(feature = "alloc_uninit", target_has_atomic = "ptr"))]
pub fn zeroed_arc<T: Zeroable>() -> Arc<T> {
let mut arc = Arc::new_uninit();
crate::write_zeroes(Arc::get_mut(&mut arc).unwrap()); // unwrap never fails for a newly allocated Arc
unsafe { arc.assume_init() }
}
/// Allocates a `Arc<[T]>` with all contents being zeroed out.
#[cfg(all(feature = "alloc_uninit", target_has_atomic = "ptr"))]
pub fn zeroed_arc_slice<T: Zeroable>(length: usize) -> Arc<[T]> {
let mut arc = Arc::new_uninit_slice(length);
crate::fill_zeroes(Arc::get_mut(&mut arc).unwrap()); // unwrap never fails for a newly allocated Arc
unsafe { arc.assume_init() }
}
/// Allocates a `Rc<T>` with all contents being zeroed out.
#[cfg(feature = "alloc_uninit")]
pub fn zeroed_rc<T: Zeroable>() -> Rc<T> {
let mut rc = Rc::new_uninit();
crate::write_zeroes(Rc::get_mut(&mut rc).unwrap()); // unwrap never fails for a newly allocated Rc
unsafe { rc.assume_init() }
}
/// Allocates a `Rc<[T]>` with all contents being zeroed out.
#[cfg(feature = "alloc_uninit")]
pub fn zeroed_rc_slice<T: Zeroable>(length: usize) -> Rc<[T]> {
let mut rc = Rc::new_uninit_slice(length);
crate::fill_zeroes(Rc::get_mut(&mut rc).unwrap()); // unwrap never fails for a newly allocated Rc
unsafe { rc.assume_init() }
}
/// As [`try_cast_slice_box`], but unwraps for you.
#[inline]
pub fn cast_slice_box<A: NoUninit, B: AnyBitPattern>(