Function syncpool::prelude::make_box [−][src]
pub fn make_box<T, F: Fn(Box<T>) -> Box<T>>(packer: F) -> Box<T>
This API is a wrapper on the unsafer version of the direct-to-the-heap-box APIs. The API is safe because it is the caller's responsiblity to supply the struct initialier as a closure, such that after calling the struct initializer, the returned object shall be valid and meaningful.
The closure will take the raw box object as the input parameter, which maybe invalid, and it is the closure's responsiblity to assign valid values to the fields.
Examples
Create the dangerous struct and pack valid values with it.
use syncpool::{raw_box_zeroed, make_box}; use std::mem::MaybeUninit; use std::ptr::NonNull; use std::sync::atomic::{AtomicBool, Ordering}; struct BigStruct { a: u32, b: u32, c: [u8; 0x1_000_000], } struct DangerousStruct { a: u32, b: MaybeUninit<AtomicBool>, c: NonNull<BigStruct>, } // create the object directly on the heap let mut boxed: Box<DangerousStruct> = make_box(|mut src: Box<DangerousStruct>| { // initialize the fields in the handler let mut big: &mut BigStruct = unsafe { Box::leak(raw_box_zeroed::<BigStruct>()) }; big.a = 42; big.b = 4 * 42; big.c[4200] = 125; // make sure we initialize the fields src.a = 42; src.b = MaybeUninit::new(AtomicBool::new(false)); src.c = NonNull::new(big).unwrap(); src }); // the fields are now valid let big_ref = unsafe { boxed.c.as_ref() }; assert_eq!(big_ref.c.len(), 0x1_000_000); assert_eq!(big_ref.c[4200], 125); assert_eq!(big_ref.a, 42); assert_eq!(big_ref.b, 168);