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