Thread overview | ||||||
---|---|---|---|---|---|---|
|
July 26, 2012 Re: an enum inside another enum | ||||
---|---|---|---|---|
| ||||
On Thu, 26 Jul 2012 13:40:06 +0200, maarten van damme <maartenvd1994@gmail.com> wrote: > enum first : string{ > a="a", > b="b" > } > > enum second : string{ > a=first.a, > b=first.b, > c="c" > } > > Is there a way to make this cleaner? string EnumDefAsString(T)() if (is(T == enum)) { string result = ""; foreach (e; __traits(allMembers, T)) result ~= e ~ " = T." ~ e ~ ","; return result; } template ExtendEnum(T, string s) if (is(T == enum) && is(typeof({mixin("enum a{"~s~"}");}))) { mixin( "enum ExtendEnum {" ~ EnumDefAsString!T() ~ s ~ "}"); } enum bar { a = 1, b = 7, c = 19 } import std.typetuple; void main() { //----------------------- alias ExtendEnum!(bar, q{ // Usage example here. d = 25 }) bar2; //----------------------- foreach (i, e; __traits(allMembers, bar2)) { static assert( e == TypeTuple!("a", "b", "c", "d")[i] ); } assert( bar2.a == bar.a ); assert( bar2.b == bar.b ); assert( bar2.c == bar.c ); assert( bar2.d == 25 ); static assert(!is(typeof( ExtendEnum!(int, "a")))); static assert(!is(typeof( ExtendEnum!(bar, "25")))); } -- Simen |
July 26, 2012 Re: an enum inside another enum | ||||
---|---|---|---|---|
| ||||
Attachments: | I've also written this implementation of enumerations. It's a bit different from normal D enums, but supports inheritance, guarantees unique values, as is much more conservative in what conversions and operations it allows. I'm considering adding addition and subtraction of integers as valid operations, but I'm not sure I want to. Feel free to critique, hack, improve upon and otherwise use and abuse the code. -- Simen |
July 26, 2012 Re: an enum inside another enum | ||||
---|---|---|---|---|
| ||||
Such a shame that enums do not allow mixins to be made. This (mixin(EnumInh!First)) would've been an imho way cleaner solution then declaring your own kind off enum and doing template magic on that. I still have some problems with Simen's code (the first one, haven't yet experimented with enumeration.d) template ExtendEnum(T, string s) if (is(T == enum) && is(typeof({mixin("enum a {"~s~"}");}))){ mixin( "enum ExtendEnum {" ~ EnumDefAsString!T() ~ s ~ "}"); } The newly generated ExtendEnum will try to convert my old enum with string fields to integer fields. the mixin should generated "ExtendEnum : string" when passing in an enum with type string. Same problem apply's to the second line of this sniped. enum a doesn't have a type yet so it will try to convert everything to ints. As I seem to run into problems few others have, is my usage of enum's incorrect? |
July 26, 2012 Re: an enum inside another enum | ||||
---|---|---|---|---|
| ||||
On Thu, 26 Jul 2012 18:08:24 +0200, maarten van damme <maartenvd1994@gmail.com> wrote: > The newly generated ExtendEnum will try to convert my old enum with > string fields to integer fields. the mixin should generated > "ExtendEnum : string" when passing in an enum with type string. Same > problem apply's to the second line of this sniped. enum a doesn't have > a type yet so it will try to convert everything to ints. > > > As I seem to run into problems few others have, is my usage of enum's incorrect? I had not considered non-int enums in the first version. There is nothing wrong with the way you use enums, though I haven't yet found a good reason to extend them (I just like to :p). Fixed version below: import std.traits : OriginalType; string EnumDefAsString(T)() if (is(T == enum)) { string result = ""; foreach (e; __traits(allMembers, T)) result ~= e ~ " = T." ~ e ~ ","; return result; } template ExtendEnum(T, string s) if (is(T == enum) && is(typeof({mixin("enum a: OriginalType!T {"~s~"}");}))) { mixin( "enum ExtendEnum : OriginalType!T {" ~ EnumDefAsString!T() ~ s ~ "}"); } enum bar : string { a = "a", b = "r", c = "t", } enum baz { a = 1, b = 2, c = 3, } unittest { alias ExtendEnum!(bar, q{ // Usage example here. d = "Text" }) bar2; foreach (i, e; __traits(allMembers, bar2)) { static assert( e == ["a", "b", "c", "d"][i] ); } assert( bar2.a == bar.a ); assert( bar2.b == bar.b ); assert( bar2.c == bar.c ); assert( bar2.d == "Text" ); static assert(!is(typeof( ExtendEnum!(int, "a")))); static assert(!is(typeof( ExtendEnum!(bar, "25")))); } unittest { alias ExtendEnum!(baz, q{ // Usage example here. d = 25 }) baz2; foreach (i, e; __traits(allMembers, baz2)) { static assert( e == ["a", "b", "c", "d"][i] ); } assert( baz2.a == baz.a ); assert( baz2.b == baz.b ); assert( baz2.c == baz.c ); assert( baz2.d == 25 ); static assert(!is(typeof( ExtendEnum!(baz, "25")))); } void main() { } -- Simen |
Copyright © 1999-2021 by the D Language Foundation