Heapless no_std
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?
The ways I know how to support this are
- adding some sort of
Storagetype parameter to the arena (eitherVecorheapless::Vecor something else) - adding dynamic dispatch to an internal storage trait object
- 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.
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.
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.
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)