OK, thanks

On Thu, 21 Aug 2025, 07:47 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
> +    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