heapless
heapless copied to clipboard
Make the type of `heapless::vec::VecInner`'s `len` field generic and default to `usize`
Motivation
Currently, heapless::String<33>
takes 48 bytes and Option<heapless::String<33>>
takes 56 bytes on 64-bit target platforms.
We could save up to 14 / 21 bytes respectively and remove the align(8)
requirement if we allow using user-specified types such as u8
to represent the occupied length. heapless::String<33>
could even allow niche optimization if a enum with only 34 variants can be used as the type of field len
in heapless::vec::VecInner<u8, OwnedStorage<33>>
.
Implementation
Since the API should resemble alloc::Vec
which uses usize
s everywhere to represent length / capacity / offset, we need to define a trait for an arbitrary type to interop with usize
.
And I think the TrustedStep
trait in nightly std could be a good start.
We could make a replica of the trait and it's impl
s for std types so the trait could be used in stable Rust.
Then we define the following traits:
pub trait Offset: Step {
/// The value to represent "zero size" or "no offset"
const ZERO: Self;
/// The number of *successor* steps required to get from `Self::Zero` to the max possible `Self` value.
const MAX: usize;
/// # Invariants
///
/// This should be infallible and produce the same result as `Step::steps_between(&Self::ZERO, self).unwrap()`
/// which means `Self::ZERO` is the min possible `Self` value.
fn to_usize(&self) -> usize {
Step::steps_between(&Self::ZERO, self).unwrap()
}
/// # Invariants
///
/// This should produce the same result as `Step::forward_checked(Self::ZERO, value)`
fn from_usize(value: usize) -> Option<Self> {
Step::forward_checked(Self::ZERO, value)
}
}
/// A type that upholds all invariants of [`Offset`].
///
/// # Safety
///
/// The implementation of [`Offset`] for the given type must guarantee all
/// invariants of all methods are upheld. See the [`Offset`] trait's documentation
/// for details. Consumers are free to rely on the invariants in unsafe code.
pub unsafe trait TrustedOffset: Offset + TrustedStep {}
and the TrustedOffset
trait should provide what we need to implement heapless::vec::VecInner
with.