www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - with not working wtih BitFlags

reply Jot <Jot datacentralave.com> writes:
struct EnumToFlags(alias E) {
	template opDispatch(string Name) {
		enum opDispatch = 1 << __traits(getMember, E, Name);
	};
};


enum X
{
a,b,c
}

auto q = EnumtoFlags!X;


auto m = q.a;

with(q)
{
    auto m = a;
}

a undefined.

Any way to get it to work? Maybe a full blowing string mixin is 
needed to generate the flag enum?
Jan 19 2017
parent reply Dukc <ajieskola gmail.com> writes:
This is fairly complex thing, but I managed to get it working:

template EnumToFlags(E) if(is(E == enum))
{
     import std.traits, std.typecons, std.string;

     private static auto implementation()
     {
         string result;
         foreach(i, enumMem; EnumMembers!E)
         {
             result ~= format("enum %s = 1 << %s;\n", enumMem, i);
         }
         return result;
     }

     mixin(implementation);
};

enum X
{
     a,b,c
}

void main()
{
     alias q = EnumToFlags!X;

     with(q)
     {
        auto m = a;
     }
}

It may well be that with(x) only looks for x members, it probably 
does not try to look for templates. If so, opDispatch does not do 
the trick here. But the above does.
Jan 20 2017
next sibling parent Dukc <ajieskola gmail.com> writes:
On Friday, 20 January 2017 at 09:12:04 UTC, Dukc wrote:
 template EnumToFlags(E) if(is(E == enum))
 {
     import std.traits, std.typecons, std.string;

     //...
 }
I think that typecons import was needless, you could try removing it...
Jan 20 2017
prev sibling parent Jot <Jot datacentralave.com> writes:
On Friday, 20 January 2017 at 09:12:04 UTC, Dukc wrote:
 This is fairly complex thing, but I managed to get it working:

 template EnumToFlags(E) if(is(E == enum))
 {
     import std.traits, std.typecons, std.string;

     private static auto implementation()
     {
         string result;
         foreach(i, enumMem; EnumMembers!E)
         {
             result ~= format("enum %s = 1 << %s;\n", enumMem, 
 i);
         }
         return result;
     }

     mixin(implementation);
 };

 enum X
 {
     a,b,c
 }

 void main()
 {
     alias q = EnumToFlags!X;

     with(q)
     {
        auto m = a;
     }
 }

 It may well be that with(x) only looks for x members, it 
 probably does not try to look for templates. If so, opDispatch 
 does not do the trick here. But the above does.
Thanks. That is basically what I was thinking and it does work.
Jan 20 2017