pw_polyfill#

The pw_polyfill module supports compiling code against different C++ standards.

Adapt code to compile with different C++ standards#

C++ standard macro#

pw_polyfill/standard.h provides macros for checking if a C++ or C standard is supported.

PW_CXX_STANDARD_IS_SUPPORTED(std)#

Evaluates true if the provided C++ standard (98, 11, 14, 17, 20, 23) is supported by the compiler. This is a simple alternative to checking the value of the __cplusplus macro.

PW_C_STANDARD_IS_SUPPORTED(std)#

Evaluates true if the provided C standard (89, 98, 11, 17, 23) is supported by the compiler. This is a simple alternative to checking the value of the __STDC_VERSION__ macro.

Language feature macros#

pw_polyfill/language_feature_macros.h provides macros for adapting code to work with or without C++ language features.

Macro

Feature

Description

Feature test macro

PW_CONSTEXPR_CPP20

constexpr

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/public as an include path.

API reference#

Defines

PW_CONSTEXPR_CPP20#

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.

PW_CONSTEVAL#

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.

PW_CONSTINIT#

Declare a variable as constinit. Requires compiler-specific features if constinit is not available.

PW_NODISCARD_STR(str)#

Provides [[nodiscard]] with a string literal description, which is only available starting in C++20.

Backport new C++ features to older C++ standards#

Pigweed backports a few C++ features to older C++ standards. These features are provided in the pw namespace. If the features are provided by the toolchain, the pw versions are aliases of the std versions.

List of backported features#

These features are documented here, but are not implemented in pw_polyfill. See the listed Pigweed module for more information on each feature.

Header

Feature

Pigweed module and header

Polyfill name

<array>

std::to_array

pw_containers/to_array.h

pw::containers::to_array

<bit>

std::endian

pw_bytes/bit.h

pw::endian

<expected>

std::expected

pw_result/expected.h

pw::expected

<span>

std::span

pw_span/span.h

pw::span

Adapt code to compile with different C standards#

static_assert#

pw_polyfill/static_assert.h provides C23-style static_assert for older C standards. As in C23, the message argument is optional.


#include "pw_polyfill/standard.h"
#include "pw_polyfill/static_assert.h"

extern int array[3];

static_assert(ARRAY_LEN(array) == 3, "The array must contain 3 elements");

static_assert(sizeof(array) == 3 * sizeof(int));  // The message is optional.

Tip

Use pw_polyfill/static_assert.h rather than <assert.h> to provide static_assert in C. <assert.h> provides a #define static_assert _Static_assert macro prior to C23, but its static_assert does not support C23 semantics (optional message argument), and it defines the unwanted assert macro.

Zephyr#

To enable pw_polyfill for Zephyr add CONFIG_PIGWEED_POLYFILL=y to the project’s configuration.