-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Expand file tree
/
Copy pathmacros.h
More file actions
242 lines (215 loc) · 9.06 KB
/
macros.h
File metadata and controls
242 lines (215 loc) · 9.06 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <cstdint>
#define ARROW_EXPAND(x) x
#define ARROW_STRINGIFY(x) #x
#define ARROW_CONCAT(x, y) x##y
// From Google gutil
#ifndef ARROW_DISALLOW_COPY_AND_ASSIGN
# define ARROW_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
#endif
#ifndef ARROW_DEFAULT_MOVE_AND_ASSIGN
# define ARROW_DEFAULT_MOVE_AND_ASSIGN(TypeName) \
TypeName(TypeName&&) = default; \
TypeName& operator=(TypeName&&) = default
#endif
// With ARROW_PREDICT_FALSE, GCC and clang can be told that a certain branch is
// not likely to be taken (for instance, a CHECK failure), and use that information in
// static analysis. Giving the compiler this information can affect the generated code
// layout in the absence of better information (i.e. -fprofile-arcs). [1] explains how
// this feature can be used to improve code generation. It was written as a positive
// comment to a negative article about the use of these annotations.
//
// ARROW_COMPILER_ASSUME allows the compiler to assume that a given expression is
// true, without evaluating it, and to optimise based on this assumption [2]. If this
// condition is violated at runtime, the behavior is undefined. This can be useful to
// generate both faster and smaller code in compute kernels.
//
// IMPORTANT: Different optimisers are likely to react differently to this annotation!
// It should be used with care when we can prove by some means that the assumption
// is (1) guaranteed to always hold and (2) is useful for optimization [3]. If the
// assumption is pessimistic, it might even block the compiler from decisions that
// could lead to better code [4]. If you have a good intuition for what the compiler
// can do with assumptions [5], you can use this macro to guide it and end up with
// results you would only get with more complex code transformations.
// `clang -S -emit-llvm` can be used to check how the generated code changes with
// your specific use of this macro.
//
// [1] https://lobste.rs/s/uwgtkt/don_t_use_likely_unlikely_attributes#c_xi3wmc
// [2] "Portable assumptions"
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1774r4.pdf
// [3] "Assertions Are Pessimistic, Assumptions Are Optimistic"
// https://blog.regehr.org/archives/1096
// [4] https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609
// [5] J. Doerfert et al. 2019. "Performance Exploration Through Optimistic Static
// Program Annotations". https://github.com/jdoerfert/PETOSPA/blob/master/ISC19.pdf
#define ARROW_UNUSED(x) (void)(x)
#ifdef ARROW_WARN_DOCUMENTATION
# define ARROW_ARG_UNUSED(x) x
#else
# define ARROW_ARG_UNUSED(x)
#endif
#if defined(__GNUC__) // GCC and compatible compilers (clang, Intel ICC)
# define ARROW_NORETURN __attribute__((noreturn))
# define ARROW_NOINLINE __attribute__((noinline))
# define ARROW_FORCE_INLINE __attribute__((always_inline))
# define ARROW_PREDICT_FALSE(x) (__builtin_expect(!!(x), 0))
# define ARROW_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
# define ARROW_RESTRICT __restrict
# if defined(__clang__) // clang-specific
# define ARROW_COMPILER_ASSUME(expr) __builtin_assume(expr)
# else // GCC-specific
# if __GNUC__ >= 13
# define ARROW_COMPILER_ASSUME(expr) __attribute__((assume(expr)))
# else
// GCC does not have a built-in assume intrinsic before GCC 13, so we use an
// if statement and __builtin_unreachable() to achieve the same effect [2].
// Unlike clang's __builtin_assume and C++23's [[assume(expr)]], using this
// on GCC won't warn about side-effects in the expression, so make sure expr
// is side-effect free when working with GCC versions before 13 (Jan-2024),
// otherwise clang/MSVC builds will fail in CI.
# define ARROW_COMPILER_ASSUME(expr) \
if (expr) { \
} else { \
__builtin_unreachable(); \
}
# endif // __GNUC__ >= 13
# endif
#elif defined(_MSC_VER) // MSVC
# define ARROW_NORETURN __declspec(noreturn)
# define ARROW_NOINLINE __declspec(noinline)
# define ARROW_FORCE_INLINE __forceinline
# define ARROW_PREDICT_FALSE(x) (x)
# define ARROW_PREDICT_TRUE(x) (x)
# define ARROW_RESTRICT __restrict
# define ARROW_COMPILER_ASSUME(expr) __assume(expr)
#else
# define ARROW_NORETURN
# define ARROW_NOINLINE
# define ARROW_FORCE_INLINE
# define ARROW_PREDICT_FALSE(x) (x)
# define ARROW_PREDICT_TRUE(x) (x)
# define ARROW_RESTRICT
# define ARROW_COMPILER_ASSUME(expr)
#endif
// ----------------------------------------------------------------------
// C++/CLI support macros (see ARROW-1134)
#ifndef NULLPTR
# ifdef __cplusplus_cli
# define NULLPTR __nullptr
# else
# define NULLPTR nullptr
# endif
#endif // ifndef NULLPTR
// ----------------------------------------------------------------------
// clang-format off
// [[deprecated]] is only available in C++14, use this for the time being
// This macro takes an optional deprecation message
#ifdef __COVERITY__
# define ARROW_DEPRECATED(...)
#else
# define ARROW_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
#endif
#ifdef __COVERITY__
# define ARROW_DEPRECATED_ENUM_VALUE(...)
#else
# define ARROW_DEPRECATED_ENUM_VALUE(...) [[deprecated(__VA_ARGS__)]]
#endif
// clang-format on
// Macros to disable deprecation warnings
#ifdef __clang__
# define ARROW_SUPPRESS_DEPRECATION_WARNING \
_Pragma("clang diagnostic push"); \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
# define ARROW_UNSUPPRESS_DEPRECATION_WARNING _Pragma("clang diagnostic pop")
#elif defined(__GNUC__)
# define ARROW_SUPPRESS_DEPRECATION_WARNING \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define ARROW_UNSUPPRESS_DEPRECATION_WARNING _Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
# define ARROW_SUPPRESS_DEPRECATION_WARNING \
__pragma(warning(push)) __pragma(warning(disable : 4996))
# define ARROW_UNSUPPRESS_DEPRECATION_WARNING __pragma(warning(pop))
#else
# define ARROW_SUPPRESS_DEPRECATION_WARNING
# define ARROW_UNSUPPRESS_DEPRECATION_WARNING
#endif
// ----------------------------------------------------------------------
// Macros to disable warnings about undeclared global functions
#if defined(__GNUC__)
# define ARROW_SUPPRESS_MISSING_DECLARATIONS_WARNING \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wmissing-declarations\"")
# define ARROW_UNSUPPRESS_MISSING_DECLARATIONS_WARNING _Pragma("GCC diagnostic pop")
#else
# define ARROW_SUPPRESS_MISSING_DECLARATIONS_WARNING
# define ARROW_UNSUPPRESS_MISSING_DECLARATIONS_WARNING
#endif
// ----------------------------------------------------------------------
// Macros to enforce struct member packing
#if defined(__GNUC__)
# define ARROW_PACKED_START(KEYWORD, ...) KEYWORD [[gnu::packed]] __VA_ARGS__
# define ARROW_PACKED_END
#elif defined(_MSC_VER)
# define ARROW_PACKED_START(KEYWORD, ...) _Pragma("pack(push, 1)") KEYWORD __VA_ARGS__
# define ARROW_PACKED_END _Pragma("pack(pop)")
#else
# define ARROW_PACKED_START(KEYWORD, ...) KEYWORD __VA_ARGS__
# define ARROW_PACKED_END
#endif
// ----------------------------------------------------------------------
// Convenience macro disabling a particular UBSan check in a function
#if defined(__clang__)
# define ARROW_DISABLE_UBSAN(feature) __attribute__((no_sanitize(feature)))
#else
# define ARROW_DISABLE_UBSAN(feature)
#endif
// ----------------------------------------------------------------------
// Machine information
#if INTPTR_MAX == INT64_MAX
# define ARROW_BITNESS 64
#elif INTPTR_MAX == INT32_MAX
# define ARROW_BITNESS 32
#else
# error Unexpected INTPTR_MAX
#endif
// ----------------------------------------------------------------------
// From googletest
// (also in parquet-cpp)
// When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the
// class. For example:
//
// class MyClass {
// private:
// void MyMethod();
// FRIEND_TEST(MyClassTest, MyMethod);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
// TEST_F(MyClassTest, MyMethod) {
// // Can call MyClass::MyMethod() here.
// }
#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test