Is it possible to do this using const parameters?

So,throughout my projects I like using voladdress for pointer manipulation because it saves me having to do weird type casts that I find hard to read. The structs defined by voladdress look like this:

#[repr(transparent)]
pub struct VolAddress<T, R, W> { /* fields omitted */ }

#[repr(transparent)]
pub struct VolBlock<T, R, W, const C: usize> { /* fields omitted */ }

#[repr(transparent)]
pub struct VolSeries<T, R, W, const C: usize, const S: usize> { /* fields omitted */ }

pub struct Safe;

pub struct Unsafe;

Where:

  • T is the (integral) data type for pointer accesses;
  • R is either Safe or Unsafe to determine the soundness for reading from the address that this pointer points to;
  • W is either Safe or Unsafe to determine the soundness for writing to the address that this pointer points to;
  • C is the size of the volatile memory block or series; and
  • S is the stride of the volatile memory series.

The type I'm mainly discussing is the VolBlock type, although this similarly would apply to other scenarios with VolSeries.

In embedded systems, it is often the case that devices have arbitrary sizes of queues/lists/etc. that cannot be known at compile time. For example, the NVMe specification defines submission and completion queues for both administrative and I/O commands to the controller that cannot be determined at compile time and must be determined by examining the capabilities PCIe register that is exposed by the controller. The AHCI (advanced host controller interface) specification defines command lists that can have an (arbitrary) number of command tables (up to 32), which can have an arbitrary number of commands (called "frame information structures" or FISes) (up to 65536). In these instances, is it possible to "force" the evaluation of the C and/or S parameters to occur at run time, rather than at compile time? Previously, I did this by submitting a pull request to add a dynamic version of the const types that did not accept C or S, but the crate was rewritten shortly thereafter, and I don't want to have to submit new PRs every time the crate API changes or the crate gets rewritten. I understand that I could just eliminate this abstraction entirely and just use raw pointers, but I (personally) find them unpleasant to use (needing to do 2-4 type casts just to get the data into a representation I can work with is not fun) and this takes that complexity away (though in the end it compiles down to the same code).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.