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

Reply via email to