xref: /aosp_15_r20/external/skia/include/private/base/SkMacros.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2018 Google Inc.
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 #ifndef SkMacros_DEFINED
8*c8dee2aaSAndroid Build Coastguard Worker #define SkMacros_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h" // IWYU pragma: keep
11*c8dee2aaSAndroid Build Coastguard Worker 
12*c8dee2aaSAndroid Build Coastguard Worker /*
13*c8dee2aaSAndroid Build Coastguard Worker  *  Usage:  SK_MACRO_CONCAT(a, b)   to construct the symbol ab
14*c8dee2aaSAndroid Build Coastguard Worker  *
15*c8dee2aaSAndroid Build Coastguard Worker  *  SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
16*c8dee2aaSAndroid Build Coastguard Worker  *
17*c8dee2aaSAndroid Build Coastguard Worker  */
18*c8dee2aaSAndroid Build Coastguard Worker #define SK_MACRO_CONCAT(X, Y)           SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
19*c8dee2aaSAndroid Build Coastguard Worker #define SK_MACRO_CONCAT_IMPL_PRIV(X, Y)  X ## Y
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker /*
22*c8dee2aaSAndroid Build Coastguard Worker  *  Usage: SK_MACRO_APPEND_LINE(foo)    to make foo123, where 123 is the current
23*c8dee2aaSAndroid Build Coastguard Worker  *                                      line number. Easy way to construct
24*c8dee2aaSAndroid Build Coastguard Worker  *                                      unique names for local functions or
25*c8dee2aaSAndroid Build Coastguard Worker  *                                      variables.
26*c8dee2aaSAndroid Build Coastguard Worker  */
27*c8dee2aaSAndroid Build Coastguard Worker #define SK_MACRO_APPEND_LINE(name)  SK_MACRO_CONCAT(name, __LINE__)
28*c8dee2aaSAndroid Build Coastguard Worker 
29*c8dee2aaSAndroid Build Coastguard Worker #define SK_MACRO_APPEND_COUNTER(name) SK_MACRO_CONCAT(name, __COUNTER__)
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
32*c8dee2aaSAndroid Build Coastguard Worker 
33*c8dee2aaSAndroid Build Coastguard Worker // Can be used to bracket data types that must be dense/packed, e.g. hash keys.
34*c8dee2aaSAndroid Build Coastguard Worker #if defined(__clang__)  // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
35*c8dee2aaSAndroid Build Coastguard Worker     #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
36*c8dee2aaSAndroid Build Coastguard Worker                                    _Pragma("GCC diagnostic error \"-Wpadded\"")
37*c8dee2aaSAndroid Build Coastguard Worker     #define SK_END_REQUIRE_DENSE   _Pragma("GCC diagnostic pop")
38*c8dee2aaSAndroid Build Coastguard Worker #else
39*c8dee2aaSAndroid Build Coastguard Worker     #define SK_BEGIN_REQUIRE_DENSE
40*c8dee2aaSAndroid Build Coastguard Worker     #define SK_END_REQUIRE_DENSE
41*c8dee2aaSAndroid Build Coastguard Worker #endif
42*c8dee2aaSAndroid Build Coastguard Worker 
43*c8dee2aaSAndroid Build Coastguard Worker #if defined(__clang__) && defined(__has_feature)
44*c8dee2aaSAndroid Build Coastguard Worker     // Some compilers have a preprocessor that does not appear to do short-circuit
45*c8dee2aaSAndroid Build Coastguard Worker     // evaluation as expected
46*c8dee2aaSAndroid Build Coastguard Worker     #if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
47*c8dee2aaSAndroid Build Coastguard Worker         // Chrome had issues if we tried to include lsan_interface.h ourselves.
48*c8dee2aaSAndroid Build Coastguard Worker         // https://github.com/llvm/llvm-project/blob/10a35632d55bb05004fe3d0c2d4432bb74897ee7/compiler-rt/include/sanitizer/lsan_interface.h#L26
49*c8dee2aaSAndroid Build Coastguard Worker extern "C" {
50*c8dee2aaSAndroid Build Coastguard Worker         void __lsan_ignore_object(const void *p);
51*c8dee2aaSAndroid Build Coastguard Worker }
52*c8dee2aaSAndroid Build Coastguard Worker         #define SK_INTENTIONALLY_LEAKED(X) __lsan_ignore_object(X)
53*c8dee2aaSAndroid Build Coastguard Worker     #else
54*c8dee2aaSAndroid Build Coastguard Worker         #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
55*c8dee2aaSAndroid Build Coastguard Worker     #endif
56*c8dee2aaSAndroid Build Coastguard Worker #else
57*c8dee2aaSAndroid Build Coastguard Worker     #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
58*c8dee2aaSAndroid Build Coastguard Worker #endif
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker #define SK_INIT_TO_AVOID_WARNING    = 0
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker /**
65*c8dee2aaSAndroid Build Coastguard Worker  * Defines overloaded bitwise operators to make it easier to use an enum as a
66*c8dee2aaSAndroid Build Coastguard Worker  * bitfield.
67*c8dee2aaSAndroid Build Coastguard Worker  */
68*c8dee2aaSAndroid Build Coastguard Worker #define SK_MAKE_BITFIELD_OPS(X) \
69*c8dee2aaSAndroid Build Coastguard Worker     inline X operator ~(X a) { \
70*c8dee2aaSAndroid Build Coastguard Worker         using U = std::underlying_type_t<X>; \
71*c8dee2aaSAndroid Build Coastguard Worker         return (X) (~static_cast<U>(a)); \
72*c8dee2aaSAndroid Build Coastguard Worker     } \
73*c8dee2aaSAndroid Build Coastguard Worker     inline X operator |(X a, X b) { \
74*c8dee2aaSAndroid Build Coastguard Worker         using U = std::underlying_type_t<X>; \
75*c8dee2aaSAndroid Build Coastguard Worker         return (X) (static_cast<U>(a) | static_cast<U>(b)); \
76*c8dee2aaSAndroid Build Coastguard Worker     } \
77*c8dee2aaSAndroid Build Coastguard Worker     inline X& operator |=(X& a, X b) { \
78*c8dee2aaSAndroid Build Coastguard Worker         return (a = a | b); \
79*c8dee2aaSAndroid Build Coastguard Worker     } \
80*c8dee2aaSAndroid Build Coastguard Worker     inline X operator &(X a, X b) { \
81*c8dee2aaSAndroid Build Coastguard Worker         using U = std::underlying_type_t<X>; \
82*c8dee2aaSAndroid Build Coastguard Worker         return (X) (static_cast<U>(a) & static_cast<U>(b)); \
83*c8dee2aaSAndroid Build Coastguard Worker     } \
84*c8dee2aaSAndroid Build Coastguard Worker     inline X& operator &=(X& a, X b) { \
85*c8dee2aaSAndroid Build Coastguard Worker         return (a = a & b); \
86*c8dee2aaSAndroid Build Coastguard Worker     }
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker #define SK_DECL_BITFIELD_OPS_FRIENDS(X) \
89*c8dee2aaSAndroid Build Coastguard Worker     friend X operator ~(X a); \
90*c8dee2aaSAndroid Build Coastguard Worker     friend X operator |(X a, X b); \
91*c8dee2aaSAndroid Build Coastguard Worker     friend X& operator |=(X& a, X b); \
92*c8dee2aaSAndroid Build Coastguard Worker     \
93*c8dee2aaSAndroid Build Coastguard Worker     friend X operator &(X a, X b); \
94*c8dee2aaSAndroid Build Coastguard Worker     friend X& operator &=(X& a, X b);
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker /**
97*c8dee2aaSAndroid Build Coastguard Worker  * Wraps a C++11 enum that we use as a bitfield, and enables a limited amount of
98*c8dee2aaSAndroid Build Coastguard Worker  * masking with type safety. Instantiated with the ~ operator.
99*c8dee2aaSAndroid Build Coastguard Worker  */
100*c8dee2aaSAndroid Build Coastguard Worker template<typename TFlags> class SkTFlagsMask {
101*c8dee2aaSAndroid Build Coastguard Worker public:
SkTFlagsMask(TFlags value)102*c8dee2aaSAndroid Build Coastguard Worker     constexpr explicit SkTFlagsMask(TFlags value) : SkTFlagsMask(static_cast<int>(value)) {}
SkTFlagsMask(int value)103*c8dee2aaSAndroid Build Coastguard Worker     constexpr explicit SkTFlagsMask(int value) : fValue(value) {}
value()104*c8dee2aaSAndroid Build Coastguard Worker     constexpr int value() const { return fValue; }
105*c8dee2aaSAndroid Build Coastguard Worker private:
106*c8dee2aaSAndroid Build Coastguard Worker     const int fValue;
107*c8dee2aaSAndroid Build Coastguard Worker };
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker /**
110*c8dee2aaSAndroid Build Coastguard Worker  * Defines bitwise operators that make it possible to use an enum class as a
111*c8dee2aaSAndroid Build Coastguard Worker  * basic bitfield.
112*c8dee2aaSAndroid Build Coastguard Worker  */
113*c8dee2aaSAndroid Build Coastguard Worker #define SK_MAKE_BITFIELD_CLASS_OPS(X) \
114*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr SkTFlagsMask<X> operator~(X a) { \
115*c8dee2aaSAndroid Build Coastguard Worker         return SkTFlagsMask<X>(~static_cast<int>(a)); \
116*c8dee2aaSAndroid Build Coastguard Worker     } \
117*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr X operator|(X a, X b) { \
118*c8dee2aaSAndroid Build Coastguard Worker         return static_cast<X>(static_cast<int>(a) | static_cast<int>(b)); \
119*c8dee2aaSAndroid Build Coastguard Worker     } \
120*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] inline X& operator|=(X& a, X b) { \
121*c8dee2aaSAndroid Build Coastguard Worker         return (a = a | b); \
122*c8dee2aaSAndroid Build Coastguard Worker     } \
123*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr bool operator&(X a, X b) { \
124*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(static_cast<int>(a) & static_cast<int>(b)); \
125*c8dee2aaSAndroid Build Coastguard Worker     } \
126*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X> a, SkTFlagsMask<X> b) { \
127*c8dee2aaSAndroid Build Coastguard Worker         return SkTFlagsMask<X>(a.value() | b.value()); \
128*c8dee2aaSAndroid Build Coastguard Worker     } \
129*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X> a, X b) { \
130*c8dee2aaSAndroid Build Coastguard Worker         return SkTFlagsMask<X>(a.value() | static_cast<int>(b)); \
131*c8dee2aaSAndroid Build Coastguard Worker     } \
132*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(X a, SkTFlagsMask<X> b) { \
133*c8dee2aaSAndroid Build Coastguard Worker         return SkTFlagsMask<X>(static_cast<int>(a) | b.value()); \
134*c8dee2aaSAndroid Build Coastguard Worker     } \
135*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr X operator&(SkTFlagsMask<X> a, SkTFlagsMask<X> b) { \
136*c8dee2aaSAndroid Build Coastguard Worker         return static_cast<X>(a.value() & b.value()); \
137*c8dee2aaSAndroid Build Coastguard Worker     } \
138*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr X operator&(SkTFlagsMask<X> a, X b) { \
139*c8dee2aaSAndroid Build Coastguard Worker         return static_cast<X>(a.value() & static_cast<int>(b)); \
140*c8dee2aaSAndroid Build Coastguard Worker     } \
141*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] constexpr X operator&(X a, SkTFlagsMask<X> b) { \
142*c8dee2aaSAndroid Build Coastguard Worker         return static_cast<X>(static_cast<int>(a) & b.value()); \
143*c8dee2aaSAndroid Build Coastguard Worker     } \
144*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] inline X& operator&=(X& a, SkTFlagsMask<X> b) { \
145*c8dee2aaSAndroid Build Coastguard Worker         return (a = a & b); \
146*c8dee2aaSAndroid Build Coastguard Worker     } \
147*c8dee2aaSAndroid Build Coastguard Worker 
148*c8dee2aaSAndroid Build Coastguard Worker #define SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(X) \
149*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr SkTFlagsMask<X> operator ~(X); \
150*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr X operator |(X, X); \
151*c8dee2aaSAndroid Build Coastguard Worker     friend X& operator |=(X&, X); \
152*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr bool operator &(X, X); \
153*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X>, SkTFlagsMask<X>); \
154*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X>, X); \
155*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr SkTFlagsMask<X> operator|(X, SkTFlagsMask<X>); \
156*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr X operator&(SkTFlagsMask<X>, SkTFlagsMask<X>); \
157*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr X operator&(SkTFlagsMask<X>, X); \
158*c8dee2aaSAndroid Build Coastguard Worker     friend constexpr X operator&(X, SkTFlagsMask<X>); \
159*c8dee2aaSAndroid Build Coastguard Worker     friend X& operator &=(X&, SkTFlagsMask<X>)
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker #endif  // SkMacros_DEFINED
162