Skip to content

Commit

Permalink
Add functions to allocate zeroed Arc and Rc (#283)
Browse files Browse the repository at this point in the history
These require rustc 1.82
  • Loading branch information
a1phyr authored Nov 12, 2024
1 parent af8d110 commit 13f4ae0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []

Expand All @@ -61,6 +63,7 @@ latest_stable_rust = [
# Keep this list sorted.
"aarch64_simd",
"align_offset",
"alloc_uninit",
"const_zeroed",
"derive",
"min_const_generics",
Expand Down
32 changes: 32 additions & 0 deletions src/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand Down

0 comments on commit 13f4ae0

Please sign in to comment.