Expand description
Small Box optimization: store small items on stack and fall back to heap for large items.
§Usage
First, add the following to your Cargo.toml:
[dependencies]
smallbox = "0.8"Next, add this to your crate root:
extern crate smallbox;If you want this crate to work with dynamically-sized types, you can enable it via:
[dependencies]
smallbox = { version = "0.8", features = ["coerce"] }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, you can request this via:
[dependencies.smallbox]
version = "0.8"
features = ["coerce"]
default-features = false§Feature Flags
This crate has the following cargo feature flags:
-
std- Optional, enabled by default
- Use libstd
- If the
stdfeature flag is disabled, thealloccrate will be linked, which requires nightly Rust.
-
coerce- Optional
- Requires nightly Rust
- Allow automatic coercion from sized
SmallBoxto unsizedSmallBox.
-
nightly- Optional
- Enables
coerce - Requires nightly Rust
- Uses strict provenance operations to be compatible with
miri
§Unsized Types
There are two ways to create an unsized SmallBox: using the smallbox!() macro or coercing
from a sized SmallBox instance.
Using the smallbox!() macro is the only option on stable Rust. This macro will check the types
of the expression and the expected type T. For any invalid type coercions, this macro triggers
a compiler error.
Once the coerce feature is enabled, sized SmallBox<T> can be coerced into SmallBox<T: ?Sized> if necessary.
§Example
Eliminate heap allocation for small items with SmallBox:
use smallbox::SmallBox;
use smallbox::space::S4;
let small: SmallBox<_, S4> = SmallBox::new([0; 2]);
let large: SmallBox<_, S4> = SmallBox::new([0; 32]);
assert_eq!(small.len(), 2);
assert_eq!(large.len(), 32);
assert_eq!(*small, [0; 2]);
assert_eq!(*large, [0; 32]);
assert_eq!(small.is_heap(), false);
assert_eq!(large.is_heap(), true);§Unsized Types
Construct with the smallbox!() macro:
#[macro_use]
extern crate smallbox;
use smallbox::SmallBox;
use smallbox::space::*;
let array: SmallBox<[usize], S2> = smallbox!([0usize, 1]);
assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);With the coerce feature:
use smallbox::SmallBox;
use smallbox::space::*;
let array: SmallBox<[usize], S2> = SmallBox::new([0usize, 1]);
assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);Any downcasting:
#[macro_use]
extern crate smallbox;
use std::any::Any;
use smallbox::SmallBox;
use smallbox::space::S2;
let num: SmallBox<dyn Any, S2> = smallbox!(1234u32);
if let Some(num) = num.downcast_ref::<u32>() {
assert_eq!(*num, 1234);
} else {
unreachable!();
}§Capacity
The capacity is expressed by the size of the type parameter Space, regardless of what the
Space actually is.
The crate provides some space types in the smallbox::space module, from S1, S2, S4 to
S64, representing "n * usize" spaces.
You can also define your own space type, such as a byte array [u8; 64]. Please note that space
alignment is also important. If the alignment of the space is smaller than the alignment of the
value, the value will be stored on the heap.
Modules§
- space
- Space types that are used to define capacity
Macros§
- smallbox
- Box value on stack or on heap depending on its size
Structs§
- Small
Box - An optimized box that store value on stack or on heap depending on its size