std.sumtype?

Paul Backus snarwin at gmail.com
Sun Aug 29 17:49:05 UTC 2021


On Sunday, 29 August 2021 at 16:04:53 UTC, Oleg B wrote:
> It means that `sumtype.match!(v => 
> staticIndexOf!(Unqual!(typeof(v)), T.Types))(val));` doesn't 
> return true value of type index (255 instead of 2).

`staticIndexOf` returns `-1` when the type is not found, and 
`255` is what you get when you cast `-1` to `ubyte`.

> Can you suggest how to rewrite it? If it not possible, may be 
> it can be strong argument for adding `typeIndex`?

Sure. Here's the implementation of `typeIndex` using `match`:

```d
/**
  * Returns the index of the type of the `SumType`'s current value 
in the
  * `SumType`'s `Types`.
  *
  * If the `SumType` is qualified, returns the index of the type 
in `Types`
  * whose qualified version matches the `SumType`'s current value.
  */
size_t typeIndex(This)(auto ref This this_)
{
     import std.traits : CopyTypeQualifiers;
     import std.meta : IndexOf = staticIndexOf;

     alias Qualify(T) = CopyTypeQualifiers!(This, T);
     alias QualifiedTypes = Map!(Qualify, This.Types);

     return this_.match!((ref value) =>
         IndexOf!(typeof(value), QualifiedTypes)
     );
}
```

Note that this version has [the problem you complained about 
before][1] where it does not distinguish between the `int[]` and 
the `const(int[])` members of a `const(SumType!(int[], 
const(int[])))`. This is unavoidable--`match` itself is not 
capable of distinguishing between those members, so anything that 
uses `match` will also fail to do so.

If this is still a problem for you, you can strip off the 
qualifier from the `SumType` before calling `typeIndex`:

```d
         return cast(TaggedTagType!(T))((cast(Unqual!T) 
val).typeIndex);
```

An unqualified `SumType` can never have duplicate member types, 
so this will always give consistent results.

[1]: https://github.com/pbackus/sumtype/issues/58


More information about the Digitalmars-d mailing list