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/attributes.h" 35 #include "absl/base/config.h" 36 #include "absl/base/optimization.h" 37 #include "absl/base/options.h" 38 #include "absl/base/port.h" 39 40 // ABSL_ARRAYSIZE() 41 // 42 // Returns the number of elements in an array as a compile-time constant, which 43 // can be used in defining new arrays. If you use this macro on a pointer by 44 // mistake, you will get a compile-time error. 45 #define ABSL_ARRAYSIZE(array) \ 46 (sizeof(::absl::macros_internal::ArraySizeHelper(array))) 47 48 namespace absl { 49 ABSL_NAMESPACE_BEGIN 50 namespace macros_internal { 51 // Note: this internal template function declaration is used by ABSL_ARRAYSIZE. 52 // The function doesn't need a definition, as we only use its type. 53 template <typename T, size_t N> 54 auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; 55 } // namespace macros_internal 56 ABSL_NAMESPACE_END 57 } // namespace absl 58 59 // ABSL_BAD_CALL_IF() 60 // 61 // Used on a function overload to trap bad calls: any call that matches the 62 // overload will cause a compile-time error. This macro uses a clang-specific 63 // "enable_if" attribute, as described at 64 // https://clang.llvm.org/docs/AttributeReference.html#enable-if 65 // 66 // Overloads which use this macro should be bracketed by 67 // `#ifdef ABSL_BAD_CALL_IF`. 68 // 69 // Example: 70 // 71 // int isdigit(int c); 72 // #ifdef ABSL_BAD_CALL_IF 73 // int isdigit(int c) 74 // ABSL_BAD_CALL_IF(c <= -1 || c > 255, 75 // "'c' must have the value of an unsigned char or EOF"); 76 // #endif // ABSL_BAD_CALL_IF 77 #if ABSL_HAVE_ATTRIBUTE(enable_if) 78 #define ABSL_BAD_CALL_IF(expr, msg) \ 79 __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) 80 #endif 81 82 // ABSL_ASSERT() 83 // 84 // In C++11, `assert` can't be used portably within constexpr functions. 85 // `assert` also generates spurious unused-symbol warnings. 86 // ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr 87 // functions, and maintains references to symbols. Example: 88 // 89 // constexpr double Divide(double a, double b) { 90 // return ABSL_ASSERT(b != 0), a / b; 91 // } 92 // 93 // This macro is inspired by 94 // https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ 95 #if defined(NDEBUG) 96 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L 97 // We use `decltype` here to avoid generating unnecessary code that the 98 // optimizer then has to optimize away. 99 // This not only improves compilation performance by reducing codegen bloat 100 // and optimization work, but also guarantees fast run-time performance without 101 // having to rely on the optimizer. 102 #define ABSL_ASSERT(expr) (decltype((expr) ? void() : void())()) 103 #else 104 // Pre-C++20, lambdas can't be inside unevaluated operands, so we're forced to 105 // rely on the optimizer. 106 #define ABSL_ASSERT(expr) (false ? ((expr) ? void() : void()) : void()) 107 #endif 108 #else 109 #define ABSL_ASSERT(expr) \ 110 (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ 111 : [] { assert(false && #expr); }()) // NOLINT 112 #endif 113 114 // `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()` 115 // aborts the program in release mode (when NDEBUG is defined). The 116 // implementation should abort the program as quickly as possible and ideally it 117 // should not be possible to ignore the abort request. 118 #define ABSL_INTERNAL_HARDENING_ABORT() \ 119 do { \ 120 ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(); \ 121 ABSL_INTERNAL_UNREACHABLE_IMPL(); \ 122 } while (false) 123 124 // ABSL_HARDENING_ASSERT() 125 // 126 // `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement 127 // runtime assertions that should be enabled in hardened builds even when 128 // `NDEBUG` is defined. 129 // 130 // When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to 131 // `ABSL_ASSERT()`. 132 // 133 // See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on 134 // hardened mode. 135 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG) 136 #define ABSL_HARDENING_ASSERT(expr) \ 137 (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ 138 : [] { ABSL_INTERNAL_HARDENING_ABORT(); }()) 139 #else 140 #define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr) 141 #endif 142 143 // ABSL_HARDENING_ASSERT_SLOW() 144 // 145 // `ABSL_HARDENING_ASSERT()` is like `ABSL_HARDENING_ASSERT()`, 146 // but specifically for assertions whose predicates are too slow 147 // to be enabled in many applications. 148 // 149 // When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT_SLOW()` is identical to 150 // `ABSL_ASSERT()`. 151 // 152 // See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on 153 // hardened mode. 154 #if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG) 155 #define ABSL_HARDENING_ASSERT_SLOW(expr) \ 156 (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ 157 : [] { ABSL_INTERNAL_HARDENING_ABORT(); }()) 158 #else 159 #define ABSL_HARDENING_ASSERT_SLOW(expr) ABSL_ASSERT(expr) 160 #endif 161 162 #ifdef ABSL_HAVE_EXCEPTIONS 163 #define ABSL_INTERNAL_TRY try 164 #define ABSL_INTERNAL_CATCH_ANY catch (...) 165 #define ABSL_INTERNAL_RETHROW do { throw; } while (false) 166 #else // ABSL_HAVE_EXCEPTIONS 167 #define ABSL_INTERNAL_TRY if (true) 168 #define ABSL_INTERNAL_CATCH_ANY else if (false) 169 #define ABSL_INTERNAL_RETHROW do {} while (false) 170 #endif // ABSL_HAVE_EXCEPTIONS 171 172 // ABSL_DEPRECATE_AND_INLINE() 173 // 174 // Marks a function or type alias as deprecated and tags it to be picked up for 175 // automated refactoring by go/cpp-inliner. It can added to inline function 176 // definitions or type aliases. It should only be used within a header file. It 177 // differs from `ABSL_DEPRECATED` in the following ways: 178 // 179 // 1. New uses of the function or type will be discouraged via Tricorder 180 // warnings. 181 // 2. If enabled via `METADATA`, automated changes will be sent out inlining the 182 // functions's body or replacing the type where it is used. 183 // 184 // For example: 185 // 186 // ABSL_DEPRECATE_AND_INLINE() inline int OldFunc(int x) { 187 // return NewFunc(x, 0); 188 // } 189 // 190 // will mark `OldFunc` as deprecated, and the go/cpp-inliner service will 191 // replace calls to `OldFunc(x)` with calls to `NewFunc(x, 0)`. Once all calls 192 // to `OldFunc` have been replaced, `OldFunc` can be deleted. 193 // 194 // See go/cpp-inliner for more information. 195 // 196 // Note: go/cpp-inliner is Google-internal service for automated refactoring. 197 // While open-source users do not have access to this service, the macro is 198 // provided for compatibility, and so that users receive deprecation warnings. 199 #if ABSL_HAVE_CPP_ATTRIBUTE(deprecated) && \ 200 ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate) 201 #define ABSL_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]] 202 #elif ABSL_HAVE_CPP_ATTRIBUTE(deprecated) 203 #define ABSL_DEPRECATE_AND_INLINE() [[deprecated]] 204 #else 205 #define ABSL_DEPRECATE_AND_INLINE() 206 #endif 207 208 // Requires the compiler to prove that the size of the given object is at least 209 // the expected amount. 210 #if ABSL_HAVE_ATTRIBUTE(diagnose_if) && ABSL_HAVE_BUILTIN(__builtin_object_size) 211 #define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N) \ 212 __attribute__((diagnose_if(__builtin_object_size(Obj, 0) < N, \ 213 "object size provably too small " \ 214 "(this would corrupt memory)", \ 215 "error"))) 216 #else 217 #define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N) 218 #endif 219 220 #endif // ABSL_BASE_MACROS_H_ 221