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