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
>>
>>

Reply via email to