| Thread overview |
|---|
December 24, 2014 Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
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?
| ||||
December 24, 2014 Re: Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta Attachments: | 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 & 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. | |||
December 24, 2014 Re: Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | 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:
>
>> 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.
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.
| |||
December 24, 2014 Re: Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta Attachments: | 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 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. 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... | |||
December 24, 2014 Re: Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | 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. | |||
December 24, 2014 Re: Enum template with mixin, need 'this' | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Meta | 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.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply