File: SkMacros.h

package info (click to toggle)
webkit2gtk 2.51.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 455,340 kB
  • sloc: cpp: 3,865,253; javascript: 197,710; ansic: 165,177; python: 49,241; asm: 21,868; ruby: 18,095; perl: 16,926; xml: 4,623; sh: 2,409; yacc: 2,356; java: 2,019; lex: 1,330; pascal: 372; makefile: 210
file content (161 lines) | stat: -rw-r--r-- 6,183 bytes parent folder | download | duplicates (19)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkMacros_DEFINED
#define SkMacros_DEFINED

#include "include/private/base/SkTo.h" // IWYU pragma: keep

/*
 *  Usage:  SK_MACRO_CONCAT(a, b)   to construct the symbol ab
 *
 *  SK_MACRO_CONCAT_IMPL_PRIV just exists to make this work. Do not use directly
 *
 */
#define SK_MACRO_CONCAT(X, Y)           SK_MACRO_CONCAT_IMPL_PRIV(X, Y)
#define SK_MACRO_CONCAT_IMPL_PRIV(X, Y)  X ## Y

/*
 *  Usage: SK_MACRO_APPEND_LINE(foo)    to make foo123, where 123 is the current
 *                                      line number. Easy way to construct
 *                                      unique names for local functions or
 *                                      variables.
 */
#define SK_MACRO_APPEND_LINE(name)  SK_MACRO_CONCAT(name, __LINE__)

#define SK_MACRO_APPEND_COUNTER(name) SK_MACRO_CONCAT(name, __COUNTER__)

////////////////////////////////////////////////////////////////////////////////

// Can be used to bracket data types that must be dense/packed, e.g. hash keys.
#if defined(__clang__)  // This should work on GCC too, but GCC diagnostic pop didn't seem to work!
    #define SK_BEGIN_REQUIRE_DENSE _Pragma("GCC diagnostic push") \
                                   _Pragma("GCC diagnostic error \"-Wpadded\"")
    #define SK_END_REQUIRE_DENSE   _Pragma("GCC diagnostic pop")
#else
    #define SK_BEGIN_REQUIRE_DENSE
    #define SK_END_REQUIRE_DENSE
#endif

#if defined(__clang__) && defined(__has_feature)
    // Some compilers have a preprocessor that does not appear to do short-circuit
    // evaluation as expected
    #if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
        // Chrome had issues if we tried to include lsan_interface.h ourselves.
        // https://github.com/llvm/llvm-project/blob/10a35632d55bb05004fe3d0c2d4432bb74897ee7/compiler-rt/include/sanitizer/lsan_interface.h#L26
extern "C" {
        void __lsan_ignore_object(const void *p);
}
        #define SK_INTENTIONALLY_LEAKED(X) __lsan_ignore_object(X)
    #else
        #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
    #endif
#else
    #define SK_INTENTIONALLY_LEAKED(X) ((void)0)
#endif

#define SK_INIT_TO_AVOID_WARNING    = 0

////////////////////////////////////////////////////////////////////////////////

/**
 * Defines overloaded bitwise operators to make it easier to use an enum as a
 * bitfield.
 */
#define SK_MAKE_BITFIELD_OPS(X) \
    inline X operator ~(X a) { \
        using U = std::underlying_type_t<X>; \
        return (X) (~static_cast<U>(a)); \
    } \
    inline X operator |(X a, X b) { \
        using U = std::underlying_type_t<X>; \
        return (X) (static_cast<U>(a) | static_cast<U>(b)); \
    } \
    inline X& operator |=(X& a, X b) { \
        return (a = a | b); \
    } \
    inline X operator &(X a, X b) { \
        using U = std::underlying_type_t<X>; \
        return (X) (static_cast<U>(a) & static_cast<U>(b)); \
    } \
    inline X& operator &=(X& a, X b) { \
        return (a = a & b); \
    }

#define SK_DECL_BITFIELD_OPS_FRIENDS(X) \
    friend X operator ~(X a); \
    friend X operator |(X a, X b); \
    friend X& operator |=(X& a, X b); \
    \
    friend X operator &(X a, X b); \
    friend X& operator &=(X& a, X b);

/**
 * Wraps a C++11 enum that we use as a bitfield, and enables a limited amount of
 * masking with type safety. Instantiated with the ~ operator.
 */
template<typename TFlags> class SkTFlagsMask {
public:
    constexpr explicit SkTFlagsMask(TFlags value) : SkTFlagsMask(static_cast<int>(value)) {}
    constexpr explicit SkTFlagsMask(int value) : fValue(value) {}
    constexpr int value() const { return fValue; }
private:
    const int fValue;
};

/**
 * Defines bitwise operators that make it possible to use an enum class as a
 * basic bitfield.
 */
#define SK_MAKE_BITFIELD_CLASS_OPS(X) \
    [[maybe_unused]] constexpr SkTFlagsMask<X> operator~(X a) { \
        return SkTFlagsMask<X>(~static_cast<int>(a)); \
    } \
    [[maybe_unused]] constexpr X operator|(X a, X b) { \
        return static_cast<X>(static_cast<int>(a) | static_cast<int>(b)); \
    } \
    [[maybe_unused]] inline X& operator|=(X& a, X b) { \
        return (a = a | b); \
    } \
    [[maybe_unused]] constexpr bool operator&(X a, X b) { \
        return SkToBool(static_cast<int>(a) & static_cast<int>(b)); \
    } \
    [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X> a, SkTFlagsMask<X> b) { \
        return SkTFlagsMask<X>(a.value() | b.value()); \
    } \
    [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X> a, X b) { \
        return SkTFlagsMask<X>(a.value() | static_cast<int>(b)); \
    } \
    [[maybe_unused]] constexpr SkTFlagsMask<X> operator|(X a, SkTFlagsMask<X> b) { \
        return SkTFlagsMask<X>(static_cast<int>(a) | b.value()); \
    } \
    [[maybe_unused]] constexpr X operator&(SkTFlagsMask<X> a, SkTFlagsMask<X> b) { \
        return static_cast<X>(a.value() & b.value()); \
    } \
    [[maybe_unused]] constexpr X operator&(SkTFlagsMask<X> a, X b) { \
        return static_cast<X>(a.value() & static_cast<int>(b)); \
    } \
    [[maybe_unused]] constexpr X operator&(X a, SkTFlagsMask<X> b) { \
        return static_cast<X>(static_cast<int>(a) & b.value()); \
    } \
    [[maybe_unused]] inline X& operator&=(X& a, SkTFlagsMask<X> b) { \
        return (a = a & b); \
    } \

#define SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(X) \
    friend constexpr SkTFlagsMask<X> operator ~(X); \
    friend constexpr X operator |(X, X); \
    friend X& operator |=(X&, X); \
    friend constexpr bool operator &(X, X); \
    friend constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X>, SkTFlagsMask<X>); \
    friend constexpr SkTFlagsMask<X> operator|(SkTFlagsMask<X>, X); \
    friend constexpr SkTFlagsMask<X> operator|(X, SkTFlagsMask<X>); \
    friend constexpr X operator&(SkTFlagsMask<X>, SkTFlagsMask<X>); \
    friend constexpr X operator&(SkTFlagsMask<X>, X); \
    friend constexpr X operator&(X, SkTFlagsMask<X>); \
    friend X& operator &=(X&, SkTFlagsMask<X>)

#endif  // SkMacros_DEFINED