On Monday, 13 February 2017 at 22:59:11 UTC, John Colvin wrote:
Why not use a constructor instead of static opCall?

I don't know, this comes from http://dlang.org/spec/struct.html#dynamic_struct_init. Your constructor looks a lot better. Am I missing a test case where static opCall would be called, but not the constructor? Why do the docs use static opCall?

Also, it's generally a bad idea to define `.init` for any type as code generally expects this to be the compiler-generated property (e.g. a value of type Initial!(int, 1) not of type int).

Thanks. I can't remember what confused me to think that typeof(int1.init) had to be int.

    enum initial = val;
[...]
static assert(int1.initial == 1); // typeof(int1.initial) == int

These lines have no purpose beyond illustration, right?


I now have the following, featuring the novel Scherkl-Nielsen self-important lookup:

/**
Creates an type that is mostly $(PARAM T), only with a different initial value of $(PARAM val).
*/
struct Initial(T, T val)
{
    private T _payload = val;
    alias _payload this;

    this(T v)
    {
        _payload = v;
    }

    // https://dlang.org/blog/2017/02/13/a-new-import-idiom/
    private template from(string moduleName)
    {
      mixin("import from = " ~ moduleName ~ ";");
    }

void toString(scope void delegate(const(char)[]) sink, from!"std.format".FormatSpec!char fmt)
    {
        import std.array : appender;
        import std.format : formatValue;
        auto w = appender!string();
        formatValue(w, _payload, fmt);
        sink(w.data);
    }
}

unittest
{
    alias int1 = Initial!(int, 1);
    static assert(int1.init == 1); // typeof(int1.init) == int1

    int1 i;
    assert(i == 1);
    int1 ii = 2;
    assert(ii == 2);
    assert(ii.init == 1);
    assert(int1.init == 1);

    void f(int val)
    {
        assert(val == 1);
    }
    f(i);

    int i0;
    assert(i0 == 0);
    i = i0;
    assert(i == 0);
    assert(i.init == 1);
    i0 = ii;
    assert(i0 == 2);
    assert(i0.init == 0);

    import std.string;
    assert(format("%6d", ii) == "     2");
}

Reply via email to