pub struct Box<'a, T: ?Sized> { /* private fields */ }
Expand description

An allocated instance of a type.

Example

The basic usage are allocated recursive data structures. Here is a standard example using a Bump with 'static storage duration as the allocator:

use without_alloc::{Box, alloc::LocalAllocLeakExt};
use static_alloc::Bump;

#[derive(Debug)]
enum List<T> {
    Nil,
    Cons(T, Box<'static, List<T>>),
}

static SLAB: Bump<[u8; 1024]> = Bump::uninit();

let base = SLAB.boxed(List::Nil).unwrap();
let one = SLAB.boxed(List::Cons(0, base)).unwrap();
let two = SLAB.boxed(List::Cons(1, one)).unwrap();

// We can destruct the value (not with `*` but comparable).
match Box::take(two).0 {
    List::Cons(val, _)  => assert_eq!(val, 1), // Got the value back.
    _ => unreachable!(),
}

Downsides

Unfortunately, this Box does not yet support unsizing. This is very unfortunate as it means you can’t use it for type erasure.

Design

You will likely notice quickly that this has different semantics than the std::boxed::Box. Its inner pointer may be larger and it does not allocate nor deallocate memory on its own. This only wraps a fully initialized Uninit in a RAII/Drop interface.

Of course, there is a reason for this choice. The standard Box, storing only the raw pointer (as a Unique), requires its underlying allocation to have the exact same size and align (Layout) as the value and the layout needs to be recalculated when deallocating. Without a dependency on an allocator it would seem that the underlying layout becomes less important and can be thrown away but the opposite is the case. Many converters for the std::boxed::Box rely on being able to reallocate into a suitably constructed new allocation on will. Not having this luxury at our disposal means there should be a mechanism to cope with mismatching allocations anyways. So we simply store the full Uninit provided, relying on the library user to manage other aspects of allocation for us.

Instead, this Box can offer additional ways to manipulate and massage the underlying allocation. It should be possible to restore the exact allocation Box semantics (albeit with one usize more space usage) via a wrapper when an allocator is available.

Implementations

Place val into a provided allocation.

Take out the value and return the allocation.

This function is the opposite of new.

Create a box from an pointer to an already initialized value.

Ensures that an already initialized value is properly dropped at the end of the lifetime of the Box.

Safety

The pointed-to location must have already been initialized via external means. This is as unsafe as init.as_mut().

Unwrap the contained Uninit.

The value stays initialized but that information is no longer statically available. If you simply want to avoid the Drop call, consider ManuallyDrop instead.

Consumes and leaks the Box, returning a mutable reference, &'a mut T.

Compared to a standard Box it should be noted that the reference alone is not enough to invoke Box::from_raw.

Trait Implementations

Converts this type into a mutable reference of the (usually inferred) input type.
Converts this type into a shared reference of the (usually inferred) input type.
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Unsize a Box, for example into a dynamic trait object.

Usage

use unsize::{Coercion, CoerceUnsize};
use without_alloc::Uninit;
use core::mem::MaybeUninit;

let mut memory: MaybeUninit<usize> = MaybeUninit::uninit();
let boxed = Box::new(0usize, Uninit::from(&mut memory));

let debug: Box<dyn core::fmt::Debug> = unsafe {
    boxed.unsize(Coercion::to_debug())
};
The type we point to. This influences which kinds of unsizing are possible. Read more
The output type when unsizing the pointee to U.
Get the raw inner pointer.
Replace the container inner pointer with an unsized version. Read more
Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Mutably dereferences the value.
Executes the destructor for this type. Read more
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
This method returns an Ordering between self and other. Read more
Compares and returns the maximum of two values. Read more
Compares and returns the minimum of two values. Read more
Restrict a value to a certain interval. Read more
This method tests for self and other values to be equal, and is used by ==. Read more
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more
This method returns an ordering between self and other values if one exists. Read more
This method tests less than (for self and other) and is used by the < operator. Read more
This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
This method tests greater than (for self and other) and is used by the > operator. Read more
Formats the value using the given formatter.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Convert a pointer, as if with unsize coercion. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.