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