xref: /aosp_15_r20/external/pigweed/pw_polyfill/public/pw_polyfill/language_feature_macros.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // Macros for using C++ features in older standards.
16 #pragma once
17 
18 /// Mark functions as `constexpr` if compiling for C++20 or newer. In C++17,
19 /// `PW_CONSTEXPR_CPP20` expands to nothing.
20 ///
21 /// This is primarily used for functions that rely on standard library functions
22 /// that only became `constexpr` in C++20 (e.g. `std::copy`). Use with caution
23 /// in portable code; if `constexpr` is required in C++17, use `constexpr`.
24 #if __cplusplus >= 202002L
25 #define PW_CONSTEXPR_CPP20 constexpr
26 #else
27 #define PW_CONSTEXPR_CPP20
28 #endif  // __cpp_constexpr >= 201304L
29 
30 /// Mark functions as `consteval` if supported (C++20), or `constexpr` if not
31 /// (C++17).
32 ///
33 /// Use with caution in portable code. Calling a `consteval` function outside
34 /// of a constant expression is an error.
35 #if defined(__cpp_consteval) && __cpp_consteval >= 201811L
36 #define PW_CONSTEVAL consteval
37 #else
38 #define PW_CONSTEVAL constexpr
39 #endif  // __cpp_consteval >= 201811L
40 
41 /// Declare a variable as `constinit`. Requires compiler-specific features if
42 /// `constinit` is not available.
43 #if defined(__cpp_constinit) && __cpp_constinit >= 201907L
44 #define PW_CONSTINIT constinit
45 #elif defined(__clang__)
46 #define PW_CONSTINIT [[clang::require_constant_initialization]]
47 #elif defined(__GNUC__) && __GNUC__ >= 10
48 #define PW_CONSTINIT __constinit
49 #else
50 #define PW_CONSTINIT                                                \
51   static_assert(false,                                              \
52                 "PW_CONSTINIT does not yet support this compiler; " \
53                 "implement PW_CONSTINIT for this compiler to use it.");
54 #endif  // __cpp_constinit
55 
56 /// Provides `[[nodiscard]]` with a string literal description, which is only
57 /// available starting in C++20.
58 #if __cplusplus >= 202002L
59 #define PW_NODISCARD_STR(str) [[nodiscard(str)]]
60 #else
61 #define PW_NODISCARD_STR(str) [[nodiscard]]
62 #endif  // __cplusplus >= 202002L
63