type set
Steven Schveighoffer
schveiguy at yahoo.com
Mon Feb 28 06:50:41 PST 2011
On Mon, 28 Feb 2011 09:27:36 -0500, spir <denis.spir at gmail.com> wrote:
> 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);
> }
There is a final switch, but I don't know if that works on types. You may
be stuck with static if.
When doing things like this, I'd recommend using a mapping template. For
example:
private template typeCode(T)
{
static if(is(T == DLogical)) enum typeCode = LOGICAL;
else static if(is(T == DNumber)) enum typeCode = NUMBER;
...
else static assert(0);
}
then you almost can use this to generate the right code:
if(this.code == typeCode!T)
{
static if(is(T == DUnit)) return this.unit;
else static if(...
}
You can probably replace the inner static if with a mixin, if you name
your union members properly (i.e. if you can generate the name of the
union member based on its type name or code, like DUnit dunit_val).
But at least it gives you an idea of how this can be done efficiently.
Plus avoiding large repetitive static ifs can save you from tedious
copy-pasting bugs like the one in your DList branch ;)
-Steve
More information about the Digitalmars-d-learn
mailing list