#include template struct Flags { typedef E EnumType; typedef S StorageType; StorageType value; Flags() : value(0) { } Flags(EnumType T) { value = 1 << (int)T; } Flags &operator|=(Flags X) { value |= X.value; return *this; } Flags &operator&=(Flags X) { value &= X.value; return *this; } operator bool() { return value != 0; } Flags operator~() { Flags T; T.value = ~value; return T; } }; template Flags operator&(Flags A, Flags B) { Flags R; R.value = A.value & B.value; return R; } template bool operator&(Flags A, E B) { return (A.value & (1 << B)) != 0; } template bool operator==(Flags A, Flags B) { return A.value == B.value; } template typename Flags operator|(Flags A, E B) { A.value |= 1 << B; return A; } template typename Flags operator|(E A, E B) { return Flags(A) | B; } enum Enum { One, Two, Three, Four, Five }; void main() { Flags flags(Two | Three); assert(flags & Three); assert(flags & Two); assert(flags & (One | Two)); assert(flags & (One | Three)); assert(flags & (One | Two | Three)); assert(!(flags & One)); assert(!(flags == (Two | One))); assert(flags == (Two | Three)); flags = One | Five; assert(flags & One); assert(flags & Five); assert(!(flags & (Two | Three | Four))); flags = Two | Three; flags &= Two; assert(flags == Two); flags |= Four; assert(flags & Two); assert(flags & Four); //flags &= ~Two; // compile-time error. //assert(flags == Four); }