www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Enum inheritance

reply Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
For my current project, I would be happy to have some kind of enum inheritance,
is it on the plan for future changes to D?

Syntactically, it should only be an extension to the specification of an enum
base type via

enum Name : Base { Symbols, ... }

Why not allow other enums as a Base to import their symbols? As long as one
does not think about multiple inheritance (or enum-interfaces <g>), this
shouldn't be problem?! Or is it already implemented and I missed something?

best regards
Matthias
Aug 15 2007
next sibling parent reply Witold Baryluk <baryluk smp.if.uj.edu.pl> writes:
Dnia Wed, 15 Aug 2007 13:12:57 -0400
Matthias Walter <walter mail.math.uni-magdeburg.de> napisa=B3/a:

 For my current project, I would be happy to have some kind of enum
 inheritance, is it on the plan for future changes to D?
=20
 Syntactically, it should only be an extension to the specification of
 an enum base type via
=20
 enum Name : Base { Symbols, ... }
=20
 Why not allow other enums as a Base to import their symbols? As long
 as one does not think about multiple inheritance (or enum-interfaces
 <g>), this shouldn't be problem?! Or is it already implemented and I
 missed something?
=20
 best regards
 Matthias

import std.stdio; import std.traits; string Ehelper(string[] es) { char[] r; for (int i =3D 0; i < es.length; i++) { if (i) r ~=3D ", "; r ~=3D es[i]; } return r; } template EE(E0a, E0b) { const EE =3D "enum E3 { "~Ehelper(__traits(allMembers, E0a)) ~ ", " ~ Ehelper(__traits(allMembers, E0b)) ~ " }"; } enum E1 { A, B, C } enum E2 { E, F, G } mixin(EE!(E1, E2)); void main(char[][] args) { writefln(E3.A); writefln(E3.F); } --=20 "EWitold Baryluk MAIL: baryluk smp.if.uj.edu.pl, baryluk mpi.int.pl JID: movax jabber.autocom.pl
Aug 15 2007
parent reply Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
Witold Baryluk Wrote:

 Dnia Wed, 15 Aug 2007 13:12:57 -0400
 Matthias Walter <walter mail.math.uni-magdeburg.de> napisał/a:
 
 For my current project, I would be happy to have some kind of enum
 inheritance, is it on the plan for future changes to D?
 
 Syntactically, it should only be an extension to the specification of
 an enum base type via
 
 enum Name : Base { Symbols, ... }
 
 Why not allow other enums as a Base to import their symbols? As long
 as one does not think about multiple inheritance (or enum-interfaces
 <g>), this shouldn't be problem?! Or is it already implemented and I
 missed something?
 
 best regards
 Matthias

import std.stdio; import std.traits; string Ehelper(string[] es) { char[] r; for (int i = 0; i < es.length; i++) { if (i) r ~= ", "; r ~= es[i]; } return r; } template EE(E0a, E0b) { const EE = "enum E3 { "~Ehelper(__traits(allMembers, E0a)) ~ ", " ~ Ehelper(__traits(allMembers, E0b)) ~ " }"; } enum E1 { A, B, C } enum E2 { E, F, G } mixin(EE!(E1, E2)); void main(char[][] args) { writefln(E3.A); writefln(E3.F); }

Can I do the following conversion with your code? E2 bla = E2.E; E3 foo = bla; best regards Matthias
Aug 15 2007
parent Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
Witold Baryluk Wrote:

 Dnia Wed, 15 Aug 2007 14:13:09 -0400
 Matthias Walter <walter mail.math.uni-magdeburg.de> napisał/a:
 
 
 Can I do the following conversion with your code?
 
 E2 bla = E2.E;
 E3 foo = bla;
 

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? best regards Matthias
Aug 15 2007
prev sibling next sibling parent Witold Baryluk <baryluk smp.if.uj.edu.pl> writes:
Or better:

template EE(E0a, E0b) {
        const EE = "{ "~Ehelper(__traits(allMembers, E0a)) ~ ", " ~
Ehelper(__traits(allMembers, E0b)) ~ " }";
}


mixin("enum E3 "~EE!(E1, E2));



-- 
Witold Baryluk
MAIL: baryluk smp.if.uj.edu.pl, baryluk mpi.int.pl
JID: movax jabber.autocom.pl
Aug 15 2007
prev sibling next sibling parent Witold Baryluk <baryluk smp.if.uj.edu.pl> writes:
Dnia Wed, 15 Aug 2007 14:13:09 -0400
Matthias Walter <walter mail.math.uni-magdeburg.de> napisa=B3/a:

=20
 Can I do the following conversion with your code?
=20
 E2 bla =3D E2.E;
 E3 foo =3D bla;
=20

you can do: E1 bla =3D E1.A; E3 foo =3D 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 =3D E1.max+1, F, G } then it will work. best regards --=20 Witold Baryluk MAIL: baryluk smp.if.uj.edu.pl, baryluk mpi.int.pl JID: movax jabber.autocom.pl
Aug 15 2007
prev sibling next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Matthias Walter Wrote:

 For my current project, I would be happy to have some kind of enum
inheritance, is it on the plan for future changes to D?

I made a number of enum extensions that renders each enum as a mixinable template that creates a struct. They allow pretty much everything people have been asking for in enums short of Java-style "enum classes." They have string printing, enum extension, iteration through enum values, ... Yeah, that's about it. And they're still only represented by one int, so no performance penalties. I can post them if you want... Maybe I should put them in Scrapple.
Aug 15 2007
parent reply Matthias Walter <walter mail.math.uni-magdeburg.de> writes:
Robert Fraser Wrote:

 Matthias Walter Wrote:
 
 For my current project, I would be happy to have some kind of enum
inheritance, is it on the plan for future changes to D?

I made a number of enum extensions that renders each enum as a mixinable template that creates a struct. They allow pretty much everything people have been asking for in enums short of Java-style "enum classes." They have string printing, enum extension, iteration through enum values, ... Yeah, that's about it. And they're still only represented by one int, so no performance penalties. I can post them if you want... Maybe I should put them in Scrapple.

I'm not in a hurry, so putting them in scrapple would be a good idea. thanks Matthias
Aug 15 2007
parent BCS <BCS pathlink.com> writes:
Matthias Walter wrote:
 Robert Fraser Wrote:
 
 
Matthias Walter Wrote:


For my current project, I would be happy to have some kind of enum inheritance,
is it on the plan for future changes to D?

I made a number of enum extensions that renders each enum as a mixinable template that creates a struct. They allow pretty much everything people have been asking for in enums short of Java-style "enum classes." They have string printing, enum extension, iteration through enum values, ... Yeah, that's about it. And they're still only represented by one int, so no performance penalties. I can post them if you want... Maybe I should put them in Scrapple.

I'm not in a hurry, so putting them in scrapple would be a good idea. thanks Matthias

go ahead! that's what scrapple is for. (If you need access email me shro882 at vandals dot uidaho dot edu)
Aug 15 2007
prev sibling parent Witold Baryluk <baryluk smp.if.uj.edu.pl> writes:
Dnia Wed, 15 Aug 2007 14:28:03 -0400
Matthias Walter <walter mail.math.uni-magdeburg.de> napisa=B3/a:

 Witold Baryluk Wrote:
=20
 Dnia Wed, 15 Aug 2007 14:13:09 -0400
 Matthias Walter <walter mail.math.uni-magdeburg.de> napisa=B3/a:
=20
=20
 Can I do the following conversion with your code?
=20
 E2 bla =3D E2.E;
 E3 foo =3D bla;
=20

you can do: E1 bla =3D E1.A; E3 foo =3D bla; =20 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. =20 Mayby such trick: =20 enum E1 { A, B, C } =20 enum E2 { E =3D E1.max+1, F, G } =20 =20 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! =20 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 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 ~=3D 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 =3D 1, string[] org =3D []) { char[] r; r ~=3D "struct "~name~" {\n"; r ~=3D " ET x;\n"; // r ~=3D " ET opCast() { return x;}\n"; r ~=3D " static "~name~" opCall(ET _x) { "~name~" temp; temp.x =3D _x; return temp; }\n"; for (int i =3D 0; i < org.length; i++) { r ~=3D " static "~name~" opCall("~org[i]~" _x) { "~name~" temp; temp.x =3D _x.x; return temp; }\n"; } for (int i =3D 0; i < es.length; i++) { r ~=3D " static "~name~" "~es[i]~" =3D "~name~"("~tostr(i +start)~");\n"; } r ~=3D " static const min =3D "~tostr(start) ~ ";\n"; r ~=3D " static const max =3D "~tostr(start+es.length-1) ~ ";\n"; r ~=3D " const __all =3D [cast(char[])"; for (int i =3D 0; i < es.length; i++) { if (i) r ~=3D ", "; r ~=3D "\""~es[i]~"\""; } r ~=3D "];\n"; r ~=3D " string toString() {\n"; r ~=3D " return __all[x-min];\n"; r ~=3D " }\n"; r ~=3D "}\n"; return r; } mixin(Ecreate("E1", ["A", "B", "C"])); mixin(Ecreate("E2", ["D", "E", "F"], E1.max+1)); template Emerge(Ea, Eb) { const Emerge =3D 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=3D",E1.A); writefln("E2.F=3D",E2.F); writefln("E3.A=3D",E3.A); writefln("E3.F=3D",E3.F); E1 b1 =3D E1.A; E3 c1 =3D b1; writefln("c1=3D", c1); E2 b2 =3D E2.F; E3 c2 =3D b2; writefln("c2=3D", c2); writefln("sizeof=3D",c1.sizeof); } // 20 minutes of coding. --=20 Witold Baryluk, aleph0 MAIL: baryluk smp.if.uj.edu.pl JID: movax jabber.autocom.pl
Aug 15 2007