Issue 10490 - Type enum in std.variant.Algebraic for final switches
Summary: Type enum in std.variant.Algebraic for final switches
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-27 13:48 UTC by bearophile_hugs
Modified: 2024-12-01 16:18 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2013-06-27 13:48:47 UTC
This enhancement request is just an idea. Maybe better ideas can be found.

Given the definition of an Algebraic like this:

import std.variant;
struct Foo {}
void main() {
    alias T = Algebraic!(int, Foo);
}



I think it can be a good idea to generate automatically inside T an enum and a method like this:

enum Type { int_, Foo; }

@property Type theType() const { return ...; }

(Built-in types are keywords so they get a leading underscore.)


So an Algebraic can be used in a final switch:

import std.variant;
struct Foo {}
void main() {
    alias T = Algebraic!(int, Foo);
    auto t = T(5);
    final switch (t.theType) {
        case T.Type.int_:
            auto p = t.peek!int;
            break;
        case T.Type.Foo:
            auto p = t.peek!Foo;
            break;
    }
}


(Currently T.type is a TypeInfo, that can't be used in a final switch.)

This allows a poor man's safe pattern matching on an Algebraic.

An implementation of Issue 596 will allow to use a bit better pattern matching on an Algebraic.
Comment 1 Diggory 2013-06-27 15:04:30 UTC
This is related to Issue 10127

Personally I like that syntax where you use the actual type name rather than putting an underscore in front - it means you can easily use any type, not just ones that can be named.

Algebraic could then have an alias to a particular instantiation of that TypeEnum template inside it rather than generating its own.
Comment 2 Justin Whear 2015-04-17 18:39:29 UTC
I've been using this solution, perhaps it should be included in std.variant, though possibly with a better name:

----
import std.variant;
import std.traits : isInstanceOf;

/**
 * Calls the correct overload of Fun based on the runtime value of the Variant value.
 */
auto applyToAlgebraic(alias Fun, Value)(Value value)
	if (isInstanceOf!(VariantN, Value))  // Can we constrain to Algebraic only?
{
	foreach (T; Value.AllowedTypes) // unrolled at CT
		if (typeid(T) is value.type)
			return Fun(value.get!T);
	assert(0);
}
----
Comment 3 Justin Whear 2015-04-17 21:17:22 UTC
Oops, that should use `value.peek!T`, not `value.get!T`
Comment 4 dlangBugzillaToGithub 2024-12-01 16:18:05 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/phobos/issues/9608

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB