Pedro Lacerda
Pedro Lacerda

Reputation: 1138

Handling D templated structs as a common type

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.

Upvotes: 5

Views: 185

Answers (3)

BCS
BCS

Reputation: 78585

If you really need to keep the original structs then you could create a hierarchy of classes that wrap a pointer to a struct and dispatch accordingly.

Upvotes: 2

ratchet freak
ratchet freak

Reputation: 48196

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

Upvotes: 6

Trass3r
Trass3r

Reputation: 6287

You could use std.variant.

I can't imagine another way. In the end they are completely separate types.

Upvotes: 4

Related Questions