generational-arena icon indicating copy to clipboard operation
generational-arena copied to clipboard

Heapless no_std

Open tarcieri opened this issue 6 years ago • 4 comments

I'm interested in using this crate in a microcontroller context (it's for a DSP engine, which I've found fits the whole ECS pattern extremely well).

It seems the extant no_std support needs alloc for the purposes of allocating a Vec. Would it be possible to use a heapless::Vec instead?

tarcieri avatar Aug 02 '19 17:08 tarcieri

The ways I know how to support this are

  1. adding some sort of Storage type parameter to the arena (either Vec or heapless::Vec or something else)
  2. adding dynamic dispatch to an internal storage trait object
  3. creating a whole new arena type

I think (1) would be un-ergonomic, especially for users that are not taking advantage of this feature.

I think (2) would have unacceptable runtime cost.

And for (3) I feel that at this point it makes more sense to have a whole new crate that is specialized for the needs of micro-controller arenas.

Unless I am missing a fourth way, I think that forking this repo (in the happy, blessed, with good will version of forking) and chopping it up to be specialized for your domain is the best way to go.

fitzgen avatar Aug 02 '19 18:08 fitzgen

Approach 1 could be done as a generic type with a default of Vec, so long as the operations on that Vec can be expressed in a common trait or set of traits. That shouldn't have an impact on existing users, but would complicate the underlying implementation.

tarcieri avatar Aug 04 '19 13:08 tarcieri

If you can make a proof of concept patch that adds a generic storage type parameter with a default and the existing doc comment examples continue to Just Work without modification, then I would be convinced, and would accept a full PR that implements this.

fitzgen avatar Aug 05 '19 20:08 fitzgen

I started playing with this and think it could potentially work. What I'm playing with is a Storage trait (open to suggestions for alternative names) which has an impl for Vec, the idea being to add a heapless feature (as an optional dependency) and adding a Storage impl for heapless::Vec as well. My code isn't compiling yet but it seems plausible.

The annoying bit is if I were to do something like pub struct Arena<T, S = Vec<Entry<T>>> using a default generic parameter, the resulting crate is still dependent on alloc. I'm curious if that might actually work in a case where I link alloc but don't use it in a program, but I think there's a cleaner option...

Would it be acceptable to do something like:

pub struct Arena<T, S: Storage> {
    [...]
}

pub type ArenaVec<T> = Arena<Vec<Entry<T>>;

(there's probably a better name for ArenaVec, like HeapArena possibly)

tarcieri avatar Aug 13 '19 22:08 tarcieri