An idea (Re: Implicit enum conversions are a stupid PITA)
Regan Heath
regan at netmail.co.nz
Thu Mar 25 11:41:29 PDT 2010
Nick Sabalausky wrote:
> Here's the low-hanging fruit I see:
>
> Step 1: Remove implicit enum->base-type conversions
> Step 2: Allow '|' (and maybe '&'?) on enums, and consider the result of the
> operation be the base type.
I would prefer the result of Step 2 to be the enum type, not the base
type(*)
The typical case I see for enums as flags is passing a combination of
them to a function, where the parameter (for type-safety &
self-documentation) will probably be of the enum type.
However, it occurs to me we don't actually get full type safety unless
we also ensure the enum never has a value outside those defined, or a
combination thereof(*)
Example:
enum Flags
{
A = 0x1,
B = 0x2,
C = 0x4,
D = 0x8
}
//
// possible values for a variable of type 'Flags'
// 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA
// 0xB, 0xC, 0xD, 0xE, 0xF
//
// values < 0x1 and > 0xF are illegal
//
// default value of variable of type 'Flags' is 0x1 (A)
//
<incomplete code snippets..>
void foo(Flags f) {} //accepts only legal values for Flags
foo(Flags.A|Flags.B); //ok
foo(0x10); //error
Flags f; //ok, f = 0x1
Flags err = 0x10; //error
foo(Flags.A|0x10); //error
</incomplete code snippets..>
(*) Some operators would return the base type, take ~ for example, it
naturally produces a value outside the range of values defined by the
enum type.
It follows that operators like |[=], &[=] etc would need to accept enum
and base types as operands, otherwise some common idioms would be
illegal, eg.
Flags f = Flags.A|Flags.B|Flags.C;
f &= ~Flags.A; // remove Flags.A from 'f'
R
More information about the Digitalmars-d
mailing list