diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-18 23:07:06 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-06-18 23:07:06 +0000 |
commit | 92da5476fa903bf72ddd6d107a6ac75a9a4cfd04 (patch) | |
tree | 1ba9b93fda929860a1670e1d8941ba78ca479f8e /pw_alignment/public/pw_alignment/alignment.h | |
parent | 47562fa92998f8f4289ae9a8048349067754d52e (diff) | |
parent | 3ccc229314cb5743e7c9494cc38454ce3dd0aeb0 (diff) | |
download | pigweed-sdk-release.tar.gz |
Snap for 11987826 from 3ccc229314cb5743e7c9494cc38454ce3dd0aeb0 to sdk-releasesdk-release
Change-Id: Iff8f03146d982650561e43e92139e40b407d49a7
Diffstat (limited to 'pw_alignment/public/pw_alignment/alignment.h')
-rw-r--r-- | pw_alignment/public/pw_alignment/alignment.h | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/pw_alignment/public/pw_alignment/alignment.h b/pw_alignment/public/pw_alignment/alignment.h index 7c173bdb0..3ccdaeb06 100644 --- a/pw_alignment/public/pw_alignment/alignment.h +++ b/pw_alignment/public/pw_alignment/alignment.h @@ -14,17 +14,20 @@ #pragma once // todo-check: ignore -// TODO(fxbug.dev/120998): Once this bug is addressed, this module can likely +// TODO(fxbug.dev/42072051): Once this bug is addressed, this module can likely // be removed and we could just inline the using statements. #include <atomic> +#if __cplusplus >= 202002L +#include <bit> +#endif // __cplusplus >= 202002L #include <limits> #include <type_traits> namespace pw { -#if __cplusplus >= 202002L -using bit_ceil = std::bit_ceil; +#if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L +using std::bit_ceil; #else constexpr size_t countl_zero(size_t x) noexcept { size_t size_digits = std::numeric_limits<size_t>::digits; @@ -51,34 +54,52 @@ constexpr size_t bit_ceil(size_t x) noexcept { return 1; return size_t{1} << bit_width(size_t{x - 1}); } -#endif +#endif // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L + +/// @defgroup pw_alignment -// The NaturallyAligned class is a wrapper class for ensuring the object is -// aligned to a power of 2 bytes greater than or equal to its size. +/// @ingroup pw_alignment +/// +/// Ensures the object is naturally aligned to a power of 2 bytes greater +/// than or equal to its size. `NaturallyAligned` is a wrapper class. +/// +/// Example: +/// +/// @code{.cpp} +/// #include "pw_alignment/alignment.h" +/// +/// std::atomic<pw::NaturallyAligned<std::optional<bool>>> nat_aligned_obj; +/// @endcode template <typename T> struct [[gnu::aligned(bit_ceil(sizeof(T)))]] NaturallyAligned : public T { NaturallyAligned() : T() {} NaturallyAligned(const T& t) : T(t) {} template <class U> NaturallyAligned(const U& u) : T(u) {} - NaturallyAligned operator=(T other) { + NaturallyAligned& operator=(T other) { return T::operator=(other); } // namespace pw }; -// This is a convenience wrapper for ensuring the object held by std::atomic is -// naturally aligned. Ensuring the underlying objects's alignment is natural -// allows clang to replace libcalls to atomic functions -// (__atomic_load/store/exchange/etc) with native instructions when appropriate. -// -// Example usage: -// -// // Here std::optional<bool> has a size of 2 but alignment of 1, which would -// // normally lower to an __atomic_* libcall, but pw::NaturallyAligned in -// // std::atomic tells the compiler to align the object to 2 bytes, which -// // satisfies the requirements for replacing __atomic_* with instructions. -// pw::AlignedAtomic<std::optional<bool>> mute_enable{}; -// +/// @ingroup pw_alignment +/// +/// Ensures the object held by `std::atomic` is naturally aligned. This +/// enables the compiler to replace libcalls to atomic functions with native +/// instructions when appropriate. `AlignedAtomic` is a convenience wrapper. +/// +/// Example: +/// +/// @code{.cpp} +/// #include "pw_alignment/alignment.h" +/// +/// pw::AlignedAtomic<std::optional<bool>> mute_enable{}; +/// @endcode +/// +/// `std::optional<bool>` has a size of 2 but alignment of 1, which would +/// normally lower to an `__atomic_*` libcall, but `pw::NaturallyAligned` in +/// `std::atomic` tells the compiler to align the object to 2 bytes, which +/// satisfies the requirements for replacing `__atomic_*` with native +/// instructions. template <typename T> using AlignedAtomic = std::atomic<NaturallyAligned<T>>; |