1 /** 2 * @file enum_flags.h 3 * Operators for working with bit-flag enumerators. 4 * 5 * @author Matthew Woehlke (but mostly "borrowed" from Qt) 6 * @license GPL v2+ 7 */ 8 9 #ifndef ENUM_FLAGS_H_INCLUDED 10 #define ENUM_FLAGS_H_INCLUDED 11 12 #include <type_traits> 13 14 #if __GNUC__ == 4 && !defined (__clang__) 15 #pragma GCC diagnostic push 16 #if __GNUC_MINOR__ < 9 || __GNUC_PATCHLEVEL__ < 2 17 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59624 18 #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" 19 #endif 20 #endif 21 22 #define UNC_DECLARE_FLAGS(flag_type, enum_type) \ 23 using flag_type = ::uncrustify::flags<enum_type> 24 25 #define UNC_DECLARE_OPERATORS_FOR_FLAGS(flag_type) \ 26 inline flag_type operator&(flag_type::enum_t f1, flag_type::enum_t f2) \ 27 { return(flag_type{ f1 } & f2); } \ 28 inline flag_type operator|(flag_type::enum_t f1, flag_type::enum_t f2) \ 29 { return(flag_type{ f1 } | f2); } \ 30 inline flag_type operator|(flag_type::enum_t f1, flag_type f2) \ 31 { return(f2 | f1); } \ 32 inline void operator|(flag_type::enum_t f1, int f2) = delete 33 34 namespace uncrustify 35 { 36 37 //----------------------------------------------------------------------------- 38 template<typename Enum> 39 class flags 40 { 41 public: 42 using enum_t = Enum; 43 using int_t = typename std::underlying_type<enum_t>::type; 44 45 template<typename T> using integral = 46 typename std::enable_if<std::is_integral<T>::value, bool>::type; 47 48 inline flags() = default; flags(Enum flag)49 inline flags(Enum flag) 50 : m_i{static_cast<int_t>(flag)} 51 {} 52 53 inline bool operator==(Enum const &other) 54 { return(m_i == static_cast<int_t>(other)); } 55 inline bool operator==(flags const &other) 56 { return(m_i == other.m_i); } 57 inline bool operator!=(Enum const &other) 58 { return(m_i != static_cast<int_t>(other)); } 59 inline bool operator!=(flags const &other) 60 { return(m_i != other.m_i); } 61 62 template<typename T, integral<T> = true> 63 inline flags &operator&=(T mask) 64 { m_i &= static_cast<int_t>(mask); return(*this); } 65 66 inline flags &operator|=(flags f) 67 { m_i |= f.m_i; return(*this); } 68 inline flags &operator|=(Enum f) 69 { m_i |= f; return(*this); } 70 71 inline flags &operator^=(flags f) 72 { m_i ^= f.m_i; return(*this); } 73 inline flags &operator^=(Enum f) 74 { m_i ^= f; return(*this); } 75 int_t()76 inline operator int_t() const { return(m_i); } enum_t()77 inline operator enum_t() const { return(static_cast<enum_t>(m_i)); } 78 79 inline flags operator&(Enum f) const 80 { flags g; g.m_i = m_i & static_cast<int_t>(f); return(g); } 81 inline flags operator&(flags f) const 82 { flags g; g.m_i = m_i & static_cast<int_t>(f); return(g); } 83 84 template<typename T, integral<T> = true> 85 inline flags operator&(T mask) const 86 { flags g; g.m_i = m_i & static_cast<int_t>(mask); return(g); } 87 88 inline flags operator|(flags f) const 89 { flags g; g.m_i = m_i | f.m_i; return(g); } 90 inline flags operator|(Enum f) const 91 { flags g; g.m_i = m_i | static_cast<int_t>(f); return(g); } 92 93 inline flags operator^(flags f) const 94 { flags g; g.m_i = m_i ^ f.m_i; return(g); } 95 inline flags operator^(Enum f) const 96 { flags g; g.m_i = m_i ^ static_cast<int_t>(f); return(g); } 97 98 inline int_t operator~() const 99 { return(~m_i); } 100 101 inline operator bool() const { return(!!m_i); } 102 inline bool operator!() const { return(!m_i); } 103 test(flags f)104 inline bool test(flags f) const { return((*this & f) == f); } test(Enum f)105 inline bool test(Enum f) const { return((*this & f) == f); } 106 test_any()107 inline bool test_any() const { return(m_i != 0); } test_any(flags f)108 inline bool test_any(flags f) const { return((*this & f).test_any()); } 109 110 protected: 111 int_t m_i = 0; 112 }; 113 114 } // namespace uncrustify 115 116 #if __GNUC__ == 4 && !defined (__clang__) 117 #pragma GCC diagnostic pop 118 #endif 119 120 #endif 121