On Sunday, 8 May 2016 at 14:11:31 UTC, Ali Çehreli wrote:
On 05/05/2016 11:08 PM, Dicebot wrote:
> Unless parameter list is very (very!) long, I'd suggest to
simply copy
> it into a stack struct. Something like this:
>
> auto toInputRange (T...) (T args)
> {
> struct Range
> {
> T args;
> size_t index;
>
> T[0] front () { return args[index]; }
> void popFront () { ++index; }
> bool empty () { return index >= args.length; }
> }
>
> return Range(args, 0);
> }
I wanted this syntax to work but when I tested I saw that T
does not expand to struct members.
I like Alex Parrill's only() solution but it allocates a
dynamic array as well by doing the equivalent of [args] in the
guts of its implementation.
As Dicebot said, unless there are tons of arguments, I think
the following is the best as it is @nogc. It executes a switch
statement for each front() call though. And I like the
CommonType!T idea there.
import std.stdio;
import std.string;
/* Support empty Args? */
@nogc pure nothrow
auto toInputRange(Args...)() {
struct Range {
size_t index;
bool empty() {
return index >= Args.length;
}
void popFront() {
++index;
}
import std.traits : CommonType;
alias E = CommonType!Args;
E front() {
final switch (index) {
/* static */ foreach (i, arg; Args) {
case i:
return arg;
}
}
}
}
return Range();
}
unittest {
import std.traits;
import std.range;
static assert(isInputRange!(ReturnType!(toInputRange!(1))));
}
void main() {
auto r = toInputRange!(1, 2.5, 3);
writeln(r);
}
Ali
I like this solution and it's exactly what I was looking for.
However, I'm having an issue when I try to apply it with an
actual variadic function. This seems like a DMD bug.
static void foo(Args...)(Args args) {
import std.container.array;
auto array = Array!int(toInputRange!(args));
foreach(a; array) {
writeln("e: ", a);
}
}
foo(1,2,3);
e:1431827808
e:32767
e:1254116144