From d3e10fad55171d8cdce399916acbf37b2dec732b Mon Sep 17 00:00:00 2001 From: Wyatt Hepler Date: Mon, 28 Oct 2024 22:20:47 +0000 Subject: [PATCH] pw_polyfill: Make PW_CONSTINIT support mandatory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use GCC's __constinit starting from GCC 10, when it was introduced. - Because constinit is used to avoid the static initialization order fiasco, it may not be safe to compile with PW_CONSTINIT if the compiler does not support it. Fail if PW_CONSTINIT is used without compiler support. Change-Id: Ia017163dad0ff6e743174c07d4772ccfaa6a2f2e Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/243892 Reviewed-by: Taylor Cramer Lint: Lint 🤖 Commit-Queue: Wyatt Hepler Pigweed-Auto-Submit: Wyatt Hepler --- pw_polyfill/docs.rst | 5 ++++ .../pw_polyfill/language_feature_macros.h | 28 ++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pw_polyfill/docs.rst b/pw_polyfill/docs.rst index c1f9bef13c..6270d0d5a1 100644 --- a/pw_polyfill/docs.rst +++ b/pw_polyfill/docs.rst @@ -47,6 +47,11 @@ In GN, Bazel, or CMake, depend on ``$dir_pw_polyfill``, ``//pw_polyfill``, or ``pw_polyfill``, respectively, to access these features. In other build systems, add ``pw_polyfill/public`` as an include path. +API reference +------------- +.. doxygenfile:: pw_polyfill/language_feature_macros.h + :sections: define + ------------------------------------------------ Backport new C++ features to older C++ standards ------------------------------------------------ diff --git a/pw_polyfill/public/pw_polyfill/language_feature_macros.h b/pw_polyfill/public/pw_polyfill/language_feature_macros.h index 5ec395897c..6e8d82d11d 100644 --- a/pw_polyfill/public/pw_polyfill/language_feature_macros.h +++ b/pw_polyfill/public/pw_polyfill/language_feature_macros.h @@ -15,34 +15,48 @@ // Macros for using C++ features in older standards. #pragma once -// Mark functions as constexpr if C++20 or newer +/// Mark functions as `constexpr` if compiling for C++20 or newer. In C++17, +/// `PW_CONSTEXPR_CPP20` expands to nothing. +/// +/// This is primarily used for functions that rely on standard library functions +/// that only became `constexpr` in C++20 (e.g. `std::copy`). Use with caution +/// in portable code; if `constexpr` is required in C++17, use `constexpr`. #if __cplusplus >= 202002L #define PW_CONSTEXPR_CPP20 constexpr #else #define PW_CONSTEXPR_CPP20 #endif // __cpp_constexpr >= 201304L -// Mark functions as consteval if supported. +/// Mark functions as `consteval` if supported (C++20), or `constexpr` if not +/// (C++17). +/// +/// Use with caution in portable code. Calling a `consteval` function outside +/// of a constant expression is an error. #if defined(__cpp_consteval) && __cpp_consteval >= 201811L #define PW_CONSTEVAL consteval #else #define PW_CONSTEVAL constexpr #endif // __cpp_consteval >= 201811L -// Mark functions as constinit if supported by the compiler. +/// Declare a variable as `constinit`. Requires compiler-specific features if +/// `constinit` is not available. #if defined(__cpp_constinit) && __cpp_constinit >= 201907L #define PW_CONSTINIT constinit #elif defined(__clang__) #define PW_CONSTINIT [[clang::require_constant_initialization]] -#elif defined(__GNUC__) && __GNUC__ >= 13 +#elif defined(__GNUC__) && __GNUC__ >= 10 #define PW_CONSTINIT __constinit #else -#define PW_CONSTINIT +#define PW_CONSTINIT \ + static_assert(false, \ + "PW_CONSTINIT does not yet support this compiler; " \ + "implement PW_CONSTINIT for this compiler to use it."); #endif // __cpp_constinit -// nodiscard with a string literal is only available in later versions (~C++20). +/// Provides `[[nodiscard]]` with a string literal description, which is only +/// available starting in C++20. #if __cplusplus >= 202002L #define PW_NODISCARD_STR(str) [[nodiscard(str)]] #else #define PW_NODISCARD_STR(str) [[nodiscard]] -#endif +#endif // __cplusplus >= 202002L