pw_polyfill: Remove two language feature polyfills
This change avoids polyfilling the constinit and constexpr keywords,
which requires implicit polyfilling. Instead, this introduces a macro
that is straightforward to use and portable.
- Remove consteval and constinit language feature polyfills.
- Provide PW_CONSTINIT macro that uses the constinit keyword or compiler
attributes to guarantee constant initialization.
- Update PW_CONSTEVAL so it always marks functions constexpr.
Change-Id: I8b582b69a54717017bd30d4a33ae148f3a754095
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/50360
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Keir Mierle <keir@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_metric/BUILD.gn b/pw_metric/BUILD.gn
index 0abc449..3fc335c 100644
--- a/pw_metric/BUILD.gn
+++ b/pw_metric/BUILD.gn
@@ -48,6 +48,7 @@
":pw_metric",
dir_pw_tokenizer,
]
+ deps = [ dir_pw_polyfill ]
}
################################################################################
diff --git a/pw_metric/global.cc b/pw_metric/global.cc
index 822a1d7..7281150 100644
--- a/pw_metric/global.cc
+++ b/pw_metric/global.cc
@@ -14,9 +14,11 @@
#include "pw_metric/global.h"
+#include "pw_polyfill/language_feature_macros.h"
+
namespace pw::metric {
-constinit IntrusiveList<Group> global_groups;
-constinit IntrusiveList<Metric> global_metrics;
+PW_CONSTINIT IntrusiveList<Group> global_groups;
+PW_CONSTINIT IntrusiveList<Metric> global_metrics;
} // namespace pw::metric
diff --git a/pw_polyfill/docs.rst b/pw_polyfill/docs.rst
index 1d35878..33b87a8 100644
--- a/pw_polyfill/docs.rst
+++ b/pw_polyfill/docs.rst
@@ -49,8 +49,6 @@
<type_traits> \*_t trait aliases partial (can expand as needed) __cpp_lib_transformation_trait_aliases
<type_traits> std::is_null_pointer full __cpp_lib_is_null_pointer
<utilty> std::integer_sequence & helpers full __cpp_lib_integer_sequence
-(language feature) consteval keyword ignored (equivalent to constexpr) __cpp_consteval
-(language feature) constinit keyword supported in clang; ignored in GCC __cpp_constinit
(language feature) static_assert with no message full __cpp_static_assert
================== ================================ ============================================ ========================================
@@ -64,6 +62,19 @@
- ``pw_polyfill/language_feature_macros.h`` -- provides macros for adapting
code to work with or without newer language features
+
+Language feature macros
+=======================
+====================== ================================ ======================================== ==========================
+Macro Feature Description Feature test macro
+====================== ================================ ======================================== ==========================
+PW_INLINE_VARIABLE inline variables inline if supported by the compiler __cpp_inline_variables
+PW_CONSTEXPR_FUNCTION relaxed constexpr function rules constexpr if relaxed rules are supported __cpp_constexpr >= 201304L
+PW_CONSTEXPR_CPP20 constexpr in C++20 constexpr if compiling for C++20 __cplusplus >= 202002L
+PW_CONSTEVAL consteval consteval if supported by the compiler __cpp_consteval
+PW_CONSTINIT constinit constinit in clang and GCC 10+ __cpp_constinit
+====================== ================================ ======================================== ==========================
+
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/standard_library_public`` and
diff --git a/pw_polyfill/language_features.h b/pw_polyfill/language_features.h
index 9527935..28f7b34 100644
--- a/pw_polyfill/language_features.h
+++ b/pw_polyfill/language_features.h
@@ -24,23 +24,6 @@
// C++11 is required for the features in this header.
#if defined(__cplusplus) && __cplusplus >= 201103L
-// If consteval is not supported, use constexpr. This does not guarantee
-// compile-time execution, but works equivalently in constant expressions.
-#ifndef __cpp_consteval
-#define consteval constexpr
-#endif // __cpp_consteval
-
-// If constinit is not supported, use a compiler attribute or omit it. If
-// omitted, the compiler may still constant initialize the variable, but there
-// is no guarantee.
-#ifndef __cpp_constinit
-#ifdef __clang__
-#define constinit [[clang::require_constant_initialization]]
-#else
-#define constinit
-#endif // __clang__
-#endif // __cpp_constinit
-
// This is an adapter for supporting static_assert with a single argument in
// C++11 or C++14. Macros don't correctly parse commas in template expressions,
// so the static_assert arguments are passed to an overloaded C++ function. The
diff --git a/pw_polyfill/public/pw_polyfill/language_feature_macros.h b/pw_polyfill/public/pw_polyfill/language_feature_macros.h
index 60f290c..4dae503 100644
--- a/pw_polyfill/public/pw_polyfill/language_feature_macros.h
+++ b/pw_polyfill/public/pw_polyfill/language_feature_macros.h
@@ -41,5 +41,16 @@
#if defined(__cpp_consteval) && __cpp_consteval >= 201811L
#define PW_CONSTEVAL consteval
#else
-#define PW_CONSTEVAL PW_CONSTEXPR_FUNCTION
+#define PW_CONSTEVAL constexpr
#endif // __cpp_consteval >= 201811L
+
+// Mark functions as constinit if supported by the compiler.
+#if defined(__cpp_constinit)
+#define PW_CONSTINIT constinit
+#elif defined(__clang__)
+#define PW_CONSTINIT [[clang::require_constant_initialization]]
+#elif __GNUC__ >= 10
+#define PW_CONSTINIT __constinit
+#else
+#define PW_CONSTINIT
+#endif // __cpp_constinit
diff --git a/pw_polyfill/test.cc b/pw_polyfill/test.cc
index 497bd3b..adbcad2 100644
--- a/pw_polyfill/test.cc
+++ b/pw_polyfill/test.cc
@@ -112,7 +112,7 @@
}
// Check that consteval is at least equivalent to constexpr.
-consteval int ConstevalFunction() { return 123; }
+PW_CONSTEVAL int ConstevalFunction() { return 123; }
static_assert(ConstevalFunction() == 123);
int c_array[5423] = {};
@@ -128,7 +128,7 @@
EXPECT_TRUE(std::data(array) == array.data());
}
-constinit bool mutable_value = true;
+PW_CONSTINIT bool mutable_value = true;
TEST(Constinit, ValueIsMutable) {
ASSERT_TRUE(mutable_value);