smallbox

Build Status crates.io docs.rs

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.

Documentation

Usage

First, add the following to your Cargo.toml:

toml [dependencies] smallbox = "0.3"

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.3", default-features = false }

Enable heap feature for #![no_std] build to link alloc crate and bring SmallBox<T> back.

toml [dependencies.smallbox] version = "0.3" default-features = false features = ["heap"]

Feature Flags

The stackbox crate has the following cargo feature flags:

Overview

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. Default capacity is four words (4 * sizeof(usize)), more details on custom capacity are at following sections.

SmallBox<T>: Takes StackBox<T> as an varience, and fallback to Box<T> when type T is too large for StackBox<T>.

Example

The simplest usage can be trait object dynamic-dispatch ```rust use smallbox::StackBox;

let val: StackBox> = StackBox::new(5usize).unwrap();

assert!(*val == 5) ```

Any downcasting is also quite a good use.

```rust use std::any::Any;

let num: StackBox = StackBox::new(1234u32).unwrap();

if let Some(num) = num.downcastref::() { asserteq!(*num, 1234); } else { unreachable!(); } ```

Another use case is to allow returning capturing closures without having to box them.

```rust use smallbox::StackBox;

fn make_closure(s: String) -> StackBoxString> { StackBox::new(move || format!("Hello, {}", s)).ok().unwrap() }

let closure = makeclosure("world!".toowned()); assert_eq!(closure(), "Hello, world!"); ```

SmallBox<T> 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 explicit pattern match.

```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!() } ```

Capacity

The custom capacity of SmallBox<T, Space> and StackBox<T,Space> is expressed by the size of type Space, which default to space::S4 represented as 4 words space (4 * usize). There are some default option in smallbox::space from S4 to S64. Anyway, you can defind your space type, or just use some array.

The resize() method on StackBox<T, Space> and SmallBox<T, Space> is used to transforms itself to the one of bigger capacity.

```rust use smallbox::SmallBox; use smallbox::space::*;

let s = SmallBox::<[usize], S8>::new([0usize; 8]); assert!(s.resize::().is_ok()); ```

Roadmap

Contribution

All kinds of contribution are welcome.

License

Licensed under either of

at your option.