digitalmars.D - Using Enums to Generate Scoped List of Names
- Andrey Zherikov (63/63) Aug 03 2022 I was looking at Walter's ["Strawberries and Cream"
- Dennis (5/7) Aug 04 2022 In DMD, the generated getters/setters are `extern(C++)` so LDC
- Andrey Zherikov (34/37) Aug 04 2022 Will this work? It minimizes string mixins usage an has no
- Dennis (4/6) Aug 16 2022 Sorry for the late reply. I don't think it generates the right
- Walter Bright (3/9) Aug 16 2022 Haha, this is a nice improvement! Nobody can think of everything, which ...
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/9) Aug 16 2022 And your array-at-compile-time example can subjectively be better like t...
- Walter Bright (3/10) Aug 16 2022 True, but my example was a slide-friendly version of a much more complex...
- Salih Dincer (28/37) Aug 20 2022 Generates different types if not specifically specified. Because
I was looking at Walter's ["Strawberries and Cream" presentation](https://github.com/dlang/dconf.org/blob/master/2022/online/slid s/strawberries.pdf) this morning and "Using Enums to Generate Scoped List of Names" section caught me with bad feeling: why do you need to generate code using string mixins if this can be done in more readable way (IMHO). So I played with it a bit and here is my solution: ```d static struct S(E, T) { private T flags; private enum mask(string name) = 1 << __traits(getMember, E, name); pure nothrow nogc safe final { bool opDispatch(string name)(bool v) { v ? (flags |= mask!name) : (flags &= ~mask!name); return v; } bool opDispatch(string name)() const scope { return !!(flags & mask!name); } } } enum F {square,circle,triangle } S!(F, ubyte) s; assert(s.square = true); assert(!(s.circle = false)); assert(s.triangle = true); assert(s.square); assert(!s.circle); assert(s.triangle); ``` Compare with this from the presentation: ```d string generateBitFlags(E, T)() { string result = "pure nothrow nogc safe final {"; enum enumName = __traits(identifier, E); foreach (size_t i, mem; __traits(allMembers, E)) { static assert(i < T.sizeof * 8, "too many fields”); enum mask = "(1 << "~i.stringof~")"; result ~= " bool "~mem~"() const scope { return !!(flags & "~mask~"); } bool "~mem~"(bool v) { v ? (flags |= "~mask~") : (flags &= ~"~mask~"); return v; }"; } return result ~ "}\n private "~T.stringof~" flags;\n"; } static struct S { mixin(generateFlags!(F, ubyte)); } enum F { square, circle, triangle } S s; s.square = true; s.circle = false; s.triangle = true; assert(s.square == true); assert(s.circle == false); assert(s.triangle == true); ``` My solution can even support sparse bitmasks by simply tuning the enum: `enum F {square, circle=5, triangle=7 }`
Aug 03 2022
On Wednesday, 3 August 2022 at 15:49:25 UTC, Andrey Zherikov wrote:why do you need to generate code using string mixins if this can be done in more readable way (IMHO).In DMD, the generated getters/setters are `extern(C++)` so LDC and GDC can access them from C++. This doesn't work with opDispatch.
Aug 04 2022
On Thursday, 4 August 2022 at 14:45:26 UTC, Dennis wrote:In DMD, the generated getters/setters are `extern(C++)` so LDC and GDC can access them from C++. This doesn't work with opDispatch.Will this work? It minimizes string mixins usage an has no `opDispatch`: ```d static struct S(E, T) { private T flags; private template Impl(T mask) { pure nothrow nogc safe final { bool Impl(bool v) { v ? (flags |= mask) : (flags &= ~mask); return v; } bool Impl() const scope { return !!(flags & mask); } } } static foreach (mem; __traits(allMembers, E)) mixin("alias "~mem~" = Impl!(1 << E."~mem~");"); } enum F { square,circle=5,triangle=7 } S!(F, ubyte) s; assert(s.square = true); assert(!(s.circle = false)); assert(s.triangle = true); assert(s.square); assert(!s.circle); assert(s.triangle); ```
Aug 04 2022
On Thursday, 4 August 2022 at 23:31:37 UTC, Andrey Zherikov wrote:Will this work? It minimizes string mixins usage an has no `opDispatch`:Sorry for the late reply. I don't think it generates the right extern(C++) symbols for DMD, but I like the solution in general. Minimizing string mixins is good.
Aug 16 2022
On 8/3/2022 8:49 AM, Andrey Zherikov wrote:I was looking at Walter's ["Strawberries and Cream" presentation](https://github.com/dlang/dconf.org/blob/master/2022/online/slid s/strawberries.pdf) this morning and "Using Enums to Generate Scoped List of Names" section caught me with bad feeling: why do you need to generate code using string mixins if this can be done in more readable way (IMHO). So I played with it a bit and here is my solution:Haha, this is a nice improvement! Nobody can think of everything, which is why these forums are worth while!
Aug 16 2022
On 8/16/22 08:07, Walter Bright wrote:Haha, this is a nice improvement! Nobody can think of everything, which is why these forums are worth while!And your array-at-compile-time example can subjectively be better like this: import std; void main() { pragma(msg, iota(20).map!(n => n * n).array); } Ali
Aug 16 2022
On 8/16/2022 8:34 AM, Ali Çehreli wrote:And your array-at-compile-time example can subjectively be better like this: import std; void main() { pragma(msg, iota(20).map!(n => n * n).array); }True, but my example was a slide-friendly version of a much more complex piece of real life code.
Aug 16 2022
On Tuesday, 16 August 2022 at 15:34:30 UTC, Ali Çehreli wrote:On 8/16/22 08:07, Walter Bright wrote: And your array-at-compile-time example can subjectively be better like this: ```d import std; void main() { pragma(msg, iota(20).map!(n => n * n).array); } ```Generates different types if not specifically specified. Because Walter initialized a static array. Although your example runs with #pragma , it creates a dynamic array: ```d import std.stdio; enum N = 10; void main() { int[N] squares_A = () { int[N] squares; foreach (i; 0 .. N) squares[i] = i * i; return squares; }(); squares_A.writeln(": ", typeid(squares_A)); import std.algorithm, std.range; //pragma(msg, iota(20).map!(n => n * n).array);/* auto squares_B = iota(N).map!(n => n * n).array; squares_B ~= 100; squares_B.writeln(": ", typeid(squares_B));//*/ /* [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]: int[10] * [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]: int[] */ } ``` Also, squares_A doesn't get any help from any modules. SDB 79
Aug 20 2022