www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Generating enum members

reply Milli <alezardo02 gmail.com> writes:
Hello everyone.
It's my first time starting a thread here please have patience 
and let me know if there is anything i have done wrong!

I'm currently doing a project where there are two pretty lengthy 
enums whose members depend on each other.

Declaring one after the other makes it hard to double check that 
i haven't missed anything, which is why i'm trying to make a 
template mixin where i can declare the members together and the 
template does all the appropriate sorting.
I'm not having any luck in generating the enums though.

The simplified version of what i need would be
```D
mixin template create_enum(alias members) {
   enum enumname {
     static foreach(member; members) {
       mixin(member.stringof,",");
     }
   }
}
```
which obviously doesn't work.

Is it possible at all to do something like this in D?

Thank you for the help!
Mar 15
next sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Sat, Mar 15, 2025 at 02:47:01PM +0000, Milli via Digitalmars-d wrote:
[...]
 I'm currently doing a project where there are two pretty lengthy enums
 whose members depend on each other.
 
 Declaring one after the other makes it hard to double check that i
 haven't missed anything, which is why i'm trying to make a template
 mixin where i can declare the members together and the template does
 all the appropriate sorting.
 I'm not having any luck in generating the enums though.
 
 The simplified version of what i need would be
 ```D
 mixin template create_enum(alias members) {
   enum enumname {
     static foreach(member; members) {
       mixin(member.stringof,",");
     }
   }
 }
 ```
 which obviously doesn't work.
 
 Is it possible at all to do something like this in D?
[...] Of course it's possible. D is the king of meta-programming, and something like this is right up its alley. What you want is a string mixin + CTFE: string create_enum(string[] members) { string code = "enum MyEnum { "; foreach (memb; members) { code ~= memb ~ ", "; } code ~= "}"; return code; } mixin(create_enum([ "memb1", "memb2", "memb3" ]); T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Mar 15
parent Milli <alezardo02 gmail.com> writes:
On Saturday, 15 March 2025 at 15:08:06 UTC, H. S. Teoh wrote:


oh my i don't know how i missed this feature of D altogether!

 What you want is a string mixin + CTFE:
CTFE simplifies greatly how i can approach my problem, thank you a lot!
Mar 15
prev sibling parent cc <us86kj+3rxcwe3ebdv7w grr.la> writes:
On Saturday, 15 March 2025 at 14:47:01 UTC, Milli wrote:
 Hello everyone.
 It's my first time starting a thread here please have patience 
 and let me know if there is anything i have done wrong!

 I'm currently doing a project where there are two pretty 
 lengthy enums whose members depend on each other.

 Declaring one after the other makes it hard to double check 
 that i haven't missed anything, which is why i'm trying to make 
 a template mixin where i can declare the members together and 
 the template does all the appropriate sorting.
 I'm not having any luck in generating the enums though.

 The simplified version of what i need would be
 ```D
 mixin template create_enum(alias members) {
   enum enumname {
     static foreach(member; members) {
       mixin(member.stringof,",");
     }
   }
 }
 ```
 which obviously doesn't work.

 Is it possible at all to do something like this in D?

 Thank you for the help!
If you have a 1:1 relationship between the enums, you could also declare one first as normal and then use templates/mixins to generate the second based on the first: ```d enum FooA { RED = 1, GREEN = 2, BLUE = 4, } mixin(cloneEnum!(FooA, "FooB")); string cloneEnum(E, string name)() { string s = "enum "~name~" {"; foreach (member; EnumMembers!E) { s ~= format("%s = %s.%s,", member, E.stringof, member); } s ~= "}"; return s; } void main() { assert(cast(int) FooA.BLUE == cast(int) FooB.BLUE); } ``` And of course you can modify the function if you need any special logic to exclude or modify some members.
Mar 27