www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: strong enums: why implicit conversion to basetype?

 ///T of type ENUM, and S of an integral.
 struct HandleFlags(T, S)
=A0 {
 =A0=A0=A0 S state;=A0=A0=A0 ///Holds

 =A0=A0=A0 alias T T_Enum;

 =A0=A0=A0=A0=A0this(T[] setFlags...);

 =A0=A0=A0 ///Returns true/false if a specific

 =A0=A0=A0 bool check(T[] flag...);

 =A0=A0=A0 ///Returns true/false if all flags are set

 =A0=A0=A0 bool checkAll(T[] flag...);
 =A0=A0=A0 /**
 =A0=A0=A0 Checks if a flag has been set,

 the Else flag.
 =A0=A0=A0 */
 =A0=A0=A0 T checkElse(T Else, T[] flag...);

 =A0=A0=A0 ///Sets specific flag(s) on
 =A0=A0=A0 void setFlag(T[] flag...);

 =A0=A0=A0 ///turns listed flags off.
 =A0=A0=A0 void clearFlag(T[] flag...);

 =A0=A0=A0 ///reverses the state of a specific

 =A0=A0=A0 void flipFlag(T[] flag...);

Is it possible to 'auto-detect' the integral type? I makes little sense to use a signed type or a type too small for the enum for example.

Yes, I suppose it could auto detect it, however having it the smallest size= possible isn't the right answer. If you begin using enums for your flags a= nd you are accessing C code that uses it's enums, it may only use 10 bits b= ut uses a 32bit value. Hopefully by having only one data member (of your in= t type) you can safely forcibly cast it (If it's the same size)
 And in the same fashion: Do you map an enum value to "1 << enum_value" in=

am biased for everything that works the same way. It is also the most=A0 n= atural way to work with enums that can be represented as a bit field IMO.= =A0=20 Current implementation you are explicit (ie 0x1000); Wouldn't be hard to u= se a mixin function to do the work for you.
 This means that enum values cannot be larger than 63 of course (so they f=

 What else? hmm? I'm wondering if the documentation for flipFlag should be=

Correct. So if flag A was set and B wasn't, and you flip both, B is set an= d A isn't. I'm using variadic functions since if you know you are doing mul= tiple flags you shouldn't be required to make x calls when you don't need t= o.
 How is checkElse supposed to work. I could imagine the function of a =20
 method with the signature "T (T flag, T else)". What is the use case for =

e. I've updated the signature to use "const T checkElse(T Else, T flag...)". N= ow how you would use this is if you want an ENUM flag returned and not a tr= ue/false, but you don't want to have to manually check. so you can do this.= (Returns first true ENUM, or if it fails return Else) HandleFlags!(E, int) Flags; somefunc(Flags.checkElse(ETEST.unused, ETEST.isMaster, ETEST.isSlave), ...) Rather than.. if (Flags.check(TEST.isMaster)) somefunc(ETEST.isMaster, ...) else if (Flags.check(TEST.isSlave)) somefunc(ETEST.isSlave, ...) else somefunc(ETEST.unused, ...)
 We could also introduce some operator overloading: setFlag
 <=3D> +=3D,=A0=20
 clearFlag <=3D> -=3D, flipFlag <=3D> ^=3D, check
 <=3D> in. (setFlag could be |=3D as=A0=20
 well, but +=3D is more consistent with clearFlag as -=3D)

Yep, overloading would be useful later :) But not just yet.
Jan 29 2012