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