/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkEnumBitMask_DEFINED #define SkEnumBitMask_DEFINED #include "include/private/base/SkAttributes.h" /** * Wraps an enum that is used for flags, and enables masking with type safety. Example: * * enum class MyFlags { * kNone = 0, * kA = 1, * kB = 2, * kC = 4, * }; * * SK_MAKE_BITMASK_OPS(MyFlags) * * ... * * SkEnumBitMask flags = MyFlags::kA | MyFlags::kB; * * if (flags & MyFlags::kB) {} * * ... */ template class SkEnumBitMask { public: SK_ALWAYS_INLINE constexpr SkEnumBitMask(E e) : SkEnumBitMask((int)e) {} SK_ALWAYS_INLINE constexpr explicit operator bool() const { return fValue; } SK_ALWAYS_INLINE constexpr int value() const { return fValue; } SK_ALWAYS_INLINE constexpr bool operator==(SkEnumBitMask m) const { return fValue == m.fValue; } SK_ALWAYS_INLINE constexpr bool operator!=(SkEnumBitMask m) const { return fValue != m.fValue; } SK_ALWAYS_INLINE constexpr SkEnumBitMask operator|(SkEnumBitMask m) const { return SkEnumBitMask(fValue | m.fValue); } SK_ALWAYS_INLINE constexpr SkEnumBitMask operator&(SkEnumBitMask m) const { return SkEnumBitMask(fValue & m.fValue); } SK_ALWAYS_INLINE constexpr SkEnumBitMask operator^(SkEnumBitMask m) const { return SkEnumBitMask(fValue ^ m.fValue); } SK_ALWAYS_INLINE constexpr SkEnumBitMask operator~() const { return SkEnumBitMask(~fValue); } SK_ALWAYS_INLINE SkEnumBitMask& operator|=(SkEnumBitMask m) { return *this = *this | m; } SK_ALWAYS_INLINE SkEnumBitMask& operator&=(SkEnumBitMask m) { return *this = *this & m; } SK_ALWAYS_INLINE SkEnumBitMask& operator^=(SkEnumBitMask m) { return *this = *this ^ m; } private: SK_ALWAYS_INLINE constexpr explicit SkEnumBitMask(int value) : fValue(value) {} int fValue; }; /** * Defines functions that make it possible to use bitwise operators on an enum. */ #define SK_MAKE_BITMASK_OPS(E) \ [[maybe_unused]] constexpr SkEnumBitMask operator|(E a, E b) { \ return SkEnumBitMask(a) | b; \ } \ [[maybe_unused]] constexpr SkEnumBitMask operator&(E a, E b) { \ return SkEnumBitMask(a) & b; \ } \ [[maybe_unused]] constexpr SkEnumBitMask operator^(E a, E b) { \ return SkEnumBitMask(a) ^ b; \ } \ [[maybe_unused]] constexpr SkEnumBitMask operator~(E e) { \ return ~SkEnumBitMask(e); \ } #define SK_DECL_BITMASK_OPS_FRIENDS(E) \ friend constexpr SkEnumBitMask operator|(E, E); \ friend constexpr SkEnumBitMask operator&(E, E); \ friend constexpr SkEnumBitMask operator^(E, E); \ friend constexpr SkEnumBitMask operator~(E); #endif // SkEnumBitMask_DEFINED