1 | // |
2 | // Copyright 2017 The Abseil Authors. |
3 | // |
4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | // you may not use this file except in compliance with the License. |
6 | // You may obtain a copy of the License at |
7 | // |
8 | // https://www.apache.org/licenses/LICENSE-2.0 |
9 | // |
10 | // Unless required by applicable law or agreed to in writing, software |
11 | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | // See the License for the specific language governing permissions and |
14 | // limitations under the License. |
15 | // |
16 | // ----------------------------------------------------------------------------- |
17 | // File: macros.h |
18 | // ----------------------------------------------------------------------------- |
19 | // |
20 | // This header file defines the set of language macros used within Abseil code. |
21 | // For the set of macros used to determine supported compilers and platforms, |
22 | // see absl/base/config.h instead. |
23 | // |
24 | // This code is compiled directly on many platforms, including client |
25 | // platforms like Windows, Mac, and embedded systems. Before making |
26 | // any changes here, make sure that you're not breaking any platforms. |
27 | |
28 | #ifndef ABSL_BASE_MACROS_H_ |
29 | #define ABSL_BASE_MACROS_H_ |
30 | |
31 | #include <cassert> |
32 | #include <cstddef> |
33 | |
34 | #include "absl/base/optimization.h" |
35 | #include "absl/base/port.h" |
36 | |
37 | // ABSL_ARRAYSIZE() |
38 | // |
39 | // Returns the number of elements in an array as a compile-time constant, which |
40 | // can be used in defining new arrays. If you use this macro on a pointer by |
41 | // mistake, you will get a compile-time error. |
42 | #define ABSL_ARRAYSIZE(array) \ |
43 | (sizeof(::absl::macros_internal::ArraySizeHelper(array))) |
44 | |
45 | namespace absl { |
46 | namespace macros_internal { |
47 | // Note: this internal template function declaration is used by ABSL_ARRAYSIZE. |
48 | // The function doesn't need a definition, as we only use its type. |
49 | template <typename T, size_t N> |
50 | auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; |
51 | } // namespace macros_internal |
52 | } // namespace absl |
53 | |
54 | // kLinkerInitialized |
55 | // |
56 | // An enum used only as a constructor argument to indicate that a variable has |
57 | // static storage duration, and that the constructor should do nothing to its |
58 | // state. Use of this macro indicates to the reader that it is legal to |
59 | // declare a static instance of the class, provided the constructor is given |
60 | // the absl::base_internal::kLinkerInitialized argument. |
61 | // |
62 | // Normally, it is unsafe to declare a static variable that has a constructor or |
63 | // a destructor because invocation order is undefined. However, if the type can |
64 | // be zero-initialized (which the loader does for static variables) into a valid |
65 | // state and the type's destructor does not affect storage, then a constructor |
66 | // for static initialization can be declared. |
67 | // |
68 | // Example: |
69 | // // Declaration |
70 | // explicit MyClass(absl::base_internal:LinkerInitialized x) {} |
71 | // |
72 | // // Invocation |
73 | // static MyClass my_global(absl::base_internal::kLinkerInitialized); |
74 | namespace absl { |
75 | namespace base_internal { |
76 | enum LinkerInitialized { |
77 | kLinkerInitialized = 0, |
78 | }; |
79 | } // namespace base_internal |
80 | } // namespace absl |
81 | |
82 | // ABSL_FALLTHROUGH_INTENDED |
83 | // |
84 | // Annotates implicit fall-through between switch labels, allowing a case to |
85 | // indicate intentional fallthrough and turn off warnings about any lack of a |
86 | // `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by |
87 | // a semicolon and can be used in most places where `break` can, provided that |
88 | // no statements exist between it and the next switch label. |
89 | // |
90 | // Example: |
91 | // |
92 | // switch (x) { |
93 | // case 40: |
94 | // case 41: |
95 | // if (truth_is_out_there) { |
96 | // ++x; |
97 | // ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations |
98 | // // in comments |
99 | // } else { |
100 | // return x; |
101 | // } |
102 | // case 42: |
103 | // ... |
104 | // |
105 | // Notes: when compiled with clang in C++11 mode, the ABSL_FALLTHROUGH_INTENDED |
106 | // macro is expanded to the [[clang::fallthrough]] attribute, which is analysed |
107 | // when performing switch labels fall-through diagnostic |
108 | // (`-Wimplicit-fallthrough`). See clang documentation on language extensions |
109 | // for details: |
110 | // http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough |
111 | // |
112 | // When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro |
113 | // has no effect on diagnostics. In any case this macro has no effect on runtime |
114 | // behavior and performance of code. |
115 | #ifdef ABSL_FALLTHROUGH_INTENDED |
116 | #error "ABSL_FALLTHROUGH_INTENDED should not be defined." |
117 | #endif |
118 | |
119 | // TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. |
120 | #if defined(__clang__) && defined(__has_warning) |
121 | #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") |
122 | #define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] |
123 | #endif |
124 | #elif defined(__GNUC__) && __GNUC__ >= 7 |
125 | #define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] |
126 | #endif |
127 | |
128 | #ifndef ABSL_FALLTHROUGH_INTENDED |
129 | #define ABSL_FALLTHROUGH_INTENDED \ |
130 | do { \ |
131 | } while (0) |
132 | #endif |
133 | |
134 | // ABSL_DEPRECATED() |
135 | // |
136 | // Marks a deprecated class, struct, enum, function, method and variable |
137 | // declarations. The macro argument is used as a custom diagnostic message (e.g. |
138 | // suggestion of a better alternative). |
139 | // |
140 | // Example: |
141 | // |
142 | // class ABSL_DEPRECATED("Use Bar instead") Foo {...}; |
143 | // ABSL_DEPRECATED("Use Baz instead") void Bar() {...} |
144 | // |
145 | // Every usage of a deprecated entity will trigger a warning when compiled with |
146 | // clang's `-Wdeprecated-declarations` option. This option is turned off by |
147 | // default, but the warnings will be reported by clang-tidy. |
148 | #if defined(__clang__) && __cplusplus >= 201103L |
149 | #define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) |
150 | #endif |
151 | |
152 | #ifndef ABSL_DEPRECATED |
153 | #define ABSL_DEPRECATED(message) |
154 | #endif |
155 | |
156 | // ABSL_BAD_CALL_IF() |
157 | // |
158 | // Used on a function overload to trap bad calls: any call that matches the |
159 | // overload will cause a compile-time error. This macro uses a clang-specific |
160 | // "enable_if" attribute, as described at |
161 | // http://clang.llvm.org/docs/AttributeReference.html#enable-if |
162 | // |
163 | // Overloads which use this macro should be bracketed by |
164 | // `#ifdef ABSL_BAD_CALL_IF`. |
165 | // |
166 | // Example: |
167 | // |
168 | // int isdigit(int c); |
169 | // #ifdef ABSL_BAD_CALL_IF |
170 | // int isdigit(int c) |
171 | // ABSL_BAD_CALL_IF(c <= -1 || c > 255, |
172 | // "'c' must have the value of an unsigned char or EOF"); |
173 | // #endif // ABSL_BAD_CALL_IF |
174 | |
175 | #if defined(__clang__) |
176 | # if __has_attribute(enable_if) |
177 | # define ABSL_BAD_CALL_IF(expr, msg) \ |
178 | __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) |
179 | # endif |
180 | #endif |
181 | |
182 | // ABSL_ASSERT() |
183 | // |
184 | // In C++11, `assert` can't be used portably within constexpr functions. |
185 | // ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr |
186 | // functions. Example: |
187 | // |
188 | // constexpr double Divide(double a, double b) { |
189 | // return ABSL_ASSERT(b != 0), a / b; |
190 | // } |
191 | // |
192 | // This macro is inspired by |
193 | // https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ |
194 | #if defined(NDEBUG) |
195 | #define ABSL_ASSERT(expr) \ |
196 | (false ? static_cast<void>(expr) : static_cast<void>(0)) |
197 | #else |
198 | #define ABSL_ASSERT(expr) \ |
199 | (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ |
200 | : [] { assert(false && #expr); }()) // NOLINT |
201 | #endif |
202 | |
203 | #ifdef ABSL_HAVE_EXCEPTIONS |
204 | #define ABSL_INTERNAL_TRY try |
205 | #define ABSL_INTERNAL_CATCH_ANY catch (...) |
206 | #define ABSL_INTERNAL_RETHROW do { throw; } while (false) |
207 | #else // ABSL_HAVE_EXCEPTIONS |
208 | #define ABSL_INTERNAL_TRY if (true) |
209 | #define ABSL_INTERNAL_CATCH_ANY else if (false) |
210 | #define ABSL_INTERNAL_RETHROW do {} while (false) |
211 | #endif // ABSL_HAVE_EXCEPTIONS |
212 | |
213 | #endif // ABSL_BASE_MACROS_H_ |
214 | |