]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement is_sufficiently_aligned [PR120994]
authorLuc Grosheintz <luc.grosheintz@gmail.com>
Mon, 4 Aug 2025 10:59:26 +0000 (12:59 +0200)
committerTomasz Kamiński <tkaminsk@redhat.com>
Thu, 21 Aug 2025 09:54:41 +0000 (11:54 +0200)
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>
libstdc++-v3/include/bits/align.h
libstdc++-v3/include/bits/version.def
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/std/memory
libstdc++-v3/src/c++23/std.cc.in
libstdc++-v3/testsuite/20_util/headers/memory/version.cc
libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc [new file with mode: 0644]

index 2b40c37e0330ed180eb42ac5ef0a36461f893ec2..6a8524416d3d661c14055e198e5da41343badd42 100644 (file)
@@ -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
 
index e9830d9d685db079b151ee4f1b040ad37bdeb935..56ad9ee9d4bb8ffc862a3d2ce963037a56732988 100644 (file)
@@ -732,6 +732,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = is_sufficiently_aligned;
+  values = {
+    v = 202411;
+    cxxmin = 26;
+  };
+};
+
 ftms = {
   name = atomic_flag_test;
   values = {
index 59b0cfa1f92f9a6963fd0d9aa48e41df50c42cac..51805d292f0a260b84160f8f93f2064fb2a5e95e 100644 (file)
 #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
index 763a57ee998d0ca27e376ce570ef3ee19dd9ff2d..bc59622dba896c56d936871ad83dde85e9d53848 100644 (file)
 #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
index aa577075362edc9f976d288b62cd9265fe61e102..15964597be768cfb6a4dcffe3bb19e495206673d 100644 (file)
@@ -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;
index 946955dd2123177e2ec4956b98c272e6f9503380..5366a5dce8a23c19e11b0eabd4bf7fa5d1b35f23 100644 (file)
@@ -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 (file)
index 0000000..4c2738b
--- /dev/null
@@ -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;
+}