clvec 0.3.0

Experimental implementation of const length Vec-like datastructure CLVec with corresponding finite index type Fin
Documentation
  • Coverage
  • 80%
    4 out of 5 items documented1 out of 1 items with examples
  • Size
  • Source code size: 32.98 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 556.67 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 8s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • devts-de

CLVec

Offers a const length Vec-like CLVec<T: Sized, const N: usize> with attached length const N : usize, and a corresponding finite index type Fin<N> that tries to move failures earlier (to compile time or to index creation time).

The idea is that this could be used in theory for safe, bounds-check free, Option-less and panic-free indexing, but this in not quite achieved in its current implementation.

This is currently implemented purly in safe Rust via an underlying Vec. This comes with 3 downsides:

  1. The bounds checks are not optimized away (reliably)
  2. The panic-freedom cannot be (easily) verified
  3. Neither length N nor allocation size are erased.

With varying degrees of unsafe code we could either

  1. Try to leverage core::hint::assert_unchecked on Fin to get rid of the bounds checks more reliably (but not guaranteed), without switching away from the Vec.
  2. Implement the Vec part ourselfves in unsafe and
    • Rely on the invariant of Fin for soundness and do unchecked access ourselves
    • Use a deterministic capacity like
      #![feature(try_reserve_kind, const_trait_impl, const_convert)]
      use std::collections::{TryReserveError, TryReserveErrorKind};
      const fn cap<const N: usize>() -> Result<usize, TryReserveError> {
          match N.checked_next_power_of_two() {
              Some(n) => Ok(n),
              None => {
                  if N <= isize::MAX as usize {
                      Ok(isize::MAX as usize)
                  } else {
                      Err(TryReserveError::from(TryReserveErrorKind::CapacityOverflow))
                  }
              },
         }
      }
      
      to support erasure and amortized grow.
    • Implement all this without panic!, so panic will be verifiably absent from the call graph (outside of const).

Inspiration

Idris2 Fin & Vect types made me think this is a cool way to avoid Options/Panic and I wondered if I could make a non-linked-list version of this in Rust with the various nightly const features.

Word of Caution

WIP Experimental Prototype. Expect random changes & possible API breaks. Also, relies on a lot of nightly Rust features. Lacks proofs and several of the desired attributes.

License

Licensed under either of

  • Apache License, Version 2.0 (LICENSE-APACHE)
  • MIT license (LICENSE-MIT)

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.