aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Grosheintz <luc.grosheintz@gmail.com>2025-08-04 12:59:26 +0200
committerTomasz Kamiński <tkaminsk@redhat.com>2025-08-21 11:54:41 +0200
commit5227ec972a59417a3fb3417388ba119a025b5aa6 (patch)
treeded18301b9268362a41295809ed74f304816f876
parentcf88ed5bf20c86ca38da19358ff79a34adb4d0b5 (diff)
downloadgcc-5227ec972a59417a3fb3417388ba119a025b5aa6.zip
gcc-5227ec972a59417a3fb3417388ba119a025b5aa6.tar.gz
gcc-5227ec972a59417a3fb3417388ba119a025b5aa6.tar.bz2
libstdc++: Implement is_sufficiently_aligned [PR120994]
This commit implements and tests the function is_sufficiently_aligned from P2897R7. PR libstdc++/120994 libstdc++-v3/ChangeLog: * include/bits/align.h (is_sufficiently_aligned): New function. * include/bits/version.def (is_sufficiently_aligned): Add. * include/bits/version.h: Regenerate. * include/std/memory: Add __glibcxx_want_is_sufficiently_aligned. * src/c++23/std.cc.in (is_sufficiently_aligned): Add. * testsuite/20_util/headers/memory/version.cc: Add test for __cpp_lib_is_sufficiently_aligned. * testsuite/20_util/is_sufficiently_aligned/1.cc: New test. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
-rw-r--r--libstdc++-v3/include/bits/align.h17
-rw-r--r--libstdc++-v3/include/bits/version.def8
-rw-r--r--libstdc++-v3/include/bits/version.h10
-rw-r--r--libstdc++-v3/include/std/memory1
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in3
-rw-r--r--libstdc++-v3/testsuite/20_util/headers/memory/version.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc31
7 files changed, 74 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h
index 2b40c37..6a85244 100644
--- a/libstdc++-v3/include/bits/align.h
+++ b/libstdc++-v3/include/bits/align.h
@@ -102,6 +102,23 @@ align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
}
#endif // __glibcxx_assume_aligned
+#ifdef __glibcxx_is_sufficiently_aligned // C++ >= 26
+ /** @brief Is `__ptr` aligned to an _Align byte boundary?
+ *
+ * @tparam _Align An alignment value
+ * @tparam _Tp An object type
+ *
+ * C++26 20.2.5 [ptr.align]
+ *
+ * @ingroup memory
+ */
+ template<size_t _Align, class _Tp>
+ [[nodiscard,__gnu__::__always_inline__]]
+ inline bool
+ is_sufficiently_aligned(_Tp* __ptr)
+ { return reinterpret_cast<__UINTPTR_TYPE__>(__ptr) % _Align == 0; }
+#endif // __glibcxx_is_sufficiently_aligned
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index e9830d9..56ad9ee 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -733,6 +733,14 @@ ftms = {
};
ftms = {
+ name = is_sufficiently_aligned;
+ values = {
+ v = 202411;
+ cxxmin = 26;
+ };
+};
+
+ftms = {
name = atomic_flag_test;
values = {
v = 201907;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 59b0cfa1..51805d2 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -815,6 +815,16 @@
#endif /* !defined(__cpp_lib_assume_aligned) && defined(__glibcxx_want_assume_aligned) */
#undef __glibcxx_want_assume_aligned
+#if !defined(__cpp_lib_is_sufficiently_aligned)
+# if (__cplusplus > 202302L)
+# define __glibcxx_is_sufficiently_aligned 202411L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_sufficiently_aligned)
+# define __cpp_lib_is_sufficiently_aligned 202411L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_is_sufficiently_aligned) && defined(__glibcxx_want_is_sufficiently_aligned) */
+#undef __glibcxx_want_is_sufficiently_aligned
+
#if !defined(__cpp_lib_atomic_flag_test)
# if (__cplusplus >= 202002L)
# define __glibcxx_atomic_flag_test 201907L
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 763a57e..bc59622 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -110,6 +110,7 @@
#define __glibcxx_want_constexpr_memory
#define __glibcxx_want_enable_shared_from_this
#define __glibcxx_want_indirect
+#define __glibcxx_want_is_sufficiently_aligned
#define __glibcxx_want_make_unique
#define __glibcxx_want_out_ptr
#define __glibcxx_want_parallel_algorithm
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index aa57707..1596459 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -1881,6 +1881,9 @@ export namespace std
using std::allocator_arg_t;
using std::allocator_traits;
using std::assume_aligned;
+#if __glibcxx_is_sufficiently_aligned
+ using std::is_sufficiently_aligned;
+#endif
using std::make_obj_using_allocator;
using std::pointer_traits;
using std::to_address;
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/version.cc b/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
index 946955d..5366a5d 100644
--- a/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/version.cc
@@ -10,3 +10,7 @@
#if __cpp_lib_addressof_constexpr != 201603L
# error "Feature-test macro __cpp_lib_addressof_constexpr has wrong value in <version>"
#endif
+
+#if __cplusplus > 202302L && __cpp_lib_is_sufficiently_aligned != 202411L
+# error "Feature-test macro __cpp_lib_is_sufficiently_aligned has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
new file mode 100644
index 0000000..4c2738b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
@@ -0,0 +1,31 @@
+// { dg-do run { target c++26 } }
+
+#include <memory>
+#include <array>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ constexpr size_t N = 4;
+ constexpr size_t M = 2*N + 1;
+ alignas(N) std::array<char, M> buffer{};
+
+ auto* ptr = buffer.data();
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+0));
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+1));
+
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+0));
+ VERIFY(!std::is_sufficiently_aligned<2>(ptr+1));
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+2));
+
+ for (size_t i = 0; i < M; ++i)
+ VERIFY(std::is_sufficiently_aligned<N>(ptr + i) == (i % N == 0));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}