On Mon, 28 Feb 2011 09:27:36 -0500, spir <denis.s...@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