/** * @file enum_flags.h * Operators for working with bit-flag enumerators. * * @author Matthew Woehlke (but mostly "borrowed" from Qt) * @license GPL v2+ */ #ifndef ENUM_FLAGS_H_INCLUDED #define ENUM_FLAGS_H_INCLUDED #include #if __GNUC__ == 4 && !defined (__clang__) #pragma GCC diagnostic push #if __GNUC_MINOR__ < 9 || __GNUC_PATCHLEVEL__ < 2 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59624 #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" #endif #endif #define UNC_DECLARE_FLAGS(flag_type, enum_type) \ using flag_type = ::uncrustify::flags #define UNC_DECLARE_OPERATORS_FOR_FLAGS(flag_type) \ inline flag_type operator&(flag_type::enum_t f1, flag_type::enum_t f2) \ { return(flag_type{ f1 } & f2); } \ inline flag_type operator|(flag_type::enum_t f1, flag_type::enum_t f2) \ { return(flag_type{ f1 } | f2); } \ inline flag_type operator|(flag_type::enum_t f1, flag_type f2) \ { return(f2 | f1); } \ inline void operator|(flag_type::enum_t f1, int f2) = delete namespace uncrustify { //----------------------------------------------------------------------------- template class flags { public: using enum_t = Enum; using int_t = typename std::underlying_type::type; template using integral = typename std::enable_if::value, bool>::type; inline flags() = default; inline flags(Enum flag) : m_i{static_cast(flag)} {} inline bool operator==(Enum const &other) { return(m_i == static_cast(other)); } inline bool operator==(flags const &other) { return(m_i == other.m_i); } inline bool operator!=(Enum const &other) { return(m_i != static_cast(other)); } inline bool operator!=(flags const &other) { return(m_i != other.m_i); } template = true> inline flags &operator&=(T mask) { m_i &= static_cast(mask); return(*this); } inline flags &operator|=(flags f) { m_i |= f.m_i; return(*this); } inline flags &operator|=(Enum f) { m_i |= f; return(*this); } inline flags &operator^=(flags f) { m_i ^= f.m_i; return(*this); } inline flags &operator^=(Enum f) { m_i ^= f; return(*this); } inline operator int_t() const { return(m_i); } inline operator enum_t() const { return(static_cast(m_i)); } inline flags operator&(Enum f) const { flags g; g.m_i = m_i & static_cast(f); return(g); } inline flags operator&(flags f) const { flags g; g.m_i = m_i & static_cast(f); return(g); } template = true> inline flags operator&(T mask) const { flags g; g.m_i = m_i & static_cast(mask); return(g); } inline flags operator|(flags f) const { flags g; g.m_i = m_i | f.m_i; return(g); } inline flags operator|(Enum f) const { flags g; g.m_i = m_i | static_cast(f); return(g); } inline flags operator^(flags f) const { flags g; g.m_i = m_i ^ f.m_i; return(g); } inline flags operator^(Enum f) const { flags g; g.m_i = m_i ^ static_cast(f); return(g); } inline int_t operator~() const { return(~m_i); } inline operator bool() const { return(!!m_i); } inline bool operator!() const { return(!m_i); } inline bool test(flags f) const { return((*this & f) == f); } inline bool test(Enum f) const { return((*this & f) == f); } inline bool test_any() const { return(m_i != 0); } inline bool test_any(flags f) const { return((*this & f).test_any()); } protected: int_t m_i = 0; }; } // namespace uncrustify #if __GNUC__ == 4 && !defined (__clang__) #pragma GCC diagnostic pop #endif #endif