parameter pack to inputRange

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 8 07:11:31 PDT 2016


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



More information about the Digitalmars-d-learn mailing list