diff options
author | Luc Grosheintz <luc.grosheintz@gmail.com> | 2025-08-04 12:59:26 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-08-21 11:54:41 +0200 |
commit | 5227ec972a59417a3fb3417388ba119a025b5aa6 (patch) | |
tree | ded18301b9268362a41295809ed74f304816f876 | |
parent | cf88ed5bf20c86ca38da19358ff79a34adb4d0b5 (diff) | |
download | gcc-5227ec972a59417a3fb3417388ba119a025b5aa6.zip gcc-5227ec972a59417a3fb3417388ba119a025b5aa6.tar.gz gcc-5227ec972a59417a3fb3417388ba119a025b5aa6.tar.bz2 |
libstdc++: Implement is_sufficiently_aligned [PR120994]
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>
-rw-r--r-- | libstdc++-v3/include/bits/align.h | 17 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/version.def | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/version.h | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/std/memory | 1 | ||||
-rw-r--r-- | libstdc++-v3/src/c++23/std.cc.in | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/headers/memory/version.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc | 31 |
7 files changed, 74 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/align.h b/libstdc++-v3/include/bits/align.h index 2b40c37..6a85244 100644 --- a/libstdc++-v3/include/bits/align.h +++ b/libstdc++-v3/include/bits/align.h @@ -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__]] + 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 e9830d9..56ad9ee 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -733,6 +733,14 @@ ftms = { }; ftms = { + name = is_sufficiently_aligned; + values = { + v = 202411; + cxxmin = 26; + }; +}; + +ftms = { name = atomic_flag_test; values = { v = 201907; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 59b0cfa1..51805d2 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 763a57e..bc59622 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 aa57707..1596459 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 946955d..5366a5d 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 0000000..4c2738b --- /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; +} |