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 skgpu_EnumBitMask_DEFINED 9 #define skgpu_EnumBitMask_DEFINED 10 11 #include "experimental/graphite/include/GraphiteTypes.h" 12 13 namespace skgpu { 14 15 /** 16 * Wraps an enum that is used for flags, and enables masking with type safety. Example: 17 * 18 * enum class MyFlags { 19 * kNone = 0, 20 * kA = 1, 21 * kB = 2, 22 * kC = 4, 23 * }; 24 * 25 * SKGPU_MAKE_MASK_OPS(MyFlags) 26 * 27 * ... 28 * 29 * Mask<MyFlags> flags = MyFlags::kA | MyFlags::kB; 30 * 31 * if (flags & MyFlags::kB) {} 32 * 33 * ... 34 */ 35 template<typename E> 36 class Mask { 37 public: Mask(E e)38 SK_ALWAYS_INLINE constexpr Mask(E e) : Mask((int)e) {} 39 40 SK_ALWAYS_INLINE constexpr operator bool() const { return fValue; } 41 42 SK_ALWAYS_INLINE bool operator==(Mask m) const { return fValue == m.fValue; } 43 SK_ALWAYS_INLINE bool operator!=(Mask m) const { return fValue != m.fValue; } 44 45 SK_ALWAYS_INLINE constexpr Mask operator|(Mask m) const { return Mask(fValue | m.fValue); } 46 SK_ALWAYS_INLINE constexpr Mask operator&(Mask m) const { return Mask(fValue & m.fValue); } 47 SK_ALWAYS_INLINE constexpr Mask operator^(Mask m) const { return Mask(fValue ^ m.fValue); } 48 SK_ALWAYS_INLINE constexpr Mask operator~() const { return Mask(~fValue); } 49 50 SK_ALWAYS_INLINE Mask& operator|=(Mask m) { return *this = *this | m; } 51 SK_ALWAYS_INLINE Mask& operator&=(Mask m) { return *this = *this & m; } 52 SK_ALWAYS_INLINE Mask& operator^=(Mask m) { return *this = *this ^ m; } 53 54 private: Mask(int value)55 SK_ALWAYS_INLINE constexpr explicit Mask(int value) : fValue(value) {} 56 57 int fValue; 58 }; 59 60 /** 61 * Defines functions that make it possible to use bitwise operators on an enum. 62 */ 63 #define SKGPU_MAKE_MASK_OPS(E) \ 64 SK_MAYBE_UNUSED constexpr skgpu::Mask<E> operator|(E a, E b) { return skgpu::Mask<E>(a) | b; } \ 65 SK_MAYBE_UNUSED constexpr skgpu::Mask<E> operator&(E a, E b) { return skgpu::Mask<E>(a) & b; } \ 66 SK_MAYBE_UNUSED constexpr skgpu::Mask<E> operator^(E a, E b) { return skgpu::Mask<E>(a) ^ b; } \ 67 SK_MAYBE_UNUSED constexpr skgpu::Mask<E> operator~(E e) { return ~skgpu::Mask<E>(e); } \ 68 69 #define SKGPU_DECL_MASK_OPS_FRIENDS(E) \ 70 friend constexpr skgpu::Mask<E> operator|(E, E); \ 71 friend constexpr skgpu::Mask<E> operator&(E, E); \ 72 friend constexpr skgpu::Mask<E> operator^(E, E); \ 73 friend constexpr skgpu::Mask<E> operator~(E); \ 74 75 }; // namespace skgpu 76 77 #endif // skgpu_EnumBitMask_DEFINED 78 79 80