| 1 | ## Flag Enums ##
 | 
|---|
| 2 | 
 | 
|---|
| 3 | A common programming problem is to represent a value from a set of boolean flags, each of which can be either on or off. C already has enums and bitfields, which can be naturally used to represent the individual flags, but are un-ergonomic to combine together. This proposal introduces "flag enums", a variant of the usual enums specialized to represent flags in a more ergonomic way.
 | 
|---|
| 4 | 
 | 
|---|
| 5 | As an example, a flag enum for the TCP control bits could be defined as follows:
 | 
|---|
| 6 | 
 | 
|---|
| 7 |         ```
 | 
|---|
| 8 |         enum TCP_Flags {
 | 
|---|
| 9 |                 FIN,
 | 
|---|
| 10 |                 SYN,
 | 
|---|
| 11 |                 RST,
 | 
|---|
| 12 |                 PSH,
 | 
|---|
| 13 |                 ACK,
 | 
|---|
| 14 |                 URG,
 | 
|---|
| 15 |                 ECE,
 | 
|---|
| 16 |                 CWR,
 | 
|---|
| 17 |                 NS
 | 
|---|
| 18 |         } __attribute__((flag));
 | 
|---|
| 19 |         ```
 | 
|---|
| 20 | 
 | 
|---|
| 21 | The `__attribute__` syntax is ugly, but represents the smallest backwards compatibility break; a new SUE for enum flags (e.g. `flag enum TCP_Flags { ... };` or even `flag TCP_Flags { ... };`) might also be reasonable.
 | 
|---|
| 22 | 
 | 
|---|
| 23 | A flag enum would be different than a normal enum in two ways: it would auto-generate discriminant values differently, and it would have a number of bitwise operators defined on it by default.
 | 
|---|
| 24 | 
 | 
|---|
| 25 | Normal enums generate their discriminant values sequentially starting at zero (`0, 1, 2, 3, ...`), while a flag enum would generate its discriminant values as successive powers of two starting at `1`. E.g. the `TCP_Flags` declaration above would codegen to an enum like below:
 | 
|---|
| 26 | 
 | 
|---|
| 27 |         ```
 | 
|---|
| 28 |         enum TCP_Flags {
 | 
|---|
| 29 |                 FIN = 0x1,
 | 
|---|
| 30 |                 SYN = 0x2,
 | 
|---|
| 31 |                 RST = 0x4,
 | 
|---|
| 32 |                 PSH = 0x8,
 | 
|---|
| 33 |                 ACK = 0x10,
 | 
|---|
| 34 |                 URG = 0x20,
 | 
|---|
| 35 |                 ECE = 0x40,
 | 
|---|
| 36 |                 CWR = 0x80,
 | 
|---|
| 37 |                 NS = 0x100
 | 
|---|
| 38 |         };
 | 
|---|
| 39 |         ```
 | 
|---|
| 40 | 
 | 
|---|
| 41 | The precise rule used would be that if no enum discriminant is given, the discriminant is the smallest power of two larger than the previous discriminant (`1` if there is no previous discriminant). This would allow some flexibility for cases like these:
 | 
|---|
| 42 | 
 | 
|---|
| 43 |         ```
 | 
|---|
| 44 |         enum FunFlags {
 | 
|---|
| 45 |                 NONE = 0,           // Named empty value
 | 
|---|
| 46 |                 FOO,  // == 0x1
 | 
|---|
| 47 |                 BAZ = 0x6,          // Multi-bit flag: 0x4 | 0x2
 | 
|---|
| 48 |                 BAR,  // == 0x8
 | 
|---|
| 49 |                 FOOBAR = FOO | BAR  // Named combination flag
 | 
|---|
| 50 |         } __attribute__((flag));
 | 
|---|
| 51 |         ```
 | 
|---|
| 52 | 
 | 
|---|
| 53 | Secondly, we would auto-generate a number of useful operators for any flag enum, as follows:
 | 
|---|
| 54 | * The default constructor for any flag enum would be defined, and would produce a flag with an underlying value of 0.
 | 
|---|
| 55 | * Assignment from and equality/inequality to `zero_t` should also be defined based on the underlying enum value.
 | 
|---|
| 56 | * The bitwise operators `?&?, ?|?, ?^?, ~?` and their assignment variants `?&=?, ?|=?, ?^=?` shall be defined with the semantics of the underlying enum value; `?-?` and `?-=?` should also be defined such that `a - b == a & ~b` (a set difference operation).
 | 
|---|
| 57 | 
 | 
|---|
| 58 | With these operations defined, flag enums would support a full set of useful flag operations, using existing, known syntax, as follows:
 | 
|---|
| 59 | 
 | 
|---|
| 60 |         ```
 | 
|---|
| 61 |         FunFlags f = some_val();
 | 
|---|
| 62 |         if ( f ) { sout | "f has some flag(s) set" | endl; }
 | 
|---|
| 63 |         if ( f & FOO ) { sout | "f has FOO set" | endl; }
 | 
|---|
| 64 |         f |= FOO; // set FOO
 | 
|---|
| 65 |         f -= FOO; // unset FOO
 | 
|---|
| 66 |         f ^= FOO; // toggle FOO
 | 
|---|
| 67 |         ```
 | 
|---|
| 68 | 
 | 
|---|
| 69 | In each of the cases above, `FOO` could be replaced by `(BAR | BAZ)` to do the same operation or test on multiple flags at once.
 | 
|---|
| 70 | 
 | 
|---|
| 71 | ### Alternative/Additional Features ###
 | 
|---|
| 72 | 
 | 
|---|
| 73 | #### User-defined enum discriminant iterator ####
 | 
|---|
| 74 | It may be useful to provide a more general method for changing the enum discriminant assignment function, e.g. the flag enum discriminants could be defined by something like the following:
 | 
|---|
| 75 | 
 | 
|---|
| 76 |         ```
 | 
|---|
| 77 |         enum(@ << 1) TCP_Flags {  // each discriminant is left-shifted by 1 from the previous
 | 
|---|
| 78 |                 FIN = 0x1,  // first flag is 1
 | 
|---|
| 79 |                 SYN,
 | 
|---|
| 80 |                 ACK,
 | 
|---|
| 81 |                 ...
 | 
|---|
| 82 |         }
 | 
|---|
| 83 |         ```
 | 
|---|
| 84 | 
 | 
|---|
| 85 | #### Member expression for enums ####
 | 
|---|
| 86 | As a more ergonomic way to set and unset enum flags, we could define a member expression for flags enums. Since only unions and structs can have member expressions now, this change would be backwards compatible. Basically, given a `FunFlags f`, `f.FOO` would return a proxy object which could be implicitly converted to `bool` (with semantics `f & FOO`, i.e. "check if `FOO` is set on `f`"), as well as having `bool` assigned to it (with semantics `f |= FOO` on true or `f -= FOO` on false, i.e. "set or unset `FOO` on `f` as appropriate"). With this member function, the operations above can be expressed as follows (possibly more ergonomically):
 | 
|---|
| 87 | 
 | 
|---|
| 88 |         ```
 | 
|---|
| 89 |         FunFlags f = some_val();
 | 
|---|
| 90 |         if ( f.FOO ) { sout | "f has FOO set" | endl; }
 | 
|---|
| 91 |         f.FOO = true;    // set FOO
 | 
|---|
| 92 |         f.FOO = false;   // unset FOO
 | 
|---|
| 93 |         f.FOO = ! f.FOO; // toggle FOO
 | 
|---|
| 94 |         ```
 | 
|---|
| 95 | 
 | 
|---|
| 96 | ### Related Work ###
 | 
|---|
| 97 | C# has the [`[Flags]`][1] enum attribute, but their proposal does not go as far; specifically, the flag discriminants must be manually specified, and they do not automatically implement the bitwise operators on the flags. 
 | 
|---|
| 98 | 
 | 
|---|
| 99 | Java has [`EnumSet`][2] which represents the set of flags for a given enum (C++ [`bitset`][3] can be used similarly). The main disadvantage of applying this approach to Cforall is that C enum types already implicitly convert to int, and the bitwise operators already have interpretations on enums with `int` results based on this conversion. As such, all flags need to be wrapped in a set to be used type-safely with the bitwise operators.
 | 
|---|
| 100 | 
 | 
|---|
| 101 | [1]: https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
 | 
|---|
| 102 | [2]: http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html
 | 
|---|
| 103 | [3]: http://en.cppreference.com/w/cpp/utility/bitset
 | 
|---|