T.init, struct destructors and invariants - should they be called?
Stanislav Blinov
stanislav.blinov at gmail.com
Sun Nov 18 14:38:09 UTC 2018
On Sunday, 18 November 2018 at 13:05:28 UTC, FeepingCreature
wrote:
> Ping: Resurrecting this thread because @thewilsonator
> resurrected my spec pr.
>
> https://github.com/dlang/dlang.org/pull/2410
Rebuking Simen's response then :)
On Friday, 6 July 2018 at 23:37:30 UTC, Simen Kjærås wrote:
> The union brings back the exact problems we're trying to avoid.
> It also makes it impossible to handle types where
> hasElaborateAssign is true and this() is @disabled at the same
> time. There's also the issue that at best it will do the wrong
> thing when you @disable this() and init, but you probably
> shouldn't do that anyway.
https://issues.dlang.org/show_bug.cgi?id=19321
https://github.com/dlang/dmd/pull/5830
Unions have been "fixed" for some time now. Use them, no need for
hacks with ubyte.
struct Nullable(T) {
private union U {
T value = T.init;
}
private U _u;
private @property ref _payload() inout { return _u.value; }
private bool _hasValue;
@property @trusted
ref T value() {
assert(_hasValue);
return _payload;
}
@property @trusted
void value(T val) {
cleanup();
_hasValue = true;
_payload = val;
}
@property
void value(typeof(null)) {
cleanup();
_hasValue = false;
}
@trusted
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) {
value = val;
}
void opAssign(typeof(null) val) {
value = val;
}
}
struct S
{
Object obj;
invariant
{
assert(this.obj !is null);
}
@disable this();
@safe
this(Object obj)
{
this.obj = obj;
}
@safe void opAssign(S) { /* ... */ }
@safe ~this() {}
}
@safe unittest {
Nullable!S a; // Look ma, no assert!
}
More information about the Digitalmars-d
mailing list