[−][src]Struct stackbox::StackBox
Stack1-allocated Box. Think of this as of &'frame mut T, but
with move semantics (no reborrowing!) which allow the "reference" to drop
its pointee.
1 Pedantic nit: actually, it is local-allocated: if the
local is created inside a generator such as an async block or function,
and that generator / future is Box-ed, then the local will be living on
the heap.
Given the move semantics / lack of reborrowing, there may seem to be
little point in using this over the seemingly more flexible
&'frame mut T, or the clearly more simple T.
And indeed that is mostly true: the usage of this wrapper is a bit niche. Use this wrapper when:
-
You want / need the move semantics (
FnOnce) ⇒ no&mutfor you (assumingOption::takeis too cumbersome, costly or directly unusable for your use case). -
You need the indirection:
-
if
Tis big, and you need move semantics, movingTaround may be expensive if the compiler is not able to elide the bitwise-copies (memcpy) that happen when the value is moved. Main usage
If you need a fat pointer to perform some type erasure, while preserving ownership /
movesemantics, and you don't want (or actually can't) use the heap allocation fromBox, then this type is for you!
-
Examples of type erasure
1 - Array to slice coercion and IntoIter
IntoIterator for arrays slices:
use ::stackbox::prelude::*; stackbox!([ String::from("Hello, "), String::from("World!"), ] => let boxed_slice: StackBox<'_, [_]>); for s in boxed_slice { println!("{}", s); stuff::<String>(s); }
While &mut [T; N] → &mut [T] already covers most of the use cases,
imagine needing the [T] slice type erasure (e.g., an if branch which
yields arrays of different lengths) and also needing to have
IntoIterator available to you. And you don't want to "stupidly" pay a
heap allocation for something that should not deserve one:
use ::core::mem::ManuallyDrop; use ::stackbox::prelude::*; let mut storage = (None, None); let boxed_slice_of_strings: StackBox<'_, [String]> = if some_condition() { let p0 = storage.0.get_or_insert(ManuallyDrop::<[String; 1]>::new([ "Hi.".into(), ])); unsafe { // Safety: nobody else may free `storage.0` StackBox::assume_owns(p0) } } else { let p1 = storage.1.get_or_insert(ManuallyDrop::<[String; 2]>::new([ "Hello, ".into(), "World!".into(), ])); unsafe { // Safety: nobody else may free `storage.0` StackBox::assume_owns(p1) } } ; for s in boxed_slice_of_strings { println!("{}", s); stuff::<String>(s); }
Implementations
impl<'frame, ImplTrait: 'frame> StackBox<'frame, ImplTrait>[src]
pub fn coerce_into_dyn<StackBoxDynTrait>(
self: StackBox<'frame, ImplTrait>
) -> StackBoxDynTrait where
StackBoxDynTrait: DynCoerce<StackBox<'frame, ImplTrait>>, [src]
self: StackBox<'frame, ImplTrait>
) -> StackBoxDynTrait where
StackBoxDynTrait: DynCoerce<StackBox<'frame, ImplTrait>>,
impl<'frame, T: 'frame> StackBox<'frame, T>[src]
pub fn with_new<R, F>(value: T, ret: F) -> R where
F: for<'local> FnOnce(StackBox<'local, T>) -> R, [src]
F: for<'local> FnOnce(StackBox<'local, T>) -> R,
#[::with_locals::with]
Using this constructor can be made quite ergonomic if using the
#[with] CPS sugar:
use ::stackbox::prelude::*; use ::with_locals::with; #[with] fn main () { let stackbox: StackBox<'ref, /* … */> = StackBox::new({ /* … */ }); // … }
pub fn into_inner(self: StackBox<'frame, T>) -> T[src]
impl<'frame, T: ?Sized + 'frame> StackBox<'frame, T>[src]
pub unsafe fn assume_owns(
it: &'frame mut ManuallyDrop<T>
) -> StackBox<'frame, T>[src]
it: &'frame mut ManuallyDrop<T>
) -> StackBox<'frame, T>
Safety
This type has ownership of the pointee T. This means that despite the
borrow-looking nature of the &'frame mut, the pointee should not be
used (⇒ not dropped!) once it has been pointed to by a StackBox /
given to this function: the ManuallyDrop<T> pointee will represent
deallocated memory after the 'frame lifetime!
As a rule of thumb, it is sound to call this function when and only
when calling ManuallyDrop::drop is.
When possible (T : Sized), prefer to use the non-unsafe
constructors:
-
Either the
stackbox!macro, -
Or the CPS / callback-based
StackBox::with_newconstructor.
impl<'frame, Item: 'frame> StackBox<'frame, [Item]>[src]
pub fn stackbox_split_at(
self: StackBox<'frame, [Item]>,
mid: usize
) -> (StackBox<'frame, [Item]>, StackBox<'frame, [Item]>)[src]
self: StackBox<'frame, [Item]>,
mid: usize
) -> (StackBox<'frame, [Item]>, StackBox<'frame, [Item]>)
pub fn stackbox_pop(self: &mut StackBox<'frame, [Item]>) -> Option<Item>[src]
Trait Implementations
impl<'frame, T: ?Sized + 'frame> Deref for StackBox<'frame, T>[src]
type Target = T
The resulting type after dereferencing.
fn deref(self: &StackBox<'frame, T>) -> &T[src]
impl<'frame, T: ?Sized + 'frame> DerefMut for StackBox<'frame, T>[src]
impl<T: ?Sized, '_> Drop for StackBox<'_, T>[src]
impl<'frame, Item: 'frame> IntoIterator for StackBox<'frame, [Item]>[src]
Auto Trait Implementations
impl<'frame, T: ?Sized> RefUnwindSafe for StackBox<'frame, T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
impl<'frame, T: ?Sized> Send for StackBox<'frame, T> where
T: Send,
T: Send,
impl<'frame, T: ?Sized> Sync for StackBox<'frame, T> where
T: Sync,
T: Sync,
impl<'frame, T: ?Sized> Unpin for StackBox<'frame, T>
impl<'frame, T> !UnwindSafe for StackBox<'frame, T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized, [src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized, [src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T[src]
impl<T> From<T> for T[src]
impl<T, U> Into<U> for T where
U: From<T>, [src]
U: From<T>,
impl<I> IntoIterator for I where
I: Iterator, [src]
I: Iterator,
type Item = <I as Iterator>::Item
The type of the elements being iterated over.
type IntoIter = I
Which kind of iterator are we turning this into?
pub fn into_iter(self) -> I[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>, [src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>, [src]
U: TryFrom<T>,