1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
//! 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. //! //! # Usage //! First, add the following to your `Cargo.toml`: //! //! ```toml //! [dependencies] //! smallbox = "0.2" //! ``` //! //! Next, add this to your crate root: //! //! ```rust //! extern crate smallbox; //! ``` //! //! //! # 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. 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>`. //! //! //! # Example //! One of the most obvious uses is to allow returning capturing closures without having to box them. //! //! ```rust //! use smallbox::StackBox; //! //! fn make_closure(s: String) -> StackBox<Fn()->String> { //! StackBox::new(move || format!("Hello, {}", s)).ok().unwrap() //! } //! //! let closure = make_closure("world!".to_owned()); //! assert_eq!(closure(), "Hello, world!"); //! ``` //! //! The other uses is to eliminate heap alloction for small things, only when 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]); //! //! assert_eq!(tiny.len(), 2); //! assert_eq!(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!() //! } //! ``` #![feature(unsize)] #![feature(box_syntax)] mod stackbox; mod smallbox; pub use stackbox::StackBox; pub use smallbox::SmallBox;