1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkEnumBitMask_DEFINED 9 #define SkEnumBitMask_DEFINED 10 11 #include "include/core/SkTypes.h" 12 13 /** 14 * Wraps an enum that is used for flags, and enables masking with type safety. Example: 15 * 16 * enum class MyFlags { 17 * kNone = 0, 18 * kA = 1, 19 * kB = 2, 20 * kC = 4, 21 * }; 22 * 23 * MAKE_MASK_OPS(MyFlags) 24 * 25 * ... 26 * 27 * Mask<MyFlags> flags = MyFlags::kA | MyFlags::kB; 28 * 29 * if (flags & MyFlags::kB) {} 30 * 31 * ... 32 */ 33 template<typename E> 34 class SkEnumBitMask { 35 public: SkEnumBitMask(E e)36 SK_ALWAYS_INLINE constexpr SkEnumBitMask(E e) : SkEnumBitMask((int)e) {} 37 38 SK_ALWAYS_INLINE constexpr operator bool() const { return fValue; } 39 40 SK_ALWAYS_INLINE bool operator==(SkEnumBitMask m) const { return fValue == m.fValue; } 41 SK_ALWAYS_INLINE bool operator!=(SkEnumBitMask m) const { return fValue != m.fValue; } 42 43 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator|(SkEnumBitMask m) const { 44 return SkEnumBitMask(fValue | m.fValue); 45 } 46 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator&(SkEnumBitMask m) const { 47 return SkEnumBitMask(fValue & m.fValue); 48 } 49 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator^(SkEnumBitMask m) const { 50 return SkEnumBitMask(fValue ^ m.fValue); 51 } 52 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator~() const { return SkEnumBitMask(~fValue); } 53 54 SK_ALWAYS_INLINE SkEnumBitMask& operator|=(SkEnumBitMask m) { return *this = *this | m; } 55 SK_ALWAYS_INLINE SkEnumBitMask& operator&=(SkEnumBitMask m) { return *this = *this & m; } 56 SK_ALWAYS_INLINE SkEnumBitMask& operator^=(SkEnumBitMask m) { return *this = *this ^ m; } 57 58 private: SkEnumBitMask(int value)59 SK_ALWAYS_INLINE constexpr explicit SkEnumBitMask(int value) : fValue(value) {} 60 61 int fValue; 62 }; 63 64 /** 65 * Defines functions that make it possible to use bitwise operators on an enum. 66 */ 67 #define SK_MAKE_BITMASK_OPS(E) \ 68 [[maybe_unused]] constexpr SkEnumBitMask<E> operator|(E a, E b) { \ 69 return SkEnumBitMask<E>(a) | b; \ 70 } \ 71 [[maybe_unused]] constexpr SkEnumBitMask<E> operator&(E a, E b) { \ 72 return SkEnumBitMask<E>(a) & b; \ 73 } \ 74 [[maybe_unused]] constexpr SkEnumBitMask<E> operator^(E a, E b) { \ 75 return SkEnumBitMask<E>(a) ^ b; \ 76 } \ 77 [[maybe_unused]] constexpr SkEnumBitMask<E> operator~(E e) { \ 78 return ~SkEnumBitMask<E>(e); \ 79 } \ 80 81 #define SK_DECL_BITMASK_OPS_FRIENDS(E) \ 82 friend constexpr SkEnumBitMask<E> operator|(E, E); \ 83 friend constexpr SkEnumBitMask<E> operator&(E, E); \ 84 friend constexpr SkEnumBitMask<E> operator^(E, E); \ 85 friend constexpr SkEnumBitMask<E> operator~(E); \ 86 87 #endif // SkEnumBitMask_DEFINED 88