On Sunday, 8 May 2016 at 23:49:40 UTC, Ali Çehreli wrote:
On 05/08/2016 04:48 PM, Erik Smith wrote:
On Sunday, 8 May 2016 at 22:37:44 UTC, Dicebot wrote:
On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote:
E front() {
final switch (index) {
/* static */ foreach (i, arg; Args) {
case i:
return arg;
}
}
}
AFAIK, this will do funny things with referencing stack if
arguments
are variables and not literals.
Thanks! The static array version works for me too. It would
be good to
understand more about what is going on. It looks like the
cost of the
static array is an extra copy for each element. Maybe there is
still a
way to avoid that.
I had to change one line of your test code. Dicebot's code work
with it:
auto toInputRange (T...) (T args) @nogc
{
import std.traits : CommonType;
alias E = CommonType!T;
struct Range
{
E[T.length] args;
size_t index;
E front () { return args[index]; }
void popFront () { ++index; }
bool empty () { return index >= args.length; }
}
Range range;
foreach (i, ref arg; args)
range.args[i] = arg;
return range;
}
static void foo(Args...)(Args args) {
import std.container.array;
auto array = Array!int(toInputRange(args)); // <-- HERE
foreach(a; array) {
import std.stdio : writeln;
writeln("e: ", a);
}
}
void main ( )
{
import std.stdio;
writeln(toInputRange(1, 2, 3));
foo(1,2,3);
}
It used to be
toInputRange!(args)
Ali
I did notice that but forgot to mention it - thanks for
clarifying. Again it definitely works but it would be nice to
find a non-copy solution. I tried to form a static array of
pointers to the args (see below). It compiled but the output was
bad. I would expect that taking the address of the arguments
should be safe as long as you are in the called function.
auto toInputRange (T...) (T args) @nogc {
import std.traits : CommonType;
alias E = CommonType!T;
struct Range {
alias P = E*;
P[T.length] args;
size_t index;
E front () { return *args[index]; }
void popFront () { ++index; }
bool empty () { return index >= args.length; }
}
Range range;
foreach (i, ref arg; args) range.args[i] = &arg;
return range;
}