From 13f4ae0cdf1f6481940c12451407c48d159fc284 Mon Sep 17 00:00:00 2001 From: Alphyr <47725341+a1phyr@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:42:04 +0100 Subject: [PATCH] Add functions to allocate zeroed `Arc` and `Rc` (#283) These require rustc 1.82 --- Cargo.toml | 3 +++ src/allocation.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index ee1ccca..c273325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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", diff --git a/src/allocation.rs b/src/allocation.rs index 817e23c..e116f42 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -149,6 +149,38 @@ pub fn zeroed_slice_box(length: usize) -> Box<[T]> { try_zeroed_slice_box(length).unwrap() } +/// Allocates a `Arc` with all contents being zeroed out. +#[cfg(all(feature = "alloc_uninit", target_has_atomic = "ptr"))] +pub fn zeroed_arc() -> Arc { + 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(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` with all contents being zeroed out. +#[cfg(feature = "alloc_uninit")] +pub fn zeroed_rc() -> Rc { + 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(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(