On 02/28/2011 02:32 PM, Steven Schveighoffer wrote:
On Mon, 28 Feb 2011 08:22:58 -0500, spir <denis.s...@gmail.com> wrote:

Hello,

I have a template condition that looks like this:

T check (T) () if (
is(T == DLogical) ||
is(T == DNumber) ||
is(T == DText) ||
is(T == DList) ||
is(T == DUnit)
) {
...
}

Is there a way to "factor out" such an expression using a kind of type set?
If only for cleaning the code; but also because such a set may get long.

T check (T) () if (is (T in validTypeSet)) {
...
}

This should probably work:

template isOneOf(X, T...)
{
static if(!T.length)
enum bool isOneOf = false;
else static if(is(X == T[0]))
enum bool isOneOf = true;
else
enum bool isOneOf = isOneOf!(X, T[1..$]);
}

T check(T) () if(isOneOf!(T, DLogical, DNumber, DText, TList, DUnit))
{
...
}

Not sure if this exists in std.traits or not, but that's where I'd look.

-Steve

Waow, great anyway! Didn't even know one can write variadic type/template param lists.

By the way, the block of the function is a series of static if-s, one for each allowed type. Is there any static switch? Or any other nicer way to write it than:

    T check (T) () if (
            is(T == DLogical) ||
            is(T == DNumber) ||
            is(T == DText) ||
            is(T == DList) ||
            is(T == DUnit)
        ) {
        TypeCode type;

        static if (is(T == DLogical))
            if (this.code == LOGICAL)
                return this.logical;
            else
                type == LOGICAL;
        static if (is(T == DNumber))
            if (this.code == NUMBER)
                return this.number;
            else
                type == NUMBER;
        static if (is(T == DText))
            if (this.code == TEXT)
                return this.text;
            else
                type == TEXT;
        static if (is(T == DList))
            if (this.code == LOGICAL)
                return this.list;
            else
                type == LOGICAL;
        static if (is(T == DUnit))
            if (this.code == UNIT)
                return this.unit;
            else
                type == UNIT;

        // type error
        throw new TypeError(type, this);
    }

This func type-checks and returns the current value of a tagged union. I would be very pleased with a mapping from types to type codes (tags). I can't do without the type param, I guess, because it's the return value's type... or can I? But the discriminating code of the union cannot be the type itself (*), instead it's a plain code. I thought at using TypeInfo-s as codes, which can then be mapped from types using typeid(). But according to sizeof, this makes the code weigh 1 word instead of one byte.

Denis

(*) Indeed. Else it would be a template generating N distinct types, which is precisely the opposite of what a union provides.
--
_________________
vita es estrany
spir.wikidot.com

Reply via email to