Thread overview
Generating enum members
Mar 15
Milli
Mar 15
Milli
1 day ago
cc
March 15

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

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!

March 15
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
March 15
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!
1 day ago

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

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:

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.