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


Reply via email to