Alias type with different initialiser.

Bastiaan Veelo via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Feb 14 03:34:22 PST 2017


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


More information about the Digitalmars-d-learn mailing list