0

With const generics almost here I was wondering how would one build an enum for all (or at least for many) possible variations of a const generic struct? Or if that's not possible, how would one crate a vector that's capable of containing multiple variations of the const generic struct without dynamic access?

Example code: (pseudo code)

pub struct Test<const L: usize> {
    data: [i32; L]
}

pub enum AllVariations {
    Test1(Test<1>),
    Test2(Test<2>),
    Test3(Test<3>),
    .
    .
    .
}

To clarify, with dynamic access I mean

pub trait TraitForTestType {}

and doing

let v: Vec<Box<dyn TraitForTestType>> = Vec::new();
glennsl
  • 28,186
  • 12
  • 57
  • 75
Adam
  • 743
  • 1
  • 6
  • 11
  • **without dynamic access**? How is an `enum` accessed, if not dynamic? – trent Mar 12 '21 at 13:45
  • I mean without using Vec> to identify an item. – Adam Mar 12 '21 at 13:46
  • 1
    If I understand the second bit correctly, one would and could not: `Test<1>` and `Test<2>` are different and incompatible types in the same way `Vec` and `Vec` are. – Masklinn Mar 12 '21 at 13:47
  • 1
    `enum` doesn't really seem to make sense here, because an `enum` must be at least the size of its largest variant. Can you reasonably make a vector of `Test<2305843009213693951>`s? – trent Mar 12 '21 at 14:34
  • @trentcl that's true. But what about something like Test<15> etc..., The correlation to the array size doesn't have to be constant, for example: data: [i32; L/2 + 1]. Is there an ergonomic way to code these options without having to write each variant separately in the enum? – Adam Mar 12 '21 at 16:23
  • What *about* `Test<15>`? If `AllVariations` has to be big enough to hold `Test`, it doesn't matter if you only put small values in it. Enums store their variants in-line... that's why a `Box` is necessary to store heterogenous types. I don't know how you imagine this would work and be useful without some form of indirection. (It occurs to me you could use slices -- `Box>` can be coerced to `Box>`, for example -- but the `Box` is still there. Would that be an acceptable answer, or is it still too "dynamic"?) – trent Mar 12 '21 at 16:52
  • As long as the Box is used, the items are not necessarily contiguous in memory. I was hoping to circumvent that by using the enum(I believe that's the rust equivalent of the C++ variant class, right?) but coding each individual specific case is a lot of work. But I'm getting the impression it's simply not doable and I'd have to define a trait and use the Box. – Adam Mar 12 '21 at 19:43
  • 2
    Note that as soon as one variant is bigger than a cache line, you loose all the benefit of memory continuity _even if you never use that variant_ since smaller variants include padding to make them all the same size. If you want to get the best of both worlds, your best bet is probably [`smallvec`](https://crates.io/crates/smallvec). – Jmb Mar 15 '21 at 08:01

0 Answers0