use alloc::boxed::Box; use core::fmt; use core::marker::PhantomData; use core::mem::{self, MaybeUninit}; use core::ptr;
/// Number of words a piece of `Data` can hold. /// /// Three words should be enough for the majority of cases. For example, you can fit inside it the /// function pointer together with a fat pointer representing an object that needs to be destroyed. const DATA_WORDS: usize = 3;
/// Some space to keep a `FnOnce()` object on the stack. type Data = [usize; DATA_WORDS];
/// A `FnOnce()` that is stored inline if small, or otherwise boxed on the heap. /// /// This is a handy way of keeping an unsized `FnOnce()` within a sized structure. pub(crate) struct Deferred {
call: unsafefn(*mut u8),
data: MaybeUninit<Data>,
_marker: PhantomData<*mut ()>, // !Send + !Sync
}
/// Constructs a new `Deferred` from a `FnOnce()`. pub(crate) fn new<F: FnOnce()>(f: F) -> Self { let size = mem::size_of::<F>(); let align = mem::align_of::<F>();
unsafe { if size <= mem::size_of::<Data>() && align <= mem::align_of::<Data>() { letmut data = MaybeUninit::<Data>::uninit();
ptr::write(data.as_mut_ptr().cast::<F>(), f);
unsafefn call<F: FnOnce()>(raw: *mut u8) { let f: F = ptr::read(raw.cast::<F>());
f();
}
unsafefn call<F: FnOnce()>(raw: *mut u8) { // It's safe to cast `raw` from `*mut u8` to `*mut Box<F>`, because `raw` is // originally derived from `*mut Box<F>`. let b: Box<F> = ptr::read(raw.cast::<Box<F>>());
(*b)();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.