blob: 2f6089f4c68332deff11543c0c707cfb9ebe2a6f [file] [log] [blame]
mistergc2e75482017-09-19 16:54:40 -04001//
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//
nik727338b70432019-03-08 10:27:53 -05008// https://www.apache.org/licenses/LICENSE-2.0
mistergc2e75482017-09-19 16:54:40 -04009//
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.
mistergc2e75482017-09-19 16:54:40 -040027
28#ifndef ABSL_BASE_MACROS_H_
29#define ABSL_BASE_MACROS_H_
30
Abseil Teamdedb4ee2017-10-24 10:37:49 -070031#include <cassert>
mistergc2e75482017-09-19 16:54:40 -040032#include <cstddef>
33
Abseil Teama4b757b2019-12-02 10:41:53 -080034#include "absl/base/attributes.h"
Abseil Team518f1752020-03-23 13:16:18 -070035#include "absl/base/config.h"
Abseil Team8a394b12019-05-17 10:51:37 -070036#include "absl/base/optimization.h"
mistergc2e75482017-09-19 16:54:40 -040037#include "absl/base/port.h"
38
39// ABSL_ARRAYSIZE()
40//
Abseil Teamcd95e712018-05-09 13:57:56 -070041// Returns the number of elements in an array as a compile-time constant, which
42// can be used in defining new arrays. If you use this macro on a pointer by
mistergc2e75482017-09-19 16:54:40 -040043// mistake, you will get a compile-time error.
Abseil Teamcd95e712018-05-09 13:57:56 -070044#define ABSL_ARRAYSIZE(array) \
45 (sizeof(::absl::macros_internal::ArraySizeHelper(array)))
46
mistergc2e75482017-09-19 16:54:40 -040047namespace absl {
Abseil Team1e39f862019-12-10 09:03:32 -080048ABSL_NAMESPACE_BEGIN
mistergc2e75482017-09-19 16:54:40 -040049namespace macros_internal {
Abseil Teamcd95e712018-05-09 13:57:56 -070050// Note: this internal template function declaration is used by ABSL_ARRAYSIZE.
51// The function doesn't need a definition, as we only use its type.
mistergc2e75482017-09-19 16:54:40 -040052template <typename T, size_t N>
Abseil Team7fda0992018-02-27 13:38:47 -080053auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
mistergc2e75482017-09-19 16:54:40 -040054} // namespace macros_internal
Abseil Team1e39f862019-12-10 09:03:32 -080055ABSL_NAMESPACE_END
mistergc2e75482017-09-19 16:54:40 -040056} // namespace absl
mistergc2e75482017-09-19 16:54:40 -040057
58// kLinkerInitialized
59//
60// An enum used only as a constructor argument to indicate that a variable has
61// static storage duration, and that the constructor should do nothing to its
62// state. Use of this macro indicates to the reader that it is legal to
63// declare a static instance of the class, provided the constructor is given
64// the absl::base_internal::kLinkerInitialized argument.
65//
66// Normally, it is unsafe to declare a static variable that has a constructor or
67// a destructor because invocation order is undefined. However, if the type can
68// be zero-initialized (which the loader does for static variables) into a valid
69// state and the type's destructor does not affect storage, then a constructor
70// for static initialization can be declared.
71//
72// Example:
73// // Declaration
74// explicit MyClass(absl::base_internal:LinkerInitialized x) {}
75//
76// // Invocation
77// static MyClass my_global(absl::base_internal::kLinkerInitialized);
78namespace absl {
Abseil Team1e39f862019-12-10 09:03:32 -080079ABSL_NAMESPACE_BEGIN
mistergc2e75482017-09-19 16:54:40 -040080namespace base_internal {
81enum LinkerInitialized {
82 kLinkerInitialized = 0,
83};
84} // namespace base_internal
Abseil Team1e39f862019-12-10 09:03:32 -080085ABSL_NAMESPACE_END
mistergc2e75482017-09-19 16:54:40 -040086} // namespace absl
87
88// ABSL_FALLTHROUGH_INTENDED
89//
90// Annotates implicit fall-through between switch labels, allowing a case to
91// indicate intentional fallthrough and turn off warnings about any lack of a
92// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by
93// a semicolon and can be used in most places where `break` can, provided that
94// no statements exist between it and the next switch label.
95//
96// Example:
97//
98// switch (x) {
99// case 40:
100// case 41:
101// if (truth_is_out_there) {
102// ++x;
103// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations
104// // in comments
105// } else {
106// return x;
107// }
108// case 42:
109// ...
110//
111// Notes: when compiled with clang in C++11 mode, the ABSL_FALLTHROUGH_INTENDED
112// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed
113// when performing switch labels fall-through diagnostic
114// (`-Wimplicit-fallthrough`). See clang documentation on language extensions
115// for details:
nlewyckya2e6ade2020-01-13 11:12:06 -0800116// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
mistergc2e75482017-09-19 16:54:40 -0400117//
118// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro
119// has no effect on diagnostics. In any case this macro has no effect on runtime
120// behavior and performance of code.
121#ifdef ABSL_FALLTHROUGH_INTENDED
122#error "ABSL_FALLTHROUGH_INTENDED should not be defined."
123#endif
124
125// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported.
126#if defined(__clang__) && defined(__has_warning)
127#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
128#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]]
129#endif
130#elif defined(__GNUC__) && __GNUC__ >= 7
131#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
132#endif
133
134#ifndef ABSL_FALLTHROUGH_INTENDED
135#define ABSL_FALLTHROUGH_INTENDED \
136 do { \
137 } while (0)
138#endif
139
140// ABSL_DEPRECATED()
141//
142// Marks a deprecated class, struct, enum, function, method and variable
143// declarations. The macro argument is used as a custom diagnostic message (e.g.
144// suggestion of a better alternative).
145//
Abseil Teamddf8e522019-09-19 09:27:34 -0700146// Examples:
mistergc2e75482017-09-19 16:54:40 -0400147//
148// class ABSL_DEPRECATED("Use Bar instead") Foo {...};
Abseil Teamddf8e522019-09-19 09:27:34 -0700149//
150// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...}
151//
152// template <typename T>
153// ABSL_DEPRECATED("Use DoThat() instead")
154// void DoThis();
mistergc2e75482017-09-19 16:54:40 -0400155//
156// Every usage of a deprecated entity will trigger a warning when compiled with
157// clang's `-Wdeprecated-declarations` option. This option is turned off by
Abseil Teamcf6ab6b2017-09-24 08:20:48 -0700158// default, but the warnings will be reported by clang-tidy.
Abseil Team787891a2018-01-22 13:10:49 -0800159#if defined(__clang__) && __cplusplus >= 201103L
mistergc2e75482017-09-19 16:54:40 -0400160#define ABSL_DEPRECATED(message) __attribute__((deprecated(message)))
161#endif
162
163#ifndef ABSL_DEPRECATED
164#define ABSL_DEPRECATED(message)
165#endif
166
167// ABSL_BAD_CALL_IF()
168//
169// Used on a function overload to trap bad calls: any call that matches the
170// overload will cause a compile-time error. This macro uses a clang-specific
171// "enable_if" attribute, as described at
nlewyckya2e6ade2020-01-13 11:12:06 -0800172// https://clang.llvm.org/docs/AttributeReference.html#enable-if
mistergc2e75482017-09-19 16:54:40 -0400173//
174// Overloads which use this macro should be bracketed by
175// `#ifdef ABSL_BAD_CALL_IF`.
176//
177// Example:
178//
179// int isdigit(int c);
180// #ifdef ABSL_BAD_CALL_IF
181// int isdigit(int c)
182// ABSL_BAD_CALL_IF(c <= -1 || c > 255,
183// "'c' must have the value of an unsigned char or EOF");
184// #endif // ABSL_BAD_CALL_IF
Abseil Teama4b757b2019-12-02 10:41:53 -0800185#if ABSL_HAVE_ATTRIBUTE(enable_if)
186#define ABSL_BAD_CALL_IF(expr, msg) \
187 __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
mistergc2e75482017-09-19 16:54:40 -0400188#endif
189
190// ABSL_ASSERT()
191//
192// In C++11, `assert` can't be used portably within constexpr functions.
193// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr
194// functions. Example:
195//
196// constexpr double Divide(double a, double b) {
197// return ABSL_ASSERT(b != 0), a / b;
198// }
199//
200// This macro is inspired by
201// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
202#if defined(NDEBUG)
Abseil Team666fc122019-04-04 08:13:57 -0700203#define ABSL_ASSERT(expr) \
204 (false ? static_cast<void>(expr) : static_cast<void>(0))
mistergc2e75482017-09-19 16:54:40 -0400205#else
Abseil Team666fc122019-04-04 08:13:57 -0700206#define ABSL_ASSERT(expr) \
207 (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
Abseil Teameb686c02018-06-13 11:44:15 -0700208 : [] { assert(false && #expr); }()) // NOLINT
mistergc2e75482017-09-19 16:54:40 -0400209#endif
210
Abseil Team518f1752020-03-23 13:16:18 -0700211// `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()`
212// aborts the program in release mode (when NDEBUG is defined). The
213// implementation should abort the program as quickly as possible and ideally it
214// should not be possible to ignore the abort request.
215#if ABSL_HAVE_BUILTIN(__builtin_trap) || \
216 (defined(__GNUC__) && !defined(__clang__))
217#define ABSL_INTERNAL_HARDENING_ABORT() \
218 do { \
219 __builtin_trap(); \
220 __builtin_unreachable(); \
221 } while (false)
222#else
223#define ABSL_INTERNAL_HARDENING_ABORT() abort()
224#endif
225
226// ABSL_HARDENING_ASSERT()
227//
228// `ABSL_HARDENED_ASSERT()` is like `ABSL_ASSERT()`, but used to implement
229// runtime assertions that should be enabled in hardened builds even when
230// `NDEBUG` is defined.
231//
232// When `NDEBUG` is not defined, `ABSL_HARDENED_ASSERT()` is identical to
233// `ABSL_ASSERT()`.
234//
235// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
236// hardened mode.
237#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG)
238#define ABSL_HARDENING_ASSERT(expr) \
239 (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \
240 : [] { ABSL_INTERNAL_HARDENING_ABORT(); }())
241#else
242#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr)
243#endif
244
Abseil Teama4c3fff2018-10-29 15:53:34 -0700245#ifdef ABSL_HAVE_EXCEPTIONS
246#define ABSL_INTERNAL_TRY try
247#define ABSL_INTERNAL_CATCH_ANY catch (...)
248#define ABSL_INTERNAL_RETHROW do { throw; } while (false)
249#else // ABSL_HAVE_EXCEPTIONS
250#define ABSL_INTERNAL_TRY if (true)
251#define ABSL_INTERNAL_CATCH_ANY else if (false)
252#define ABSL_INTERNAL_RETHROW do {} while (false)
253#endif // ABSL_HAVE_EXCEPTIONS
254
mistergc2e75482017-09-19 16:54:40 -0400255#endif // ABSL_BASE_MACROS_H_