[PATCH v1 1/3] libstdc++: Implement is_sufficiently_aligned.
Tomasz Kaminski
tkaminsk@redhat.com
Tue Jul 8 14:56:32 GMT 2025
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.
> --
> 2.49.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250708/dcb3771b/attachment.htm>
More information about the Libstdc++
mailing list