On Thursday, 11 January 2018 at 08:59:01 UTC, Chirs Forest wrote:
I'm using std.variant.Variant to hold a value of unknown type (not a string, could be a numeric type or a container holding multiple numeric types). I'm trying to retrieve this value with .get!T but I need the type to do that... .type gives me TypeInfo, but that's not a type so I'm not sure how to get the type without checking the TypeInfo against all possible types (which would be a massive pain).

Since types are compile-time features, you can't just turn a TypeInfo into a type, sadly. However, provided you use Algebraic and not Variant, you have a limited type universe, and can iterate over the possibilities:

import std.variant;
import std.stdio;

template dispatch(alias Fn)
{
    auto dispatch(A)(A arg)
    if (A.AllowedTypes.length > 0)
    {
        static foreach (T; A.AllowedTypes)
        {
            if (typeid(T) == arg.type) {
                return Fn(arg.get!T);
            }
        }
    }
}

void test(int n) {
    writeln("It's an int!");
}

void test(string s) {
    writeln("It's a string!");
}

unittest {
    Algebraic!(int, string) a = 4;
    a.dispatch!test(); // It's an int!
    a = "Test";
    a.dispatch!test(); // It's a string!

    Algebraic!(float, int[]) b = 2.3f;
a.dispatch!test(); // Will not compile, since test has no overloads for float or int[].

    Variant v = 3;
v.dispatch!test; // Will not compile, since we don't know which types it can take
}

--
  Simen

Reply via email to