[PATCH v5 1/2] libstdc++: Implement is_sufficiently_aligned [PR120994]
Jonathan Wakely
jwakely.gcc@gmail.com
Thu Aug 21 07:24:07 GMT 2025
On Thu, 21 Aug 2025, 08:22 Tomasz Kaminski, <tkaminsk@redhat.com> wrote:
>
>
> On Thu, Aug 21, 2025 at 8:47 AM Tomasz Kamiński <tkaminsk@redhat.com>
> wrote:
>
>> From: Luc Grosheintz <luc.grosheintz@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 <tkaminsk@redhat.com>
>> Signed-off-by: Luc Grosheintz <luc.grosheintz@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
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250821/dcdbfe4c/attachment.htm>
More information about the Libstdc++
mailing list