[PATCH v1 1/3] libstdc++: Implement is_sufficiently_aligned.
Luc Grosheintz
luc.grosheintz@gmail.com
Thu Jul 17 09:04:41 GMT 2025
On 7/8/25 16:56, Tomasz Kaminski wrote:
> On Thu, Jul 3, 2025 at 12:36 PM Luc Grosheintz <luc.grosheintz@gmail.com>
> wrote:
>
>> This commit implements and tests the function is_sufficiently_aligned
>> from P2897R7.
>>
>> 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/is_sufficiently_aligned/1.cc: New test.
>> * testsuite/20_util/is_sufficiently_aligned/2.cc: New test.
>> ---
>>
> Only one small suggestion on placement of the tests. Otherwise it looks
> good.
>
>> libstdc++-v3/include/bits/align.h | 16 ++++++++++
>> 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 | 1 +
>> .../20_util/is_sufficiently_aligned/1.cc | 31 +++++++++++++++++++
>> .../20_util/is_sufficiently_aligned/2.cc | 7 +++++
>> 7 files changed, 74 insertions(+)
>> create mode 100644
>> libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
>> create mode 100644
>> libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
>>
>> diff --git a/libstdc++-v3/include/bits/align.h
>> b/libstdc++-v3/include/bits/align.h
>> index 2b40c37e033..fbbe9cb1f9c 100644
>> --- a/libstdc++-v3/include/bits/align.h
>> +++ b/libstdc++-v3/include/bits/align.h
>> @@ -102,6 +102,22 @@ 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 @a __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>
>> + 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 f4ba501c403..a2695e67716 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 dc8ac07be16..1b17a965239 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 1da03b3ea6a..ff342ff35f3 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 e692caaa5f9..6f4214ed3a7 100644
>> --- a/libstdc++-v3/src/c++23/std.cc.in
>> +++ b/libstdc++-v3/src/c++23/std.cc.in
>> @@ -1864,6 +1864,7 @@ export namespace std
>> using std::allocator_arg_t;
>> using std::allocator_traits;
>> using std::assume_aligned;
>> + using std::is_sufficiently_aligned;
>> using std::make_obj_using_allocator;
>> using std::pointer_traits;
>> using std::to_address;
>> 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;
>> +}
>> diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
>> b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
>> new file mode 100644
>> index 00000000000..8e0f4c07661
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
>> @@ -0,0 +1,7 @@
>> +// { dg-do compile { target c++26 } }
>> +
>> +#include <memory>
>> +
>> +#ifndef __cpp_lib_is_sufficiently_aligned
>> +#error "Missing FTM"
>> +#endif
>>
> I would integrate that into 1.cc file directly. I do not think we need a
> separate test.
Now I know they're called version.cc it's easier to find others. There's
testsuite/20_util/headers/memory/version.cc
which checks:
__cpp_lib_allocator_traits_is_always_equal
__cpp_lib_addressof_constexpr
That feels like the place to also put this one. It's use of dejagnu is
neat too:
// { dg-do preprocess { target c++17 } }
// { dg-add-options no_pch }
Now I'm tempted to adjust mdspan/version.cc accordingly.
>
>> --
>> 2.49.0
>>
>>
>
More information about the Libstdc++
mailing list