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?

Reply via email to