Enum inheritance

Witold Baryluk baryluk at smp.if.uj.edu.pl
Wed Aug 15 12:28:42 PDT 2007


Dnia Wed, 15 Aug 2007 14:28:03 -0400
Matthias Walter <walter at mail.math.uni-magdeburg.de> napisał/a:

> Witold Baryluk Wrote:
> 
> > Dnia Wed, 15 Aug 2007 14:13:09 -0400
> > Matthias Walter <walter at mail.math.uni-magdeburg.de> napisał/a:
> > 
> > > 
> > > Can I do the following conversion with your code?
> > > 
> > > E2 bla = E2.E;
> > > E3 foo = bla;
> > > 
> > no.
> > you can do:
> > E1 bla = E1.A;
> > E3 foo = bla;
> > 
> > Enums in D are really integers, and it will not be so simple to do
> > what you want. I don't know if opCast can be done with enums.
> > 
> > Mayby such trick:
> > 
> > enum E1 {
> >     A, B, C
> > }
> > 
> > enum E2 {
> >     E = E1.max+1, F, G
> > }
> > 
> > 
> > then it will work.
> 
> But the compiler will complain that E1 and E2 are different types, so
> semantically, your updated version will work then, but you would
> still need a cast!
> 
> Thanks for your working version, but you see that it's not very easy
> to create (you need mixins) and use (need casts) the enums this way.
> I believe that some kind of enum inheritance is worth to be included
> in the language. Any other opinions or arguments, why this is not a
> good idea at all?

so try this:

// Copyright: Public Domain
// Author: Witold Baryluk <baryluk at smp.if.uj.edu.pl>
// Date: 2007-08-15
import std.stdio;
import std.traits;

string tostr(int i) {
        if (i < 10) {
                char[] r;
                r ~= cast(char)('0'+i);
                return r;
        } else {
                return tostr(i/10) ~ cast(char)('0'+i%10);
        }
}

typedef int ET;

string Ecreate(string name, string[] es, int start = 1, string[] org =
[]) { char[] r;
        r ~= "struct "~name~" {\n";
        r ~= "  ET x;\n";
//      r ~= "  ET opCast() { return x;}\n";
        r ~= "  static "~name~" opCall(ET _x) { "~name~" temp; temp.x =
_x; return temp; }\n"; for (int i = 0; i < org.length; i++) {
                r ~= "  static "~name~" opCall("~org[i]~" _x)
{ "~name~" temp; temp.x = _x.x; return temp; }\n"; }
        for (int i = 0; i < es.length; i++) {
                r ~= "  static "~name~" "~es[i]~" = "~name~"("~tostr(i
+start)~");\n"; }
        r ~= "  static const min = "~tostr(start) ~ ";\n";
        r ~= "  static const max = "~tostr(start+es.length-1) ~ ";\n";

        r ~= "  const __all = [cast(char[])";
        for (int i = 0; i < es.length; i++) {
                if (i) r ~= ", ";
                r ~= "\""~es[i]~"\"";
        }
        r ~= "];\n";
        r ~= "  string toString() {\n";
        r ~= "          return __all[x-min];\n";
        r ~= "  }\n";

        r ~= "}\n";
        return r;
}

mixin(Ecreate("E1", ["A", "B", "C"]));
mixin(Ecreate("E2", ["D", "E", "F"], E1.max+1));

template Emerge(Ea, Eb) {
        const Emerge = Ecreate("E3", cast(string[])(Ea.__all ~
Eb.__all), Ea.min, [cast(string)Ea.stringof, Eb.stringof]); }

mixin(Emerge!(E1, E2));

void main(char[][] args) {
        writefln("E1.A=",E1.A);
        writefln("E2.F=",E2.F);
        writefln("E3.A=",E3.A);
        writefln("E3.F=",E3.F);

        E1 b1 = E1.A;
        E3 c1 = b1;
        writefln("c1=", c1);

        E2 b2 = E2.F;
        E3 c2 = b2;
        writefln("c2=", c2);

        writefln("sizeof=",c1.sizeof);
}



// 20 minutes of coding.


-- 
Witold Baryluk, aleph0
MAIL: baryluk at smp.if.uj.edu.pl
JID: movax at jabber.autocom.pl



More information about the Digitalmars-d mailing list