On Monday, 23 November 2015 at 11:12:33 UTC, visitor wrote:
this work fine with your unittest :
auto let(Ts...)(ref Ts vars) {
    struct Let
    {
        void opAssign( Tuple!Ts xs ) {
            foreach(i, t; Ts)
                vars[i] = xs[i];
        }

        static if (sameTypes!Ts) {
            import std.conv : text;
void opAssign(Ts[0][] xs) { // redundant but more effective enforce(xs.length == Ts.length, "let (...) = ...: array must have " ~ Ts.length.text ~ " elements.");
                foreach(i, t; Ts)
                    vars[i] = xs[i];
            }

void opAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
                static if (hasLength!R) {                                       
enforce(xs.length >= Ts.length, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
                }
                foreach(i, t; Ts) {
enforce(!xs.empty, "let (...) = ...: range must have at least " ~ Ts.length.text ~ " elements.");
                    vars[i] = xs.front;
                    xs.popFront();
                }
            }

void opIndexAssign(R)(R xs) if (isInputRange!R && is(ElementType!R == Ts[0])) {
                foreach(i, t; Ts) {
                    if(xs.empty) return;
                    vars[i] = xs.front;
                    xs.popFront();
                }
            }
        }
    }
    return Let();
}

Nice. Why first enforce is "==" rather than ">=" ? This prevents something like:

auto arr = ["hello", "world", "!"];
string hello;
string world;

let (hello, world) = arr;


Reply via email to