Large tuple initialization shorthand macro

I have a large number of elements that I want to stuff in a tuple, and I do not want to write

(SomeStruct<0> {}, SomeStruct<1> {}, SomeStruct<2> {}, ..., SomeStruct<100> {})

by hand.

Is there a way around this? (Possibly using macros)
Preferably, I would also like to write the type signature too.

let some_tuple: (SomeStruct<0>, SomeStruct<1>, SomeStruct<2>, ..., SomeStruct<100>);

macro_rules! can't loop, but if you pass 101 arguments to it you could make it work -- even 101 of the same token would work, since you could generate

(SomeStruct<{0}> {}, SomeStruct<{0+1}> {}, SomeStruct<{0+1+1}> {}, …, SomeStruct<{0+1+…+1}> {})

But maybe you could say more about what you're trying to accomplish? There might be an easier way...

1 Like

Sorry that I was unclear (My question did not accurately represent what I needed).

I need a way to fill a tuple without manually writing it all out. (The tuple will contain structs with const generics)

Kinda like:

let mut tuple = ();
for i in 0..100 /* Could be much larger */ {
    tuple.extend(SomeStruct<some_data[i]>);
}

By "accomplish", I'm assuming @scottmcm was trying to ask what higher-level goal you have in mind. We already know that what you immediately want is to fill a tuple; the question is why.

3 Likes

I'm working on a project where structs need to take parameters. (Such as struct SomeStruct<const x: i32> {})

I need to create an array of SomeStruct, but the x part of each element in the array might be different. (So I can't do let arr_of_some_struct: [SomeStruct<_>; 3] = [SomeStruct<1> {}, SomeStruct<2> {}, SomeStruct<3> {}]; or anything similar)

I decided on using tuples, as they can store items of multiple types.

Now I need a way to fill those tuples without writing the whole thing out manually. (As the amount of repeated code would be horrendous)

I too sense an XY problem here (between this and your last question). Note that you can't dynamically iterate or index a tuple (because each element is a different type, and Rust is statically typed). Using this data structure is going to be a pain [1]. Your horrendously redundant code issue will pop up everywhere.

If the main motivation is optimization, it's likely premature, and replacing bounds checks with 100s of monomorphized types may actually hinder optimization.


  1. unless the entire program is itself generated, maybe ↩︎

3 Likes

I will look into other solutions.
Thank you.

I did not realise you could not do something like

for i in 0..n {
  println!("{}", tuple.i);
}

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.