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