parameter pack to inputRange
Erik Smith via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun May 8 15:00:07 PDT 2016
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
More information about the Digitalmars-d-learn
mailing list