strong enums: why implicit conversion to basetype?

Marco Leise Marco.Leise at gmx.de
Sun Jan 29 13:33:02 PST 2012


Am 27.01.2012, 20:01 Uhr, schrieb Era Scarecrow <rtcvb32 at yahoo.com>:

>> >> El 26/01/2012 14:59, Trass3r escribi?:
>> >>> I thought it'd be good to outsource this
>> question from the other thread
>> >>> about enums as flags.
>> >>>
>> >>> Is there any merit in having implicit
>> conversion to the basetype?
>> >>> Imo it only introduces a severe bug source and
>> brings no advantages.
>> >>
>> > Sometimes, bitwise operations make sense, other times
>> not. Enums play two
>> > roles in D - that of an enumeration and that of a set
>> of flags. Only for
>> > the latter do bitwise operations make sense.
>>
>> You'd think that with some use of a templated struct and
>> some "alias
>> this" we'd be able to have a strongly-typed type for storing
>> sets of
>> flags.  It could even offer convenience functions like
>> "getFlag" and
>> "setFlag" to make the code read a bit nicer.
>
>  I have a personal class i am using, may submit it later to Walter to  
> add to Phobos. Comments? (I have working unittests... :) )
>
>
> ///T of type ENUM, and S of an integral.
> struct HandleFlags(T, S)
>  {
> 	S state;	///Holds state.
> 	alias T T_Enum;
>
> 	 this(T[] setFlags...);
>
> 	///Returns true/false if a specific ENUM flag has been set.
> 	bool check(T[] flag...);
>
> 	///Returns true/false if a specific ENUM flag has been set.
> 	bool checkAll(T[] flag...);
> 	
> 	/**
> 	Checks if a flag has been set, returning that ENUM, otherwise returning  
> the Else flag.
> 	*/
> 	T checkElse(T Else, T[] flag...);
>
> 	///Sets specific flag(s) on
> 	void setFlag(T[] flag...);
>
> 	///turns listed flags off.
> 	void clearFlag(T[] flag...);
>
> 	///reverses the state of a specific flag.
> 	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.
And in the same fashion: Do you map an enum value to "1 << enum_value" in  
the bit field? I know that in Delphi 'sets' worked great for me and so I  
am biased for everything that works the same way. It is also the most  
natural way to work with enums that can be represented as a bit field IMO.  
This means that enum values cannot be larger than 63 of course (so they  
fit inside a ulong).
What else… hmm… I'm wondering if the documentation for flipFlag should be  
"reverses the state of all given flags".
How is checkElse supposed to work. I could imagine the function of a  
method with the signature "T (T flag, T else)". What is the use case for  
it? Even check seems to accept multiple flags, where I would expect only  
one.
We could also introduce some operator overloading: setFlag <=> +=,  
clearFlag <=> -=, flipFlag <=> ^=, check <=> in. (setFlag could be |= as  
well, but += is more consistent with clearFlag as -=)


More information about the Digitalmars-d mailing list