On 29-08-2011 22:22, Walter Bright wrote:
For the latest dmd,
https://github.com/D-Programming-Language/dmd/commit/1193f7828b444056c943742daae0a5ccf262272e
,
I've implemented the ability to disable default initialization. This
makes it practical to implement a library based "NotNull" type without a
special syntax for it. The rationale for this is (rather than making it
builtin) one can now build any type that is a restricted subset of
another type. I suspect that a non-null type is just scratching the
surface of this ability.

Here's a draft prototype of the NotNull type:

import std.c.stdio;

struct NotNull(P) if (is(typeof({P p = null;})))
{
P p;

this() @disable;

this(P q)
{
assert(q);
p = q;
}

NotNull opAssign(P q)
{
assert(q);
p = q;
return this;
}

alias p this;
}

void main()
{
int x;
NotNull!(int*) s = &x;
*s = 3;
printf("test1 %d\n", *s);
s++;
printf("test2 %d\n", s[-1]);
}

What it does is:
1. disallows instantiation with any type that null doesn't implicitly
convert to
2. disables default construction (this is the new feature)
3. intercepts construction and assignment to enforce not-nullness
4. uses alias this to forward the rest to the wrapped pointer type

For example, try this:

void main()
{
NotNull!(int*) s;
// Error: variable test.main.s initializer required for type NotNull!(int*)
}

I do think that the "this() @disable;" is an ugly syntax, and I cringe
when seeing it. But I can't think of anything better. It does make
logical sense given the existence of default construction syntax and the
@disable, so in a sense it is just connecting existing dots, which has a
compelling value.

This is great! I've often had to use classes where I wanted to use structs because the default state would result in bad behavior.

Thanks!

- Alex

Reply via email to