Re: Making enum join variadic
artur Thx! Here's my final version that compiles and run: import std.stdio: writeln; import traits_ex: isEnum; import std.typetuple: allSatisfy; /** Join/Chain/Concatenate/Unite Enums $(D E1), $(D E2), ... into $(D E). See also: http://forum.dlang.org/thread/f9vc6p$1b7k$1...@digitalmars.com */ template join(ES...) if (allSatisfy!(isEnum, ES)) { mixin({ string r = enum join { ; foreach (E; ES) { import std.range: join; r ~= [__traits(allMembers, E), ].join(,); } return r ~ }; }()); } unittest { enum E1 { a, b, c } enum E2 { e, f, g } enum E3 { h, i, j} alias E1_ = join!(E1); alias E12 = join!(E1, E2); alias E123 = join!(E1, E2, E3); writeln(E123.min, ,, E123.max); } Some final questions: - Is join a good naming for this? Is chain better? - Is it better to be verbose with joinEnums? - What other useful enum algorithms are you missing? - Should this perhaps go into Phobos? If so in what module? std.algorithm, range, traits?
Re: Making enum join variadic
Its up: https://github.com/nordlow/justd/blob/master/enums.d
Re: Making enum join variadic
On Fri, May 2, 2014 at 12:59 PM, Nordlöw digitalmars-d-learn@puremagic.com wrote: Some final questions: - Is join a good naming for this? Is chain better? - Is it better to be verbose with joinEnums? I'd be verbose. It's an uncommon operation, bound to surprise a reader a bit.It's better to type a few more letters. I did not try to compile it, but what happens if the enum elements have the same name ? The same min/max/values ? Like this: enum E1 { a, b, c } alias E111 = join!(E1, E1, E1); - What other useful enum algorithms are you missing? - Should this perhaps go into Phobos? If so in what module? std.algorithm, range, traits? I would put it in std.typecons, since it's a type constructor
Re: Making enum join variadic
I'd be verbose. It's an uncommon operation, bound to surprise a reader a bit.It's better to type a few more letters. See update. I did not try to compile it, but what happens if the enum elements have the same name ? The same min/max/values ? Like this: enum E1 { a, b, c } alias E111 = join!(E1, E1, E1); This should give a better error message, than current mixin error. I'll work on that. I would put it in std.typecons, since it's a type constructor Ok. Thx!
Re: Making enum join variadic
On Friday, 2 May 2014 at 12:45:44 UTC, Nordlöw wrote: I'd be verbose. It's an uncommon operation, bound to surprise a reader a bit.It's better to type a few more letters. See update. I did not try to compile it, but what happens if the enum elements have the same name ? The same min/max/values ? Like this: enum E1 { a, b, c } alias E111 = join!(E1, E1, E1); This should give a better error message, than current mixin error. I'll work on that. I would put it in std.typecons, since it's a type constructor Ok. Thx! Here's my try at detecting member names collision at compile time: template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E)) { bool[string] allMembers; // used to detect member collisions mixin({ string r = enum MemberNamesUnion { ; foreach (T; E) { import std.range: join; foreach (member; __traits(allMembers, T)) { static assert (member in allMembers, Member collision); allMembers[member] = true; } r ~= [__traits(allMembers, T)].join(,) ~ ,; } return r ~ }; }()); } It fails as enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem?
Re: Making enum join variadic
On Friday, 2 May 2014 at 13:38:39 UTC, Nordlöw wrote: enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem? Associative arrays are not CTFE-able.
Re: Making enum join variadic
On Friday, 2 May 2014 at 14:36:16 UTC, Meta wrote: On Friday, 2 May 2014 at 13:38:39 UTC, Nordlöw wrote: enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem? Associative arrays are not CTFE-able. So that leaves me with using an array of bool and rank() then, I guess...
Re: Making enum join variadic
So that leaves me with using an array of bool and rank() then, I guess... Correction: I mean array of strings and find.
Re: Making enum join variadic
On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote: template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E)) { bool[string] allMembers; // used to detect member collisions mixin({ string r = enum MemberNamesUnion { ; foreach (T; E) { import std.range: join; foreach (member; __traits(allMembers, T)) { static assert (member in allMembers, Member collision); allMembers[member] = true; } r ~= [__traits(allMembers, T)].join(,) ~ ,; } return r ~ }; }()); } It fails as enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem? Move the AA declaration to inside the lambda, remove the 'static' from the assert, and fix the condition (member !in allMembers), then it will work. artur
Re: Making enum join variadic
On Friday, 2 May 2014 at 15:18:06 UTC, Artur Skawina via Digitalmars-d-learn wrote: On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote: template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E)) { bool[string] allMembers; // used to detect member collisions mixin({ string r = enum MemberNamesUnion { ; foreach (T; E) { import std.range: join; foreach (member; __traits(allMembers, T)) { static assert (member in allMembers, Member collision); allMembers[member] = true; } r ~= [__traits(allMembers, T)].join(,) ~ ,; } return r ~ }; }()); } It fails as enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem? Move the AA declaration to inside the lambda, remove the 'static' from the assert, and fix the condition (member !in allMembers), then it will work. artur But that will also move the compile time check to a runtime one.
Re: Making enum join variadic
On 05/02/14 17:27, Meta via Digitalmars-d-learn wrote: On Friday, 2 May 2014 at 15:18:06 UTC, Artur Skawina via Digitalmars-d-learn wrote: On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote: template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E)) { bool[string] allMembers; // used to detect member collisions mixin({ string r = enum MemberNamesUnion { ; foreach (T; E) { import std.range: join; foreach (member; __traits(allMembers, T)) { static assert (member in allMembers, Member collision); allMembers[member] = true; } r ~= [__traits(allMembers, T)].join(,) ~ ,; } return r ~ }; }()); } It fails as enums.d(25,46): Error: static variable allMembers cannot be read at compile time enums.d(25,21):while evaluating: static assert(a in allMembers) Is there a solution to this problem? Move the AA declaration to inside the lambda, remove the 'static' from the assert, and fix the condition (member !in allMembers), then it will work. But that will also move the compile time check to a runtime one. No; mixin arguments are always evaluated at CT. artur
Making enum join variadic
How can I make `join` variadic (by filling in njoin) in the following code? import std.stdio: writeln; import std.traits; string enumsHelper(S...)(S s) { typeof(return) r; foreach (i, e; s) { if (i = 1) r ~= , ; r ~= e; } return r; } /** Join/Chain/Concatenate/Unite Enums $(D E1), $(D E2), ... into $(D E). See also: http://forum.dlang.org/thread/f9vc6p$1b7k$1...@digitalmars.com */ template join(string E, E1, E2) { const join = (enum ~ E ~ { ~ enumsHelper(__traits(allMembers, E1)) ~ , ~ enumsHelper(__traits(allMembers, E2)) ~ } ); } template njoin(string E, Ei...) { import std.algorithm: map; enum string njoin = enum ~ E ~ { ~ ~ } ; } void main(string[] args) { enum E1 { A, B, C } enum E2 { E, F, G } mixin(join!(E12, E1, E2)); E12 e12; writeln(e12.min, ,, e12.max); }
Re: Making enum join variadic
Nordlöw: How can I make `join` variadic (by filling in njoin) in the following code? When you have a D tuple (not Phobos tuple), and it contains values all of the same type, you can turn it into an array with just: [mytuple] Once you have an array of strings, you can use the normal phobos function to join the strings as you desire. Bye, bearophile
Re: Making enum join variadic
On 05/02/14 00:24, Nordlöw via Digitalmars-d-learn wrote: How can I make `join` variadic (by filling in njoin) in the following code? import std.array, std.range, std.algorithm; import std.stdio; template Njoin(ES...) { mixin({ string r = enum Njoin { ; foreach (E; ES) r ~= [__traits(allMembers, E), ].join(,); return r ~ }; }()); } void main(string[] args) { enum E1 { A, B, C } enum E2 { E, F, G } alias E12 = Njoin!(E1, E2); E12 e12; writeln(e12.min, ,, e12.max); } artur