xref: /aosp_15_r20/external/skia/src/base/SkEnumBitMask.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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