rustonaut / vec1

Rust `Vec<T>` wrapper that gurantees to contain at least 1 element
Apache License 2.0
88 stars 15 forks source link

Would you expand it to be be bounded? #28

Closed dzmitry-lahoda closed 1 year ago

dzmitry-lahoda commented 1 year ago

like this

https://github.com/ergoplatform/bounded-vec

dzmitry-lahoda commented 1 year ago

is it possible to do without loosing good interface and performance? or these 2 project always different. on my fork,

/// A non-empty Vec with no effective upper-bound on its length
pub type NonEmptyVec<T> = BiBoundedVec<T, 1, { usize::MAX }>;

impl<T, const U: usize> BiBoundedVec<T, 1, U> {
    pub fn new(first: T) -> Self {
        BiBoundedVec::from_vec(vec![first]).expect("compile time verified")
    }

    pub fn first_mut(&mut self) -> &mut T {
        self.inner.first_mut().expect("verified by compiler")
    }
}

Can be done, on nightly feature gate, can be

enable when feature(const_evaluatable_checked) is stable
where
     Assert<{ L > 0 }>: IsTrue,

kind of

rustonaut commented 1 year ago

I think an Vec with some additional const based bound constraints is a fundamentally different API.

For example Vec1.first() returning I instead of Option<I> relies on the lower bound being >1 and Vec1.push not being fallible is based on there not being an upper bound/it being usize::MAX.

So I think a type with two bounds either would have had many more fallible variants and/or needs a bunch of "specialized" methods which are implemented where generic bounds like LOWER_BOUND > 0 hold.

Additionally I have realized over the years that in many places where using Vec1 and similar seem to be a good idea at first, it often yields more ergonomic APIs to either custom new-type the Vec or move the bounds check to a different place/phase in the code.

Giving all this I don't think I will consider supporting const generic bounds until all functionality needed for nicely implementing them is available on stable rust.