Merge pull request #58 from s-ludwig/nothrow_postblit

Add forceNothrowPostblit attribute.
This commit is contained in:
Leonid Kramer 2020-06-26 23:22:09 +02:00 committed by GitHub
commit 49ab092d02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -14,7 +14,7 @@ alias visit = taggedalgebraic.visit.visit;
import std.algorithm.mutation : move, swap;
import std.meta;
import std.range : isOutputRange;
import std.traits : EnumMembers, FieldNameTuple, Unqual, isInstanceOf;
import std.traits : EnumMembers, FieldNameTuple, Unqual, hasUDA, isInstanceOf;
/** Implements a generic tagged union type.
@ -117,7 +117,12 @@ align(commonAlignment!(UnionKindTypes!(UnionFieldEnum!U))) struct TaggedUnion
static if (hasElaborateCopyConstructor!T)
{
case __traits(getMember, Kind, tname):
typeid(T).postblit(cast(void*)&trustedGet!T());
static if (hasUDA!(U, typeof(forceNothrowPostblit()))) {
try typeid(T).postblit(cast(void*)&trustedGet!T());
catch (Exception e) assert(false, e.msg);
} else {
typeid(T).postblit(cast(void*)&trustedGet!T());
}
return;
}
}
@ -542,6 +547,32 @@ unittest { // support trailing underscores properly
assert(val.intValue == 20);
}
@property auto forceNothrowPostblit()
{
if (!__ctfe) assert(false, "@forceNothrowPostblit must only be used as a UDA.");
static struct R {}
return R.init;
}
nothrow unittest {
static struct S {
this(this) nothrow {}
}
@forceNothrowPostblit
struct U {
S s;
}
alias TU = TaggedUnion!U;
TU tu, tv;
tu = S.init;
tv = tu;
}
enum isUnitType(T) = is(T == Void) || is(T == void) || is(T == typeof(null));