aboutsummaryrefslogtreecommitdiff
path: root/pw_alignment/public/pw_alignment/alignment.h
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-06-18 23:07:06 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-06-18 23:07:06 +0000
commit92da5476fa903bf72ddd6d107a6ac75a9a4cfd04 (patch)
tree1ba9b93fda929860a1670e1d8941ba78ca479f8e /pw_alignment/public/pw_alignment/alignment.h
parent47562fa92998f8f4289ae9a8048349067754d52e (diff)
parent3ccc229314cb5743e7c9494cc38454ce3dd0aeb0 (diff)
downloadpigweed-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.h61
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>>;