#include <type_traits>
#include <iostream>


#define ENUM_FLAG(F) (1 << (F))
#define ENUM_FLAGS(F) \
    enum class Flags : unsigned; \
    inline F    operator~ (F  a)      { using U = std::underlying_type<F>::type; return (F)(~(U)a       ); } \
    inline F    operator| (F  a, F b) { using U = std::underlying_type<F>::type; return (F)( (U)a | (U)b); } \
    inline F    operator& (F  a, F b) { using U = std::underlying_type<F>::type; return (F)( (U)a & (U)b); } \
    inline F    operator^ (F  a, F b) { using U = std::underlying_type<F>::type; return (F)( (U)a ^ (U)b); } \
    inline F&   operator|=(F& a, F b) { return a = a | b; } \
    inline F&   operator&=(F& a, F b) { return a = a & b; } \
    inline F&   operator^=(F& a, F b) { return a = a ^ b; } \
    template<typename Func> \
    inline void for_enum_flags(F f, Func && func) \
    { \
        using U = std::underlying_type<F>::type; \
        auto  u = (U)f; \
        for (auto flag = U{}; (flag = u & -u); u ^= flag) \
            func((F)flag); \
    } \
    enum class Flags : unsigned
// static_assert(std::is_unsigned<std::underlying_type<F>::type>::value, "Flag enum F must be unsigned");


ENUM_FLAGS(Flags)
{
    one   = ENUM_FLAG(0),
    two   = ENUM_FLAG(1),
    three = ENUM_FLAG(2),
};


int main()
{

    auto flags = Flags{Flags::one | Flags::three};
    flags |=  Flags::two;
    flags &= ~Flags::three;
    for_enum_flags(flags, [](Flags flag) {
        switch (flag)
        {
            #define FLAG_PRINT(FLAG) case Flags::FLAG: std::cout << #FLAG << std::endl; break;
            FLAG_PRINT(one)
            FLAG_PRINT(two)
            FLAG_PRINT(three)
            #undef FLAG_PRINT
            default: std::cout << "UNKNOWN" << std::endl;
        }
    });
}