digitalmars.D.learn - Enum template with mixin, need 'this'
- Meta (65/65) Dec 24 2014 The code I currently have is as follows:
- ketmar via Digitalmars-d-learn (9/13) Dec 24 2014 i don't think that you can cheat like this. ;-)
- Meta (6/22) Dec 24 2014 Hmm, I confused myself over when the expression is interpreted. I
- ketmar via Digitalmars-d-learn (5/9) Dec 24 2014 sometimes i want to have some kind of C-like macros in D too, which
- Meta (7/7) Dec 24 2014 I am curious, however, why changing `enum` to `auto` (or bool)
- Meta (5/12) Dec 24 2014 Ok, I understand now. I missed the fact that even when it's an
The code I currently have is as follows: import std.stdio; import std.traits; import std.typecons; struct EmbeddedTest { int bits; } struct Test { //Other stuff EmbeddedTest embeddedTest; enum isSet(alias bit) = `cast(bool)(embeddedTest.bits & ` ~ bit.stringof ~ `)`; property setBits() { enum Bits = EnumMembers!Bit; Nullable!(Bit, Bit.max)[Bits.length] ret; foreach (i, bit; Bits) { if (mixin(isSet!bit)) { ret[i] = bit; } } return ret; } } enum Bit { bit1 = 0x0001, bit2 = 0x0002, bit3 = 0x0004, bit4 = 0x0008, } void main() { Test t; t.embeddedTest.bits = 0x1; foreach (bit; t.setBits) { if (!bit.isNull) { writeln(bit); } } } My problem is that I would like to not have to mixin the result of Test.isSet at each usage site, but I also want to avoid making it a function if possible. I tried to move the mixin into isSet like this: enum isSet(alias bit) = mixin(`cast(bool)(embeddedTest.bits & ` ~ bit.stringof ~ `)`); This would now break isSet for usage outside of the struct Test. However, I don't see why it wouldn't work inside of Test, since the mixin expands, for example, to: cast(bool)(embeddedTest.bits & bit1) So `if (isSet!bit1)` becomes `if (cast(bool)(embeddedTest.bits & bit1)`. That doesn't work, however. I get an error message saying "need 'this' for 'bits' of type 'int'". Is there a way to make this work, or am I stuck with the uglier mixin at the usage site?
Dec 24 2014
On Wed, 24 Dec 2014 17:05:45 +0000 Meta via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:So `if (isSet!bit1)` becomes `if (cast(bool)(embeddedTest.bits &=20 bit1)`. That doesn't work, however. I get an error message saying=20 "need 'this' for 'bits' of type 'int'". Is there a way to make=20 this work, or am I stuck with the uglier mixin at the usage site?i don't think that you can cheat like this. ;-) templates aren't macros, and `mixin` inside the template works immediately. i.e. it's trying to *execute* the mixined code in compile time. so your template with `mixin` in it tries to check `embedded.bits` in *compile* time, and then complains about missing 'this', as it should. i don't think that you can do c-like macros in D.
Dec 24 2014
On Wednesday, 24 December 2014 at 17:41:09 UTC, ketmar via Digitalmars-d-learn wrote:On Wed, 24 Dec 2014 17:05:45 +0000 Meta via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Hmm, I confused myself over when the expression is interpreted. I got it into my head that the template expansion would somehow delay interpretation of the expression so it could be picked up at runtime, but of course `enum` forces it to be CTFE'd.So `if (isSet!bit1)` becomes `if (cast(bool)(embeddedTest.bits & bit1)`. That doesn't work, however. I get an error message saying "need 'this' for 'bits' of type 'int'". Is there a way to make this work, or am I stuck with the uglier mixin at the usage site?i don't think that you can cheat like this. ;-) templates aren't macros, and `mixin` inside the template works immediately. i.e. it's trying to *execute* the mixined code in compile time. so your template with `mixin` in it tries to check `embedded.bits` in *compile* time, and then complains about missing 'this', as it should. i don't think that you can do c-like macros in D.
Dec 24 2014
On Wed, 24 Dec 2014 19:52:31 +0000 Meta via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Hmm, I confused myself over when the expression is interpreted. I=20 got it into my head that the template expansion would somehow=20 delay interpretation of the expression so it could be picked up=20 at runtime, but of course `enum` forces it to be CTFE'd.sometimes i want to have some kind of C-like macros in D too, which just inserts the generated string in the place of instantiation with implicit `mixin`. maybe someone will write a DIP/ER for this...
Dec 24 2014
I am curious, however, why changing `enum` to `auto` (or bool) doesn't work. You said that the mixin tries to interpret the expression `cast(bool)(embeddedTest.bits & <enumName>)` at compile time, but I don't understand why that would be so when the storage is auto and not enum. I guess mixin doesn't work quite like I thought it did; it's not quite the equivalent of pasting the mixed-in code.
Dec 24 2014
On Wednesday, 24 December 2014 at 20:08:07 UTC, Meta wrote:I am curious, however, why changing `enum` to `auto` (or bool) doesn't work. You said that the mixin tries to interpret the expression `cast(bool)(embeddedTest.bits & <enumName>)` at compile time, but I don't understand why that would be so when the storage is auto and not enum. I guess mixin doesn't work quite like I thought it did; it's not quite the equivalent of pasting the mixed-in code.Ok, I understand now. I missed the fact that even when it's an auto or a bool variable, it is CTFE-initialized because it's outside the constructor. I'm so close, yet so far from making this work.
Dec 24 2014