• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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