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