<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Thu, Jul 3, 2025 at 12:36 PM Luc Grosheintz <<a href="mailto:luc.grosheintz@gmail.com">luc.grosheintz@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This commit implements and tests the function is_sufficiently_aligned<br>
from P2897R7.<br>
<br>
libstdc++-v3/ChangeLog:<br>
<br>
* include/bits/align.h (is_sufficiently_aligned): New function.<br>
* include/bits/version.def (is_sufficiently_aligned): Add.<br>
* include/bits/version.h: Regenerate.<br>
* include/std/memory: Add __glibcxx_want_is_sufficiently_aligned.<br>
* src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a> (is_sufficiently_aligned): Add.<br>
* testsuite/20_util/is_sufficiently_aligned/1.cc: New test.<br>
* testsuite/20_util/is_sufficiently_aligned/2.cc: New test.<br>
---<br></blockquote><div>Only one small suggestion on placement of the tests. Otherwise it looks good. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
libstdc++-v3/include/bits/align.h | 16 ++++++++++<br>
libstdc++-v3/include/bits/version.def | 8 +++++<br>
libstdc++-v3/include/bits/version.h | 10 ++++++<br>
libstdc++-v3/include/std/memory | 1 +<br>
libstdc++-v3/src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a> | 1 +<br>
.../20_util/is_sufficiently_aligned/1.cc | 31 +++++++++++++++++++<br>
.../20_util/is_sufficiently_aligned/2.cc | 7 +++++<br>
7 files changed, 74 insertions(+)<br>
create mode 100644 libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc<br>
create mode 100644 libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc<br>
<br>
diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h<br>
index 2b40c37e033..fbbe9cb1f9c 100644<br>
--- a/libstdc++-v3/include/bits/align.h<br>
+++ b/libstdc++-v3/include/bits/align.h<br>
@@ -102,6 +102,22 @@ align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept<br>
}<br>
#endif // __glibcxx_assume_aligned<br>
<br>
+#ifdef __glibcxx_is_sufficiently_aligned // C++ >= 26<br>
+ /** @brief Is @a __ptr aligned to an _Align byte boundary?<br>
+ *<br>
+ * @tparam _Align An alignment value<br>
+ * @tparam _Tp An object type<br>
+ *<br>
+ * C++26 20.2.5 [ptr.align]<br>
+ *<br>
+ * @ingroup memory<br>
+ */<br>
+ template<size_t _Align, class _Tp><br>
+ bool<br>
+ is_sufficiently_aligned(_Tp* __ptr)<br>
+ { return reinterpret_cast<__UINTPTR_TYPE__>(__ptr) % _Align == 0; }<br>
+#endif // __glibcxx_is_sufficiently_aligned<br>
+<br>
_GLIBCXX_END_NAMESPACE_VERSION<br>
} // namespace<br>
<br>
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def<br>
index f4ba501c403..a2695e67716 100644<br>
--- a/libstdc++-v3/include/bits/version.def<br>
+++ b/libstdc++-v3/include/bits/version.def<br>
@@ -732,6 +732,14 @@ ftms = {<br>
};<br>
};<br>
<br>
+ftms = {<br>
+ name = is_sufficiently_aligned;<br>
+ values = {<br>
+ v = 202411;<br>
+ cxxmin = 26;<br>
+ };<br>
+};<br>
+<br>
ftms = {<br>
name = atomic_flag_test;<br>
values = {<br>
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h<br>
index dc8ac07be16..1b17a965239 100644<br>
--- a/libstdc++-v3/include/bits/version.h<br>
+++ b/libstdc++-v3/include/bits/version.h<br>
@@ -815,6 +815,16 @@<br>
#endif /* !defined(__cpp_lib_assume_aligned) && defined(__glibcxx_want_assume_aligned) */<br>
#undef __glibcxx_want_assume_aligned<br>
<br>
+#if !defined(__cpp_lib_is_sufficiently_aligned)<br>
+# if (__cplusplus > 202302L)<br>
+# define __glibcxx_is_sufficiently_aligned 202411L<br>
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_sufficiently_aligned)<br>
+# define __cpp_lib_is_sufficiently_aligned 202411L<br>
+# endif<br>
+# endif<br>
+#endif /* !defined(__cpp_lib_is_sufficiently_aligned) && defined(__glibcxx_want_is_sufficiently_aligned) */<br>
+#undef __glibcxx_want_is_sufficiently_aligned<br>
+<br>
#if !defined(__cpp_lib_atomic_flag_test)<br>
# if (__cplusplus >= 202002L)<br>
# define __glibcxx_atomic_flag_test 201907L<br>
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory<br>
index 1da03b3ea6a..ff342ff35f3 100644<br>
--- a/libstdc++-v3/include/std/memory<br>
+++ b/libstdc++-v3/include/std/memory<br>
@@ -110,6 +110,7 @@<br>
#define __glibcxx_want_constexpr_memory<br>
#define __glibcxx_want_enable_shared_from_this<br>
#define __glibcxx_want_indirect<br>
+#define __glibcxx_want_is_sufficiently_aligned<br>
#define __glibcxx_want_make_unique<br>
#define __glibcxx_want_out_ptr<br>
#define __glibcxx_want_parallel_algorithm<br>
diff --git a/libstdc++-v3/src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a> b/libstdc++-v3/src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a><br>
index e692caaa5f9..6f4214ed3a7 100644<br>
--- a/libstdc++-v3/src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a><br>
+++ b/libstdc++-v3/src/c++23/<a href="http://std.cc.in" rel="noreferrer" target="_blank">std.cc.in</a><br>
@@ -1864,6 +1864,7 @@ export namespace std<br>
using std::allocator_arg_t;<br>
using std::allocator_traits;<br>
using std::assume_aligned;<br>
+ using std::is_sufficiently_aligned;<br>
using std::make_obj_using_allocator;<br>
using std::pointer_traits;<br>
using std::to_address;<br>
diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc<br>
new file mode 100644<br>
index 00000000000..4c2738b57db<br>
--- /dev/null<br>
+++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc<br>
@@ -0,0 +1,31 @@<br>
+// { dg-do run { target c++26 } }<br>
+<br>
+#include <memory><br>
+#include <array><br>
+#include <testsuite_hooks.h><br>
+<br>
+void<br>
+test01()<br>
+{<br>
+ constexpr size_t N = 4;<br>
+ constexpr size_t M = 2*N + 1;<br>
+ alignas(N) std::array<char, M> buffer{};<br>
+<br>
+ auto* ptr = buffer.data();<br>
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+0));<br>
+ VERIFY(std::is_sufficiently_aligned<1>(ptr+1));<br>
+<br>
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+0));<br>
+ VERIFY(!std::is_sufficiently_aligned<2>(ptr+1));<br>
+ VERIFY(std::is_sufficiently_aligned<2>(ptr+2));<br>
+<br>
+ for (size_t i = 0; i < M; ++i)<br>
+ VERIFY(std::is_sufficiently_aligned<N>(ptr + i) == (i % N == 0));<br>
+}<br>
+<br>
+int<br>
+main()<br>
+{<br>
+ test01();<br>
+ return 0;<br>
+}<br>
diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc<br>
new file mode 100644<br>
index 00000000000..8e0f4c07661<br>
--- /dev/null<br>
+++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc<br>
@@ -0,0 +1,7 @@<br>
+// { dg-do compile { target c++26 } }<br>
+<br>
+#include <memory><br>
+<br>
+#ifndef __cpp_lib_is_sufficiently_aligned<br>
+#error "Missing FTM"<br>
+#endif<br></blockquote><div>I would integrate that into 1.cc file directly. I do not think we need a separate test. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-- <br>
2.49.0<br>
<br>
</blockquote></div></div>