Index: doc/proposals/flags.md
===================================================================
--- doc/proposals/flags.md	(revision 6152c819869ff813b9700aee132f2e96745b4d7c)
+++ doc/proposals/flags.md	(revision 6152c819869ff813b9700aee132f2e96745b4d7c)
@@ -0,0 +1,78 @@
+## Flag Enums ##
+
+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.
+
+As an example, a flag enum for the TCP control bits could be defined as follows:
+
+	```
+	enum TCP_Flags {
+		FIN,
+		SYN,
+		RST,
+		PSH,
+		ACK,
+		URG,
+		ECE,
+		CWR,
+		NS
+	} __attribute__((flag));
+	```
+
+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.
+
+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.
+
+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:
+
+	```
+	enum TCP_Flags {
+		FIN = 0x1,
+		SYN = 0x2,
+		RST = 0x4,
+		PSH = 0x8,
+		ACK = 0x10,
+		URG = 0x20,
+		ECE = 0x40,
+		CWR = 0x80,
+		NS = 0x100
+	};
+	```
+
+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:
+
+	```
+	enum FunFlags {
+		NONE = 0,           // Named empty value
+		FOO,  // == 0x1
+		BAZ = 0x6,          // Multi-bit flag: 0x4 | 0x2
+		BAR,  // == 0x8
+		FOOBAR = FOO | BAR  // Named combination flag
+	} __attribute__((flag));
+	```
+
+Secondly, we would auto-generate a number of useful operators for any flag enum, as follows:
+* The default constructor for any flag enum would be defined, and would produce a flag with an underlying value of 0.
+* Assignment from and equality/inequality to `zero_t` should also be defined based on the underlying enum value.
+* 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).
+
+With these operations defined, flag enums would support a full set of useful flag operations, using existing, known syntax, as follows:
+
+	```
+	FunFlags f = some_val();
+	if ( f ) { sout | "f has some flag(s) set" | endl; }
+	if ( f & FOO ) { sout | "f has FOO set" | endl; }
+	f |= FOO; // set FOO
+	f -= FOO; // unset FOO
+	f ^= FOO; // toggle FOO
+	```
+
+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.
+
+### Related Work ###
+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. 
+
+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.
+
+[1]: https://msdn.microsoft.com/en-us/library/system.enum.hasflag(v=vs.110).aspx
+[2]: http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html
+[3]: http://en.cppreference.com/w/cpp/utility/bitset
