mirror of git://gcc.gnu.org/git/gcc.git
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>
This commit is contained in:
parent
cf88ed5bf2
commit
5227ec972a
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -732,6 +732,14 @@ ftms = {
|
|||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = is_sufficiently_aligned;
|
||||
values = {
|
||||
v = 202411;
|
||||
cxxmin = 26;
|
||||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = atomic_flag_test;
|
||||
values = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue