Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling D templated structs as a common type

Tags:

templates

d

I'm in trouble on designing a D app. Maybe my approach is completely wrong, so I come here to you rescue me. Any suggestion, including complete rewrite, is welcome.

I have some templated types:

enum Type : byte { Message='!', Integer='@' }

struct Token (T) {
    Type type;
    T value;
}

alias Token!string MessageToken;
alias Token!long   IntegerToken;

And I need to handle these types generically:

AnyToken genToken(bool cond) {
  if (cond)
     return MessageToken(Type.Message, "nighly builds");
  else
      return IntegerToken(Type.Integer, -42);
}

AnyToken a = genToken(true);
AnyToken b = genToken(false);

How do I achieve this effect? Edit: OOP alternatives are welcome too.

like image 878
Pedro Lacerda Avatar asked Feb 05 '12 15:02

Pedro Lacerda


1 Answers

I'd have used a tagged union myself

struct Token{
    Type type;
    union{
        string str;
        long integer;
    }
    @property string strMessage()in{assert(type==Type.Message)}body{
        return str;
    }
    @property void strMessage(string s){
        type=Type.Message;
        str=s;
    }
    @property long intMessage()in{assert(type==Type.Integer)}body{
        return integer;
    }
    @property void intMessage(long l){
        type=Type.Integer;
        integer=l;
    }
}

note that there's no static (compile time) difference between them but it's pretty much the best on can do without inheritance

you can add some extra functions so it looks more like inheritance so you won't need to examine the type field so much outside the struct's functions

like image 115
ratchet freak Avatar answered Sep 28 '22 02:09

ratchet freak