Skip to content

Commit eae81e8

Browse files
committed
Fix #10459: SumType should provide convenient access to the type index
1 parent 5f8a36f commit eae81e8

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

std/sumtype.d

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,19 @@ public:
842842
return this.match!hashOf;
843843
}
844844
}
845+
846+
/**
847+
* Returns the index of the current value's type in the `SumType`'s
848+
* $(LREF Types).
849+
*
850+
* Note that $(LREF Types) does not include type qualifiers that are
851+
* applied to the `SumType` itself. To obtain the properly-qualified type
852+
* of a qualified `SumType`'s value, use $(REF CopyTypeQualifiers, std,traits).
853+
*/
854+
size_t typeIndex() const
855+
{
856+
return tag;
857+
}
845858
}
846859

847860
// Construction
@@ -1577,6 +1590,59 @@ version (D_BetterC) {} else
15771590
static assert(SumType!int.sizeof == int.sizeof);
15781591
}
15791592

1593+
// typeIndex
1594+
@safe unittest
1595+
{
1596+
alias MySum = SumType!(int, string);
1597+
1598+
MySum a = 42;
1599+
MySum b = "hello";
1600+
1601+
assert(a.typeIndex == IndexOf!(int, MySum.Types));
1602+
assert(b.typeIndex == IndexOf!(string, MySum.Types));
1603+
}
1604+
1605+
// typeIndex with qualified SumTypes
1606+
@safe unittest
1607+
{
1608+
alias MySum = SumType!(int[], const int[], immutable int[]);
1609+
1610+
int[] a;
1611+
const int[] ca;
1612+
immutable int[] ia;
1613+
1614+
MySum s1 = a;
1615+
MySum s2 = ca;
1616+
MySum s3 = ia;
1617+
1618+
const MySum cs1 = s1;
1619+
const MySum cs2 = s2;
1620+
const MySum cs3 = s3;
1621+
1622+
// Copying a SumType doesn't change its typeIndex
1623+
assert(cs1.typeIndex == s1.typeIndex);
1624+
assert(cs2.typeIndex == s2.typeIndex);
1625+
assert(cs3.typeIndex == s3.typeIndex);
1626+
1627+
static bool isIndexOf(Target, Types...)(size_t i)
1628+
{
1629+
switch (i)
1630+
{
1631+
static foreach (tid, T; Types)
1632+
case tid: return is(T == Target);
1633+
default: return false;
1634+
}
1635+
}
1636+
1637+
// const(int[]) appears twice in ConstTypes.
1638+
// Both indices are valid return values for typeIndex.
1639+
alias ConstTypes = Map!(ConstOf, MySum.Types);
1640+
1641+
assert(isIndexOf!(const int[], ConstTypes)(cs1.typeIndex));
1642+
assert(isIndexOf!(const int[], ConstTypes)(cs2.typeIndex));
1643+
assert(isIndexOf!(immutable int[], ConstTypes)(cs3.typeIndex));
1644+
}
1645+
15801646
/// True if `T` is an instance of the `SumType` template, otherwise false.
15811647
private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);
15821648

0 commit comments

Comments
 (0)