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/private/base/SkAttributes.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 * SK_MAKE_BITMASK_OPS(MyFlags) 24 * 25 * ... 26 * 27 * SkEnumBitMask<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 explicit operator bool() const { return fValue; } value()39 SK_ALWAYS_INLINE constexpr int value() const { return fValue; } 40 41 SK_ALWAYS_INLINE constexpr bool operator==(SkEnumBitMask m) const { return fValue == m.fValue; } 42 SK_ALWAYS_INLINE constexpr bool operator!=(SkEnumBitMask m) const { return fValue != m.fValue; } 43 44 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator|(SkEnumBitMask m) const { 45 return SkEnumBitMask(fValue | m.fValue); 46 } 47 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator&(SkEnumBitMask m) const { 48 return SkEnumBitMask(fValue & m.fValue); 49 } 50 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator^(SkEnumBitMask m) const { 51 return SkEnumBitMask(fValue ^ m.fValue); 52 } 53 SK_ALWAYS_INLINE constexpr SkEnumBitMask operator~() const { return SkEnumBitMask(~fValue); } 54 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 SK_ALWAYS_INLINE SkEnumBitMask& operator^=(SkEnumBitMask m) { return *this = *this ^ m; } 58 59 private: SkEnumBitMask(int value)60 SK_ALWAYS_INLINE constexpr explicit SkEnumBitMask(int value) : fValue(value) {} 61 62 int fValue; 63 }; 64 65 /** 66 * Defines functions that make it possible to use bitwise operators on an enum. 67 */ 68 #define SK_MAKE_BITMASK_OPS(E) \ 69 [[maybe_unused]] constexpr SkEnumBitMask<E> operator|(E a, E b) { \ 70 return SkEnumBitMask<E>(a) | b; \ 71 } \ 72 [[maybe_unused]] constexpr SkEnumBitMask<E> operator&(E a, E b) { \ 73 return SkEnumBitMask<E>(a) & b; \ 74 } \ 75 [[maybe_unused]] constexpr SkEnumBitMask<E> operator^(E a, E b) { \ 76 return SkEnumBitMask<E>(a) ^ b; \ 77 } \ 78 [[maybe_unused]] constexpr SkEnumBitMask<E> operator~(E e) { \ 79 return ~SkEnumBitMask<E>(e); \ 80 } 81 82 #define SK_DECL_BITMASK_OPS_FRIENDS(E) \ 83 friend constexpr SkEnumBitMask<E> operator|(E, E); \ 84 friend constexpr SkEnumBitMask<E> operator&(E, E); \ 85 friend constexpr SkEnumBitMask<E> operator^(E, E); \ 86 friend constexpr SkEnumBitMask<E> operator~(E); 87 88 #endif // SkEnumBitMask_DEFINED 89