On Thu, 21 Aug 2025, 08:22 Tomasz Kaminski, <tkami...@redhat.com> wrote:
> > > On Thu, Aug 21, 2025 at 8:47 AM Tomasz Kamiński <tkami...@redhat.com> > wrote: > >> From: Luc Grosheintz <luc.groshei...@gmail.com> >> >> 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 <tkami...@redhat.com> >> Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> >> --- >> Changes in v5: >> * replaced @ __ptr with markdown >> * add nondiscard and __always_inline >> * guard export in std.cc.in >> >> libstdc++-v3/include/bits/align.h | 19 +++++++++++- >> libstdc++-v3/include/bits/version.def | 8 +++++ >> libstdc++-v3/include/bits/version.h | 10 ++++++ >> libstdc++-v3/include/std/memory | 1 + >> libstdc++-v3/src/c++23/std.cc.in | 3 ++ >> .../20_util/headers/memory/version.cc | 4 +++ >> .../20_util/is_sufficiently_aligned/1.cc | 31 +++++++++++++++++++ >> 7 files changed, 75 insertions(+), 1 deletion(-) >> create mode 100644 >> libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc >> >> diff --git a/libstdc++-v3/include/bits/align.h >> b/libstdc++-v3/include/bits/align.h >> index 2b40c37e033..12c51028927 100644 >> --- a/libstdc++-v3/include/bits/align.h >> +++ b/libstdc++-v3/include/bits/align.h >> @@ -1,4 +1,4 @@ >> -// align implementation -*- C++ -*- >> +// align implementatzion -*- C++ -*- >> >> // Copyright (C) 2014-2025 Free Software Foundation, Inc. >> // >> @@ -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__]] >> + bool >> > We also need an inline here to silence warning. Locally I have: > - bool > + inline bool > Yes, always_inline doesn't work unless the function is inline > >> + 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 e9830d9d685..56ad9ee9d4b 100644 >> --- a/libstdc++-v3/include/bits/version.def >> +++ b/libstdc++-v3/include/bits/version.def >> @@ -732,6 +732,14 @@ ftms = { >> }; >> }; >> >> +ftms = { >> + name = is_sufficiently_aligned; >> + values = { >> + v = 202411; >> + cxxmin = 26; >> + }; >> +}; >> + >> ftms = { >> name = atomic_flag_test; >> values = { >> diff --git a/libstdc++-v3/include/bits/version.h >> b/libstdc++-v3/include/bits/version.h >> index 59b0cfa1f92..51805d292f0 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 763a57ee998..bc59622dba8 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 aa577075362..15964597be7 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 946955dd212..5366a5dce8a 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 00000000000..4c2738b57db >> --- /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; >> +} >> -- >> 2.50.1 >> >>