static-alloc 0.1.1

Replacements for `Box`, `Rc`, `Vec`, .. without `alloc`
Documentation

static-alloc

Crates.io Status Docs.rs Status License CI Status

Replacements for alloc without dynamic allocation.

Goal and Target Platform

Provides allocator based data structures for extremely resource constrained environments where the only memory guaranteed is your program's image in memory as provided by the loader. This includes Box, Rc, a FixedVec, and a Slab allocator to create the structures.

This library aims to provide functionality similar to the standard alloc crate. It is obviously far from complete, and contributions with bug fixes or more allocators are welcome. As a general principle those should provide mechanisms, not policy, have a usable direct api that does not require them to override any singleton such as the single global allocator.

Possible use cases are OS-less development, embedded, bootloaders (even stage0/1 maybe, totally untested). The primary goals are similar to the standard library simplicity, and correctness, and minimal assumptions.

Usage

As a global allocator for alloc:

use static_alloc::Slab;

#[global_allocator]
static A: Slab<[u8; 1 << 16]> = Slab::uninit();

fn main() {
    // Vec occupying `1 << 7` bytes
    let v = vec![0xdeadbeef_u32; 32];

    // … or allocate values directly.
    let buffer: &mut [u32; 32] = A.leak([0; 32])
        .unwrap();
    buffer.copy_from_slice(&v);
}

For recursive data structures:

use static_alloc::{Box, Slab};

enum List {
    Nil,
    Cons(u8, Box<'static, List>),
}

static SLAB: Slab<[u8; 1024]> = Slab::uninit();

let base = SLAB.boxed(List::Nil).unwrap();
let one = SLAB.boxed(List::Cons(0, base)).unwrap();
let two = SLAB.boxed(List::Cons(1, one)).unwrap();

As local memory pools for fixed capacity FixedVec:

use static_alloc::{FixedVec, Slab};

let mut pool: Slab<[usize; 16]> = Slab::uninit();
// Allocate a vector with capacity of 16 from the slab.
let mut vector = pool.fixed_vec(16).unwrap();

let mut num = 0;
// Push mutable ref, not `'static`, `Copy` nor `Clone`!
vector.push(&mut num);
*vector[0] = 42;

drop(vector);
assert_eq!(num, 42);

Contributing

PRs introducing more tests or documentation are very welcome! Whatever else submitted should have simplicity and composability in mind, ideas that can not be put into a draft form are likely too complex or not focussed enough. PRs should be extremely reluctant with introducing new dependencies and should contain no non-optional dependency.

Please open issues with drafts only, feature requests and 'help' issues will be closed (if you are lucky with a final comment). Stability trumps growth. I simply can not make any longterm commitment outside my intrinsic motiviation towards this project. Hence, I favour a highly usable core over a large interface that is only somewhat usable.

Additional

This project is mainly MIT licensed. You may alternatively choose the Unlicense instead in which case the copyright headers signify the parts dedicated to the public domain to the fullest possible extent instead.