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









ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> 