From ff0fd283dd1218cb307f1fc9b510ea0e72d7ab7e Mon Sep 17 00:00:00 2001 From: Paul Backus Date: Fri, 19 Mar 2021 14:12:51 -0400 Subject: [PATCH 1/2] Refactor tests to allow non-unique typeIndex --- src/sumtype.d | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/sumtype.d b/src/sumtype.d index c0101f0..f66fbc6 100644 --- a/src/sumtype.d +++ b/src/sumtype.d @@ -1320,8 +1320,17 @@ version (D_BetterC) {} else @safe unittest { alias MySum = SumType!(int, float); - assert(MySum(42).typeIndex == IndexOf!(int, MySum.Types)); - assert(MySum(3.14).typeIndex == IndexOf!(float, MySum.Types)); + static bool isIndexOf(Target, Types...)(size_t i) + { + switch (i) { + static foreach (tid, T; Types) + case tid: return is(T == Target); + default: return false; + } + } + + assert(isIndexOf!(int, MySum.Types)(MySum(42).typeIndex)); + assert(isIndexOf!(float, MySum.Types)(MySum(3.14).typeIndex)); } // Type index for qualified SumTypes @@ -1330,12 +1339,24 @@ version (D_BetterC) {} else @safe unittest { alias MySum = SumType!(const(int[]), int[]); + static bool isIndexOf(Target, Types...)(size_t i) + { + switch (i) { + static foreach (tid, T; Types) + case tid: return is(T == Target); + default: return false; + } + } + int[] ma = [1, 2, 3]; // Construct as mutable and convert to const to get mismatched type + tag - const x = MySum(ma); + auto x = MySum(ma); + const y = MySum(ma); + auto z = const(MySum)(ma); - assert(MySum(ma).typeIndex == IndexOf!(int[], MySum.Types)); - assert(x.typeIndex == IndexOf!(const(int[]), Map!(ConstOf, MySum.Types))); + assert(isIndexOf!(int[], MySum.Types)(x.typeIndex)); + assert(isIndexOf!(const(int[]), Map!(ConstOf, MySum.Types))(y.typeIndex)); + assert(isIndexOf!(const(int[]), Map!(ConstOf, MySum.Types))(z.typeIndex)); } /// True if `T` is an instance of the `SumType` template, otherwise false. From a550c578c56a0b565804818f2bad538d09484f42 Mon Sep 17 00:00:00 2001 From: Paul Backus Date: Fri, 19 Mar 2021 14:30:10 -0400 Subject: [PATCH 2/2] Have typeIndex return the tag In most cases, this gives the same result as before. For qualified SumTypes with duplicate member types, it no longer gives a unique result for those member types. However, the result still gives the correct type when used as an index into `Map!(QualOf, Types)`. Fixes #58 on Github --- src/sumtype.d | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/sumtype.d b/src/sumtype.d index f66fbc6..282f4fe 100644 --- a/src/sumtype.d +++ b/src/sumtype.d @@ -672,16 +672,9 @@ public: * If the `SumType` is qualified, then its qualifiers are applied to * [Types] before determining the index. */ - size_t typeIndex(this This)() + size_t typeIndex() const { - import std.traits: CopyTypeQualifiers; - - alias Qualify(T) = CopyTypeQualifiers!(This, T); - alias QualifiedTypes = Map!(Qualify, Types); - - return this.match!((ref value) => - IndexOf!(typeof(value), QualifiedTypes) - ); + return tag; } } @@ -1359,6 +1352,19 @@ version (D_BetterC) {} else assert(isIndexOf!(const(int[]), Map!(ConstOf, MySum.Types))(z.typeIndex)); } +// Type index for differently-qualified versions of the same SumType +// Disabled in BetterC due to use of dynamic arrays +version (D_BetterC) {} else +@safe unittest { + alias MySum = SumType!(const(int[]), int[]); + + int[] ma = [1, 2, 3]; + auto x = MySum(ma); + const y = x; + + assert(x.typeIndex == y.typeIndex); +} + /// True if `T` is an instance of the `SumType` template, otherwise false. private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...);