@@ -110,7 +110,7 @@ unittest {
110110struct TaggedAlgebraic (U) if (is (U == union ) || is(U == struct) || is(U == enum))
111111{
112112 import std.algorithm : among;
113- import std.string : format ;
113+ import std.conv : to ;
114114
115115 // / Alias of the type used for defining the possible storage types/kinds.
116116 deprecated alias Union = U;
@@ -1313,58 +1313,60 @@ private enum OpKind {
13131313
13141314deprecated alias TypeEnum(U) = UnionFieldEnum! U;
13151315
1316+ private string generateConstructor1 (string tname) {
1317+ return " this(UnionType.FieldTypeByName!\" " ~ tname ~ ` " value)
1318+ {
1319+ static if (isUnitType!(UnionType.FieldTypeByName!"` ~ tname ~ ` "))
1320+ m_union.set!(Kind.` ~ tname ~ ` )();
1321+ else
1322+ m_union.set!(Kind.` ~ tname ~ ` )(value);
1323+ }
1324+
1325+ void opAssign(UnionType.FieldTypeByName!"` ~ tname ~ ` " value)
1326+ {
1327+ static if (isUnitType!(UnionType.FieldTypeByName!"` ~ tname ~ ` "))
1328+ m_union.set!(Kind.` ~ tname ~ ` )();
1329+ else
1330+ m_union.set!(Kind.` ~ tname ~ ` )(value);
1331+ }` ;
1332+ }
1333+
1334+ private string generateConstructor2 (string tname) {
1335+ return ` this(UnionType.FieldTypeByName!"` ~ tname ~ ` " value, Kind type)
1336+ {
1337+ switch (type) {
1338+ foreach (i, n; TaggedUnion!U.fieldNames) {
1339+ static if (is(UnionType.FieldTypeByName!"` ~ tname ~ ` " == UnionType.FieldTypes[i])) {
1340+ case __traits(getMember, Kind, n):
1341+ static if (isUnitType!(UnionType.FieldTypes[i]))
1342+ m_union.set!(__traits(getMember, Kind, n))();
1343+ else m_union.set!(__traits(getMember, Kind, n))(value);
1344+ return;
1345+ }
1346+ }
1347+ // NOTE: the default case needs to be at the bottom to avoid bogus
1348+ // unreachable code warnings (DMD issue 21671)
1349+ default: assert(false, "Invalid type ID for type " ~
1350+ UnionType.FieldTypeByName!"` ~ tname ~ ` ".stringof ~ ": " ~ to!(string)(type));
1351+ }
1352+ }` ;
1353+ }
13161354
13171355private string generateConstructors (U)()
13181356{
13191357 import std.algorithm : map;
13201358 import std.array : join;
1321- import std.string : format;
13221359 import std.traits : FieldTypeTuple;
13231360
13241361 string ret;
13251362
1326-
13271363 // normal type constructors
13281364 foreach (tname; UniqueTypeFields! U)
1329- ret ~= q{
1330- this (UnionType.FieldTypeByName! " %1$s" value)
1331- {
1332- static if (isUnitType! (UnionType.FieldTypeByName! " %1$s" ))
1333- m_union.set! (Kind.% 1 $s)();
1334- else
1335- m_union.set! (Kind.% 1 $s)(value);
1336- }
1337-
1338- void opAssign (UnionType.FieldTypeByName! " %1$s" value)
1339- {
1340- static if (isUnitType! (UnionType.FieldTypeByName! " %1$s" ))
1341- m_union.set! (Kind.% 1 $s)();
1342- else
1343- m_union.set! (Kind.% 1 $s)(value);
1344- }
1345- }.format(tname);
1365+ ret ~= generateConstructor1(tname);
13461366
13471367 // type constructors with explicit type tag
13481368 foreach (tname; AliasSeq! (UniqueTypeFields! U, AmbiguousTypeFields! U))
1349- ret ~= q{
1350- this (UnionType.FieldTypeByName! " %1$s" value, Kind type)
1351- {
1352- switch (type) {
1353- foreach (i, n; TaggedUnion! U.fieldNames) {
1354- static if (is (UnionType.FieldTypeByName! " %1$s" == UnionType.FieldTypes[i])) {
1355- case __traits (getMember, Kind, n):
1356- static if (isUnitType! (UnionType.FieldTypes[i]))
1357- m_union.set! (__traits(getMember, Kind, n))();
1358- else m_union.set! (__traits(getMember, Kind, n))(value);
1359- return ;
1360- }
1361- }
1362- // NOTE: the default case needs to be at the bottom to avoid bogus
1363- // unreachable code warnings (DMD issue 21671)
1364- default : assert (false , format(" Invalid type ID for type %%s: %%s" , UnionType.FieldTypeByName! " %1$s" .stringof, type));
1365- }
1366- }
1367- }.format(tname);
1369+ ret ~= generateConstructor2(tname);
13681370
13691371 return ret;
13701372}
0 commit comments