smallbox
Box dynamically-sized types on stack. Requires nightly rust.
Store or return trait-object and closure without heap allocation, and fallback to heap when thing goes too large.
First, add the following to your Cargo.toml
:
toml
[dependencies]
smallbox = "0.2"
Next, add this to your crate root:
rust
extern crate smallbox;
Currently smallbox by default links to the standard library, but if you would
instead like to use this crate in a #![no_std]
situation or crate, and want to
opt out heap dependency and SmallBox<T>
type, you can request this via:
toml
[dependencies]
smallbox = { version = "0.2", default-features = false }
Enable heap
feature for #![no_std]
build to link alloc
crate
and bring SmallBox<T>
back.
toml
[dependencies.smallbox]
version = "0.2"
default-features = false
features = ["heap"]
The arraydeque crate has the following cargo feature flags:
std
heap
SmallBox<T>
type, and link to alloc
crate if std
feature flag is opted out.This crate delivers two core type:
StackBox<T>
: Represents a fixed-capacity allocation, and on stack stores dynamically-sized type.
The new
method on this type allows creating a instance from a concrete type,
returning Err(value)
if the instance is too large for the allocated region.
So far, the fixed-capcity is about four words (4 * sizeof(usize)
)
SmallBox<T>
: Takes StackBox<T>
as an varience, and fallback to Box<T>
when type T
is too large for StackBox<T>
.
The simplest usage can be trait object dynamic-dispatch ```rust use smallbox::StackBox;
let val: StackBox
assert!(*val == 5) ```
One of the most obvious use case is to allow returning capturing closures without having to box them.
```rust use smallbox::StackBox;
fn make_closure(s: String) -> StackBox
let closure = makeclosure("world!".toowned()); assert_eq!(closure(), "Hello, world!"); ```
The other use case is to eliminate heap alloction for small things, except that
the object is large enough to allocte.
In addition, the inner StackBox<T>
or Box<T>
can be moved out by explicitely pattern matching on SmallBox<T>
.
```rust use smallbox::SmallBox;
let tiny: SmallBox<[u64]> = SmallBox::new([0; 2]); let big: SmallBox<[u64]> = SmallBox::new([1; 8]);
asserteq!(tiny.len(), 2); asserteq!(big[7], 1);
match tiny { SmallBox::Stack(val) => assert_eq!(*val, [0; 2]), _ => unreachable!() }
match big { SmallBox::Box(val) => assert_eq!(*val, [1; 8]), _ => unreachable!() } ```
SmallBox<T>
and StackBox<T>
StackBox<T>
allocation sizeStackBox<Any>
and SmallBox<Any>
All kinds of contribution are welcome.
Licensed under either of
at your option.