xxxxxxxxxx
import std.algorithm;
struct Nullable(T) {
private union U {
T value = T.init;
}
private ref _payload() inout { return _u.value; }
private U _u;
private bool _hasValue;
ref T value() {
assert(_hasValue);
return _payload;
}
void value(T val) {
cleanup();
_hasValue = true;
_payload = val;
}
void value(typeof(null)) {
cleanup();
_hasValue = false;
}
private void cleanup() {
if (!_hasValue) return;
destroy(_payload);
_hasValue = false;
}
this(T val) {
value = val;
}
~this() {
cleanup();
}
this(typeof(null) val) {
value = val;
}
void opAssign(T val) {
auto copy = U(val);
if (_hasValue)
_payload = val;
else
moveEmplace(copy.value, _payload);
}
void opAssign(typeof(null) val) {
value = val;
}
}
struct S
{
immutable int i;
Object obj;
invariant
{
assert(this.obj !is null);
}
this();
this(Object obj)
{
this.obj = obj;
}
void opAssign(S) { /* ... */ }
~this() {}
}
unittest {
Nullable!S a; // Look ma, no assert!
a = S(new Object);
}