#static #no-heap

no-std heapless

static friendly data structures that don’t require dynamic memory allocation

25 releases

✓ Uses Rust 2018 edition

0.5.0 Jul 11, 2019
0.4.4 May 2, 2019
0.4.2 Feb 12, 2019
0.4.1 Dec 16, 2018
0.1.0 Apr 27, 2017

#23 in Data structures

Download history 327/week @ 2019-03-28 229/week @ 2019-04-04 382/week @ 2019-04-11 374/week @ 2019-04-18 440/week @ 2019-04-25 446/week @ 2019-05-02 444/week @ 2019-05-09 442/week @ 2019-05-16 243/week @ 2019-05-23 310/week @ 2019-05-30 299/week @ 2019-06-06 250/week @ 2019-06-13 511/week @ 2019-06-20 749/week @ 2019-06-27 662/week @ 2019-07-04

1,841 downloads per month
Used in 35 crates (19 directly)

MIT/Apache

213KB
5K SLoC

crates.io crates.io

heapless

static friendly data structures that don't require dynamic memory allocation

Documentation

Change log

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


lib.rs:

static friendly data structures that don't require dynamic memory allocation

The core principle behind heapless is that its data structures are backed by a static memory allocation. For example, you can think of heapless::Vec as an alternative version of std::Vec with fixed capacity and that can't be re-allocated on the fly (e.g. via push).

All heapless data structures store their memory allocation inline and specify their capacity via their type parameter N. This means that you can instantiate a heapless data structure on the stack, in a static variable, or even in the heap.

use heapless::Vec; // fixed capacity `std::Vec`
use heapless::consts::U8; // type level integer used to specify capacity

// on the stack
let mut xs: Vec<u8, U8> = Vec::new(); // can hold up to 8 elements
xs.push(42).unwrap();
assert_eq!(xs.pop(), Some(42));

// in a `static` variable
// (because `const-fn` has not been fully stabilized you need to use the helper structs in
// the `i` module, which must be wrapped in a tuple struct)
static mut XS: Vec<u8, U8> = Vec(heapless::i::Vec::new());

let xs = unsafe { &mut XS };

xs.push(42);
assert_eq!(xs.pop(), Some(42));

// in the heap (though kind of pointless because no reallocation)
let mut ys: Box<Vec<u8, U8>> = Box::new(Vec::new());
ys.push(42).unwrap();
assert_eq!(ys.pop(), Some(42));

Because they have fixed capacity heapless data structures don't implicitly reallocate. This means that operations like heapless::Vec.push are truly constant time rather than amortized constant time with potentially unbounded (depends on the allocator) worst case execution time (which is bad / unacceptable for hard real time applications).

heapless data structures don't use a memory allocator which means no risk of an uncatchable Out Of Memory (OOM) condition while performing operations on them. It's certainly possible to run out of capacity while growing heapless data structures, but the API lets you handle this possibility by returning a Result on operations that may exhaust the capacity of the data structure.

List of currently implemented data structures:

Minimum Supported Rust Version (MSRV)

This crate is guaranteed to compile on stable Rust 1.36 and up with its default set of features. It might compile on older versions but that may change in any new patch release.

Dependencies

~314KB