digitalmars.D.learn - Array to argument list
- Simen Haugen (4/4) Sep 11 2008 I have an array, but I want to send them one by one to a function that
- Jarrett Billingsley (47/51) Sep 11 2008 Hm. My guess is that in general, "no", since you need to know how
- Sergey Gromov (8/30) Sep 11 2008 Obviously it works only for static arrays.
I have an array, but I want to send them one by one to a function that
has variadic arguments. Is there a way to do this at runtime?
void p(A ...)(A Args) {}
p([1, 2, 3]); // I want this to become p(1, 2, 3) somehow...
Sep 11 2008
On Thu, Sep 11, 2008 at 9:39 AM, Simen Haugen <simen norstat.no> wrote:
I have an array, but I want to send them one by one to a function that has
variadic arguments. Is there a way to do this at runtime?
void p(A ...)(A Args) {}
p([1, 2, 3]); // I want this to become p(1, 2, 3) somehow...
Hm. My guess is that in general, "no", since you need to know how
many arguments to call p with at compile time, but you don't know how
many you'll need until runtime. You'd have to generate size_t.max
instantiations of p to cover all possible array lengths, as well as
size_t.max instantiations of a helper function to convert an array
into a tuple.
However for a restricted case -- fixed-size arrays -- it's possible.
But again, the number of instantiations is proportional to the length
of the array.
Here's an ugly, completely un-transparent solution.
import tango.core.Tuple;
import tango.io.Stdout;
struct Tup(T...)
{
T vals;
}
Tup!(T) makeTup(T...)(T args)
{
Tup!(T) ret;
ret.vals = args;
return ret;
}
template Rep(int num, V...)
{
static if(num == 0)
alias Tuple!() Rep;
else
alias Tuple!(V[0], Rep!(num - 1, V)) Rep;
}
Tup!(Rep!(N, U)) toTuple(T: U[N], U, int N)(T arr)
{
Tup!(Rep!(N, U)) ret;
foreach(i, v; ret.vals)
ret.vals[i] = arr[i];
return ret;
}
void p(A...)(A args)
{
foreach(i, arg; args)
Stdout.formatln("Arg {}: {}", i, arg);
}
void main()
{
int[3] arr = [1, 2, 3];
p(toTuple(arr).vals);
}
Sep 11 2008
Simen Haugen <simen norstat.no> wrote:I have an array, but I want to send them one by one to a function that has variadic arguments. Is there a way to do this at runtime? void p(A ...)(A Args) {} p([1, 2, 3]); // I want this to become p(1, 2, 3) somehow...With a bit of template trickery I've got this:import std.stdio; void p(A ...)(A Args) { writeln(A.stringof); writeln(Args[4]); } void PassArrayAsTuple(alias fun, T: E[S], E, size_t S, R...)(T arr, R rest) { static if (S) PassArrayAsTuple!(fun)(cast(E[S-1])arr, arr[$-1], rest); else fun(rest); } void main() { PassArrayAsTuple!(p)("array"); }Obviously it works only for static arrays. I wanted to come up with something like p(ArrayTuple!("array")); but the trick with casting a static array to a smaller static array does not work for template arguments. I'm not sure that it should work for function arguments either, bit it works in DMD 2.019 indeed.
Sep 11 2008









"Jarrett Billingsley" <jarrett.billingsley gmail.com> 