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