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

Reply via email to