Am 27.01.2012, 20:01 Uhr, schrieb Era Scarecrow <rtcv...@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 -=)

Reply via email to