YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/gutil/macros.h
Line
Count
Source
1
// Copyright 2008 Google Inc. All Rights Reserved.
2
//
3
// The following only applies to changes made to this file as part of YugaByte development.
4
//
5
// Portions Copyright (c) YugaByte, Inc.
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8
// in compliance with the License.  You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software distributed under the License
13
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14
// or implied.  See the License for the specific language governing permissions and limitations
15
// under the License.
16
//
17
// Various Google-specific macros.
18
//
19
// This code is compiled directly on many platforms, including client
20
// platforms like Windows, Mac, and embedded systems.  Before making
21
// any changes here, make sure that you're not breaking any platforms.
22
//
23
24
#ifndef YB_GUTIL_MACROS_H
25
#define YB_GUTIL_MACROS_H
26
27
#include <stddef.h>         // For size_t
28
#include "yb/gutil/port.h"
29
30
// The swigged version of an abstract class must be concrete if any methods
31
// return objects of the abstract type. We keep it abstract in C++ and
32
// concrete for swig.
33
#ifndef SWIG
34
#define ABSTRACT = 0
35
#endif
36
37
// The COMPILE_ASSERT macro can be used to verify that a compile time
38
// expression is true. For example, you could use it to verify the
39
// size of a static array:
40
//
41
//   COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
42
//                  content_type_names_incorrect_size);
43
//
44
// or to make sure a struct is smaller than a certain size:
45
//
46
//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
47
//
48
// The second argument to the macro is the name of the variable. If
49
// the expression is false, most compilers will issue a warning/error
50
// containing the name of the variable.
51
52
template <bool>
53
struct CompileAssert {
54
};
55
56
#define COMPILE_ASSERT(expr, msg) \
57
250M
  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED
58
59
// Implementation details of COMPILE_ASSERT:
60
//
61
// - COMPILE_ASSERT works by defining an array type that has -1
62
//   elements (and thus is invalid) when the expression is false.
63
//
64
// - The simpler definition
65
//
66
//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
67
//
68
//   does not work, as gcc supports variable-length arrays whose sizes
69
//   are determined at run-time (this is gcc's extension and not part
70
//   of the C++ standard).  As a result, gcc fails to reject the
71
//   following code with the simple definition:
72
//
73
//     int foo;
74
//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
75
//                               // not a compile-time constant.
76
//
77
// - By using the type CompileAssert<(bool(expr))>, we ensures that
78
//   expr is a compile-time constant.  (Template arguments must be
79
//   determined at compile-time.)
80
//
81
// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
82
//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
83
//
84
//     CompileAssert<bool(expr)>
85
//
86
//   instead, these compilers will refuse to compile
87
//
88
//     COMPILE_ASSERT(5 > 0, some_message);
89
//
90
//   (They seem to think the ">" in "5 > 0" marks the end of the
91
//   template argument list.)
92
//
93
// - The array size is (bool(expr) ? 1 : -1), instead of simply
94
//
95
//     ((expr) ? 1 : -1).
96
//
97
//   This is to avoid running into a bug in MS VC 7.1, which
98
//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
99
100
101
// A macro to disallow the copy constructor and operator= functions
102
// This should be used in the private: declarations for a class
103
//
104
// For disallowing only assign or copy, write the code directly, but declare
105
// the intend in a comment, for example:
106
// void operator=(const TypeName&);  // DISALLOW_ASSIGN
107
// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
108
// semantically, one should either use disallow both or neither. Try to
109
// avoid these in new code.
110
//
111
// The LANG_CXX11 branch is a workaround for
112
// http://gcc.gnu.org/PR51213 in gcc-4.7 / Crosstool v16.
113
// TODO(user): Remove "&& !defined(__clang_)" when =delete is
114
// gcc-4.7 before =delete is allowed, go back to the C++98 definition.
115
#if LANG_CXX11 && !defined(__clang__)
116
#ifndef DISALLOW_COPY_AND_ASSIGN
117
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
118
  TypeName(const TypeName&) = delete;      \
119
  void operator=(const TypeName&) = delete
120
#endif
121
#else
122
#ifndef DISALLOW_COPY_AND_ASSIGN
123
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
124
  TypeName(const TypeName&);               \
125
  void operator=(const TypeName&)
126
#endif
127
#endif
128
129
// An older, politically incorrect name for the above.
130
// Prefer DISALLOW_COPY_AND_ASSIGN for new code.
131
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
132
133
// A macro to disallow all the implicit constructors, namely the
134
// default constructor, copy constructor and operator= functions.
135
//
136
// This should be used in the private: declarations for a class
137
// that wants to prevent anyone from instantiating it. This is
138
// especially useful for classes containing only static methods.
139
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
140
  TypeName();                                    \
141
  DISALLOW_COPY_AND_ASSIGN(TypeName)
142
143
// The arraysize(arr) macro returns the # of elements in an array arr.
144
// The expression is a compile-time constant, and therefore can be
145
// used in defining new arrays, for example.  If you use arraysize on
146
// a pointer by mistake, you will get a compile-time error.
147
//
148
// One caveat is that, for C++03, arraysize() doesn't accept any array of
149
// an anonymous type or a type defined inside a function.  In these rare
150
// cases, you have to use the unsafe ARRAYSIZE() macro below.  This is
151
// due to a limitation in C++03's template system.  The limitation has
152
// been removed in C++11.
153
154
// This template function declaration is used in defining arraysize.
155
// Note that the function doesn't need an implementation, as we only
156
// use its type.
157
template <typename T, size_t N>
158
char (&ArraySizeHelper(T (&array)[N]))[N];
159
160
// That gcc wants both of these prototypes seems mysterious. VC, for
161
// its part, can't decide which to use (another mystery). Matching of
162
// template overloads: the final frontier.
163
#ifndef _MSC_VER
164
template <typename T, size_t N>
165
char (&ArraySizeHelper(const T (&array)[N]))[N];
166
#endif
167
168
590M
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
169
170
// ARRAYSIZE performs essentially the same calculation as arraysize,
171
// but can be used on anonymous types or types defined inside
172
// functions.  It's less safe than arraysize as it accepts some
173
// (although not all) pointers.  Therefore, you should use arraysize
174
// whenever possible.
175
//
176
// The expression ARRAYSIZE(a) is a compile-time constant of type
177
// size_t.
178
//
179
// ARRAYSIZE catches a few type errors.  If you see a compiler error
180
//
181
//   "warning: division by zero in ..."
182
//
183
// when using ARRAYSIZE, you are (wrongfully) giving it a pointer.
184
// You should only use ARRAYSIZE on statically allocated arrays.
185
//
186
// The following comments are on the implementation details, and can
187
// be ignored by the users.
188
//
189
// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
190
// the array) and sizeof(*(arr)) (the # of bytes in one array
191
// element).  If the former is divisible by the latter, perhaps arr is
192
// indeed an array, in which case the division result is the # of
193
// elements in the array.  Otherwise, arr cannot possibly be an array,
194
// and we generate a compiler error to prevent the code from
195
// compiling.
196
//
197
// Since the size of bool is implementation-defined, we need to cast
198
// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
199
// result has type size_t.
200
//
201
// This macro is not perfect as it wrongfully accepts certain
202
// pointers, namely where the pointer size is divisible by the pointee
203
// size.  For code that goes through a 32-bit compiler, where a pointer
204
// is 4 bytes, this means all pointers to a type whose size is 3 or
205
// greater than 4 will be (righteously) rejected.
206
//
207
// Kudos to Jorg Brown for this simple and elegant implementation.
208
//
209
// - wan 2005-11-16
210
//
211
// Starting with Visual C++ 2005, WinNT.h includes ARRAYSIZE.
212
#if !defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1400)
213
#define ARRAYSIZE(a) \
214
2.50k
  ((sizeof(a) / sizeof(*(a))) / \
215
2.50k
   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
216
#endif
217
218
// A macro to turn a symbol into a string
219
11.7M
#define AS_STRING(x)   AS_STRING_INTERNAL(x)
220
11.7M
#define AS_STRING_INTERNAL(x)   #x
221
222
// Macro that allows definition of a variable appended with the current line
223
// number in the source file. Typically for use by other macros to allow the
224
// user to declare multiple variables with the same "base" name inside the same
225
// lexical block.
226
3.06M
#define VARNAME_LINENUM(varname) VARNAME_LINENUM_INTERNAL(varname ## _L, __LINE__)
227
3.06M
#define VARNAME_LINENUM_INTERNAL(v, line) VARNAME_LINENUM_INTERNAL2(v, line)
228
3.06M
#define VARNAME_LINENUM_INTERNAL2(v, line) v ## line
229
230
// The following enum should be used only as a constructor argument to indicate
231
// that the variable has static storage class, and that the constructor should
232
// do nothing to its state.  It indicates to the reader that it is legal to
233
// declare a static instance of the class, provided the constructor is given
234
// the base::LINKER_INITIALIZED argument.  Normally, it is unsafe to declare a
235
// static variable that has a constructor or a destructor because invocation
236
// order is undefined.  However, IF the type can be initialized by filling with
237
// zeroes (which the loader does for static variables), AND the type's
238
// destructor does nothing to the storage, then a constructor for static
239
// initialization can be declared as
240
//       explicit MyClass(base::LinkerInitialized x) {}
241
// and invoked as
242
//       static MyClass my_variable_name(base::LINKER_INITIALIZED);
243
namespace base {
244
enum LinkerInitialized { LINKER_INITIALIZED };
245
}
246
247
// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
248
// between switch labels:
249
//  switch (x) {
250
//    case 40:
251
//    case 41:
252
//      if (truth_is_out_there) {
253
//        ++x;
254
//        FALLTHROUGH_INTENDED;  // Use instead of/along with annotations in
255
//                               // comments.
256
//      } else {
257
//        return x;
258
//      }
259
//    case 42:
260
//      ...
261
//
262
//  As shown in the example above, the FALLTHROUGH_INTENDED macro should be
263
//  followed by a semicolon. It is designed to mimic control-flow statements
264
//  like 'break;', so it can be placed in most places where 'break;' can, but
265
//  only if there are no statements on the execution path between it and the
266
//  next switch label.
267
//
268
//  When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is
269
//  expanded to [[clang::fallthrough]] attribute, which is analysed when
270
//  performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
271
//  See clang documentation on language extensions for details:
272
//  http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough
273
//
274
//  When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
275
//  effect on diagnostics.
276
//
277
//  In either case this macro has no effect on runtime behavior and performance
278
//  of code.
279
#if __cplusplus >= 201703L
280
#define FALLTHROUGH_INTENDED [[fallthrough]]
281
#elif defined(__clang__) && defined(LANG_CXX11) && defined(__has_warning)
282
#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
283
7.81G
#define FALLTHROUGH_INTENDED [[clang::fallthrough]]  // NOLINT
284
#endif
285
#elif defined(__GNUC__) && __GNUC__ >= 7
286
#define FALLTHROUGH_INTENDED [[gnu::fallthrough]]
287
#endif
288
289
#ifndef FALLTHROUGH_INTENDED
290
#define FALLTHROUGH_INTENDED do { } while (0)
291
#endif
292
293
// Generally it is better to not initialize variables with default values to let the compiler find
294
// branches where we don't set it and then use instead of masking issues and silently use dummy
295
// values incorrectly.
296
// But for FASTDEBUG build GCC 5.5 can't handle this correctly and issues false alarm, so
297
// we use default initialization specifically for this case.
298
#ifdef FASTDEBUG
299
#define FASTDEBUG_FAKE_INIT(x) {x}
300
#else
301
#define FASTDEBUG_FAKE_INIT(x)
302
#endif
303
304
#endif  // YB_GUTIL_MACROS_H