September 07, 2018
The following code fail to compile:

enum KeyMod : int
{
    LCtrl  = 1 << 0,
    RCtrl  = 1 << 1,
    Ctrl   = LCtrl | RCtrl,
}

struct Flags(E)
{
public:
    BitFlags!(E, Yes.unsafe) flags;
    alias flags this;

    bool opDispatch(string name)() const
    if (__traits(hasMember, E, name))
    {
        enum e = __traits(getMember, E, name);
        return (mValue & e) != 0;
    }
}

Flags!KeyMod keys;
keys.LCtrl = true;
assert(keys.Ctrl);

Error: no property LCtrl for type Flags!(KeyMod)
Error: no property Ctrl for type Flags!(KeyMod)
September 07, 2018
On Friday, 7 September 2018 at 02:22:58 UTC, Domain wrote:
> The following code fail to compile:
>
> enum KeyMod : int
> {
>     LCtrl  = 1 << 0,
>     RCtrl  = 1 << 1,
>     Ctrl   = LCtrl | RCtrl,
> }
>
> struct Flags(E)
> {
> public:
>     BitFlags!(E, Yes.unsafe) flags;
>     alias flags this;
>
>     bool opDispatch(string name)() const
>     if (__traits(hasMember, E, name))
>     {
>         enum e = __traits(getMember, E, name);
>         return (mValue & e) != 0;
>     }
> }
>
> Flags!KeyMod keys;
> keys.LCtrl = true;
> assert(keys.Ctrl);
>
> Error: no property LCtrl for type Flags!(KeyMod)
> Error: no property Ctrl for type Flags!(KeyMod)

Sorry. This works:

struct Flags(E)
{
public:
    BitFlags!(E, Yes.unsafe) flags;
    alias flags this;

    bool opDispatch(string name)() const
    if (__traits(hasMember, E, name))
    {
        enum e = __traits(getMember, E, name);
        return cast(int)(flags & e) != 0;
    }

    void opDispatch(string name)(bool set)
    if (__traits(hasMember, E, name))
    {
        enum e = __traits(getMember, E, name);
        if (set)
            flags |= e;
        else
            flags &= ~e;
    }
}