]> git.nega.tv - josh/narcissus/commitdiff
Improve Box's MaybeUninit helpers
authorJoshua Simmons <josh@nega.tv>
Sun, 26 Feb 2023 18:16:59 +0000 (19:16 +0100)
committerJoshua Simmons <josh@nega.tv>
Sun, 26 Feb 2023 18:16:59 +0000 (19:16 +0100)
libs/narcissus-core/src/lib.rs

index af7268196df1e45b4c3412b77db5582d7137fc5b..1453b4eb250dbd0df604d3b42ad790ad356e2f67 100644 (file)
@@ -253,6 +253,8 @@ pub fn string_from_c_str(c_str: &[i8]) -> String {
     String::from_utf8_lossy(s).into_owned()
 }
 
+/// Constructs a new box with uninitialized contents.
+#[inline]
 pub fn uninit_box<T>() -> Box<MaybeUninit<T>> {
     let layout = std::alloc::Layout::new::<MaybeUninit<T>>();
     unsafe {
@@ -261,6 +263,8 @@ pub fn uninit_box<T>() -> Box<MaybeUninit<T>> {
     }
 }
 
+/// Constructs a new box with zeroed contents.
+#[inline]
 pub fn zeroed_box<T>() -> Box<MaybeUninit<T>> {
     let layout = std::alloc::Layout::new::<MaybeUninit<T>>();
     unsafe {
@@ -269,6 +273,21 @@ pub fn zeroed_box<T>() -> Box<MaybeUninit<T>> {
     }
 }
 
+/// Converts `Box<MaybeUninit<T>>` to `Box<T>`
+///
+/// # Safety
+///
+/// As with [`MaybeUninit::assume_init`], it is up to the caller to guarantee that the value really
+/// is in an initialized state. Calling this when the content is not yet fully initialized causes
+/// immediate undefined behavior.
+///
+/// [`MaybeUninit::assume_init`]: mem::MaybeUninit::assume_init
+#[inline]
+pub unsafe fn box_assume_init<T>(value: Box<MaybeUninit<T>>) -> Box<T> {
+    let raw = Box::into_raw(value);
+    unsafe { Box::from_raw(raw as *mut T) }
+}
+
 /// Negative traits aren't stable yet, so use a dummy PhantomData marker to implement !Send
 pub type PhantomUnsend = std::marker::PhantomData<*mut ()>;