Branch data Line data Source code
1 : : /* 2 : : ** Copyright (C) 2022 CERN 3 : : ** 4 : : ** This software is provided 'as-is', without any express or implied 5 : : ** warranty. In no event will the authors be held liable for any damages 6 : : ** arising from the use of this software. 7 : : ** 8 : : ** Permission is granted to anyone to use this software for any purpose, 9 : : ** including commercial applications, and to alter it and redistribute it 10 : : ** freely, subject to the following restrictions: 11 : : ** 12 : : ** 1. The origin of this software must not be misrepresented; you must not 13 : : ** claim that you wrote the original software. If you use this software 14 : : ** in a product, an acknowledgment in the product documentation would be 15 : : ** appreciated but is not required. 16 : : ** 2. Altered source versions must be plainly marked as such, and must not be 17 : : ** misrepresented as being the original software. 18 : : ** 3. This notice may not be removed or altered from any source distribution. 19 : : ** 20 : : ** Created on: 2022-09-27T09:14:20 21 : : ** Author: Sylvain Fargier <sylvain.fargier@cern.ch> 22 : : */ 23 : : 24 : : #ifndef ENUM_HPP__ 25 : : #define ENUM_HPP__ 26 : : 27 : : #include <type_traits> 28 : : #include <utility> 29 : : 30 : : #include <logger/Logger.hpp> 31 : : 32 : : /** 33 : : * @brief type_traits to enable bitmask on enum types 34 : : */ 35 : : template<typename T> 36 : : struct ccut_enable_bitmask : std::false_type 37 : : {}; 38 : : 39 : : namespace ccut { 40 : : 41 : : /** 42 : : * @brief BitMask type for enums 43 : : * @details to enable BitMask support on an `Enum` type, do add the following 44 : : * declaration: 45 : : * ```template<> struct ccut_enable_bitmask<Enum> : std::true_type {};``` 46 : : */ 47 : : template<typename T> 48 : : class BitMask 49 : : { 50 : : public: 51 : : using underlying_type = typename std::underlying_type<T>::type; 52 : : 53 : : constexpr BitMask() noexcept : m_bits{0} {} 54 : 8 : explicit constexpr BitMask(underlying_type value) noexcept : m_bits{value} 55 : 8 : {} 56 : : 57 : : // cppcheck-suppress noExplicitConstructor 58 : 10 : constexpr BitMask(const T &bit) noexcept : 59 : 10 : m_bits{static_cast<underlying_type>(bit)} 60 : : { 61 : : static_assert(ccut_enable_bitmask<T>::value, "BitMask not enabled"); 62 : 10 : } 63 : : 64 : 28 : constexpr underlying_type bits() const noexcept { return m_bits; } 65 : 5 : constexpr operator bool() const noexcept { return bits() ? true : false; } 66 : : 67 : 4 : constexpr BitMask<T> operator&(const T &bit) const noexcept 68 : : { 69 : 4 : return BitMask(m_bits & static_cast<underlying_type>(bit)); 70 : : } 71 : : 72 : 3 : constexpr BitMask<T> operator|(const T &bit) const noexcept 73 : : { 74 : 3 : return BitMask(m_bits | static_cast<underlying_type>(bit)); 75 : : } 76 : : 77 : 1 : BitMask<T> &operator&=(const T &bit) noexcept 78 : : { 79 : 1 : m_bits &= static_cast<underlying_type>(bit); 80 : 1 : return *this; 81 : : } 82 : : 83 : 1 : BitMask<T> &operator|=(const T &bit) noexcept 84 : : { 85 : 1 : m_bits |= static_cast<underlying_type>(bit); 86 : 1 : return *this; 87 : : } 88 : : 89 : : constexpr BitMask<T> operator&(const BitMask<T> &mask) const noexcept 90 : : { 91 : : return BitMask(m_bits & mask.bits()); 92 : : } 93 : : 94 : : constexpr BitMask<T> operator|(const BitMask<T> &mask) const noexcept 95 : : { 96 : : return BitMask(m_bits | mask.bits()); 97 : : } 98 : : 99 : : BitMask<T> &operator&=(const BitMask<T> &mask) noexcept 100 : : { 101 : : m_bits &= mask.bits(); 102 : : return *this; 103 : : } 104 : : 105 : : BitMask<T> &operator|=(const BitMask<T> &mask) noexcept 106 : : { 107 : : m_bits |= mask.bits(); 108 : : return *this; 109 : : } 110 : : 111 : 4 : constexpr bool operator==(const BitMask<T> &mask) const noexcept 112 : : { 113 : 4 : return m_bits == mask.bits(); 114 : : } 115 : : 116 : 1 : constexpr bool operator!=(const BitMask<T> &mask) const noexcept 117 : : { 118 : 1 : return m_bits != mask.bits(); 119 : : } 120 : : 121 : : protected: 122 : : underlying_type m_bits; 123 : : }; 124 : : 125 : : /** 126 : : * @brief logger operator for BitMask<T> 127 : : * 128 : : * @param mask the mask to display 129 : : * @details this logging operator requires enum value to have their own logging 130 : : * operator. 131 : : */ 132 : : template<typename T> 133 : : typename std::enable_if<ccut_enable_bitmask<T>::value, const logger::Logger &>::type 134 : : operator<<(const logger::Logger &logger, const ccut::BitMask<T> &mask); 135 : : 136 : : } // namespace ccut 137 : : 138 : : /** 139 : : * @brief operator to transform enum to bitmask 140 : : * 141 : : * @tparam T enum type 142 : : * @param v1 enum value1 143 : : * @param v2 enum value2 144 : : * @return ccut::BitMask<T> 145 : : */ 146 : : template<typename T> 147 : : typename std::enable_if<ccut_enable_bitmask<T>::value, ccut::BitMask<T>>::type 148 : : operator|(const T &v1, const T &v2); 149 : : 150 : : /** 151 : : * @brief operator to transform enum to bitmask 152 : : * 153 : : * @tparam T enum type 154 : : * @param v1 enum value1 155 : : * @param v2 enum value2 156 : : * @return ccut::BitMask<T> 157 : : */ 158 : : template<typename T> 159 : : typename std::enable_if<ccut_enable_bitmask<T>::value, ccut::BitMask<T>>::type 160 : : operator&(const T &v1, const T &v2); 161 : : 162 : : #include "BitMask.hxx" 163 : : 164 : : #endif