On Monday, 23 November 2015 at 10:28:53 UTC, thedeemon wrote:
On Sunday, 22 November 2015 at 18:47:34 UTC, visitor wrote:

What is the reason for using pointers (alias pointerOf(T) = T*
 etc...)
it works without ! what am i missing ?

What and how exactly works without?
My original solution remembers in the constructor addresses of variables to fill, then does the filling in opAssign operator, so I needed a way to store the references and used pointers for that.

yes, but you are using ref : "auto let(Ts...)(ref Ts vars)"
so vars are changed, no need to store anything, no?
i was wondering if there is some subtleties or efficiency reasons for using pointers

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

Reply via email to