Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the type of heapless::vec::VecInner's len field generic and default to usize #506

Open
Sunshine40 opened this issue Jul 27, 2024 · 1 comment

Comments

@Sunshine40
Copy link

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 usizes 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 impls 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.

@Dirbaio
Copy link
Member

Dirbaio commented Jul 27, 2024

isn't this #504?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants