Skip to content

Commit

Permalink
pw_polyfill: Make PW_CONSTINIT support mandatory
Browse files Browse the repository at this point in the history
- 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 <[email protected]>
Lint: Lint 🤖 <[email protected]>
Commit-Queue: Wyatt Hepler <[email protected]>
Pigweed-Auto-Submit: Wyatt Hepler <[email protected]>
  • Loading branch information
255 authored and CQ Bot Account committed Oct 28, 2024
1 parent b49cd0a commit d3e10fa
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
5 changes: 5 additions & 0 deletions pw_polyfill/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------------------------------------
Expand Down
28 changes: 21 additions & 7 deletions pw_polyfill/public/pw_polyfill/language_feature_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit d3e10fa

Please sign in to comment.