On Saturday, 12 September 2020 at 14:31:59 UTC, Paul Backus wrote:
On Saturday, 12 September 2020 at 03:19:23 UTC, mw wrote:
I.e. I want to learn the generic meta-programming way to
assemble such parameter list (&(x[i], &(y[j])) at compile
time, it is possible?
It's possible if you use a helper function. Here's how:
import std.meta: allSatisfy;
import std.traits: isArray;
void printRandomElemAddr(Arrays...)(Arrays arrays)
if (allSatisfy!(isArray, Arrays))
{
auto randomElemAddr(size_t i)()
if (i < arrays.length)
{
import std.random: uniform;
return &arrays[i][uniform(0, $)];
}
import std.stdio: writeln;
import std.meta: staticMap, aliasSeqOf;
import std.range: iota;
writeln(staticMap!(randomElemAddr,
aliasSeqOf!(iota(arrays.length))));
}
void main()
{
int[] a = [1];
int[] b = [2, 3];
double[] c = [4, 5, 6];
printRandomElemAddr(a);
printRandomElemAddr(a, b);
printRandomElemAddr(a, b, c);
}
Thanks, this works. staticMap and aliasSeqOf is the key.
Now, let me expand this challenge: suppose we need to add a new
set of variable length extra parameters in parallel to the
arrays, i.e:
// just use scalar type for demo
int extraA;
string extraB;
double extraC;
// need to be called as:
printRandomElemAddr(extraA, a);
printRandomElemAddr(extraA, extraB, a, b);
printRandomElemAddr(extraA, extraB, extraC, a, b, c);
basically, two sets of variadic parameters, but need to be
treated differently:
-- the 1st scalar set, just use as it is
-- the 2nd array set, need some processing (which you have done).
Now the question is how to pass & handle 2 sets of variadic
parameters?