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