parameter pack to inputRange

Erik Smith via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 8 17:14:16 PDT 2016


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;
}




More information about the Digitalmars-d-learn mailing list