From 2766103a12489bcbfa75b3df0b6225a35e33543d Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Sat, 11 Jan 2025 13:22:17 -0500 Subject: [PATCH 1/5] [libc++] Implement P2897R7 aligned_accessor: An mdspan accessor expressing pointer over-alignment --- libcxx/docs/FeatureTestMacroTable.rst | 4 + libcxx/docs/Status/Cxx2cPapers.csv | 2 +- libcxx/include/CMakeLists.txt | 2 + libcxx/include/__mdspan/aligned_accessor.h | 86 ++++++++++++++ libcxx/include/__mdspan/mdspan.h | 9 +- .../__memory/is_sufficiently_aligned.h | 34 ++++++ libcxx/include/mdspan | 38 ++++++- libcxx/include/memory | 4 + libcxx/include/module.modulemap | 2 + libcxx/modules/std/mdspan.inc | 5 + libcxx/modules/std/memory.inc | 3 + .../mdspan/aligned_accessor/access.pass.cpp | 61 ++++++++++ .../byte_alignment.verify.cpp | 29 +++++ ....conversion.from.default_accessor.pass.cpp | 81 ++++++++++++++ .../aligned_accessor/ctor.conversion.pass.cpp | 104 +++++++++++++++++ .../aligned_accessor/ctor.default.pass.cpp | 56 ++++++++++ .../aligned_accessor/element_type.verify.cpp | 32 ++++++ .../mdspan/aligned_accessor/offset.pass.cpp | 61 ++++++++++ ...or.conversion.to.default_accessor.pass.cpp | 80 +++++++++++++ .../mdspan/aligned_accessor/types.pass.cpp | 70 ++++++++++++ .../is_sufficiently_aligned.pass.cpp | 105 ++++++++++++++++++ 21 files changed, 862 insertions(+), 6 deletions(-) create mode 100644 libcxx/include/__mdspan/aligned_accessor.h create mode 100644 libcxx/include/__memory/is_sufficiently_aligned.h create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp create mode 100644 libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index cfb0e5cfb129ce..ae8cbe61fd7d17 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -406,6 +406,8 @@ Status ---------------------------------------------------------------------------- ``__cpp_lib_associative_heterogeneous_insertion`` *unimplemented* ---------------------------------------------------------- ----------------- + ``__cpp_lib_aligned_accessor`` ``202411L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_atomic_min_max`` *unimplemented* ---------------------------------------------------------- ----------------- ``__cpp_lib_bind_front`` ``202306L`` @@ -450,6 +452,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_inplace_vector`` *unimplemented* ---------------------------------------------------------- ----------------- + ``__cpp_lib_is_sufficiently_aligned`` ``202411L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_is_virtual_base_of`` ``202406L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_is_within_lifetime`` *unimplemented* diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index aa896e85fcb1fe..ae1f887947fe06 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -81,7 +81,7 @@ "`P3379R0 `__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","","","" "`P0472R2 `__","Put ``std::monostate`` in ````","2024-11 (Wrocław)","","","" "`P2862R1 `__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","","" -"`P2897R7 `__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","","","" +"`P2897R7 `__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","20","" "`P3355R1 `__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","","" "`P3222R0 `__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","","" "`P3050R2 `__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index f7721b1047b81e..ad7574b8993d08 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -529,6 +529,7 @@ set(files __math/traits.h __math/trigonometric_functions.h __mbstate_t.h + __mdspan/aligned_accessor.h __mdspan/default_accessor.h __mdspan/extents.h __mdspan/layout_left.h @@ -553,6 +554,7 @@ set(files __memory/construct_at.h __memory/destruct_n.h __memory/inout_ptr.h + __memory/is_sufficiently_aligned.h __memory/noexcept_move_assign_container.h __memory/out_ptr.h __memory/pointer_traits.h diff --git a/libcxx/include/__mdspan/aligned_accessor.h b/libcxx/include/__mdspan/aligned_accessor.h new file mode 100644 index 00000000000000..441c144c11aebb --- /dev/null +++ b/libcxx/include/__mdspan/aligned_accessor.h @@ -0,0 +1,86 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Kokkos v. 4.0 +// Copyright (2022) National Technology & Engineering +// Solutions of Sandia, LLC (NTESS). +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H +#define _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__memory/assume_aligned.h> +#include <__type_traits/is_abstract.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/remove_const.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 26 + +template +struct aligned_accessor { + static_assert(_ByteAlignment != 0 && (_ByteAlignment & (_ByteAlignment - 1)) == 0, + "aligned_accessor: byte alignment must be a power of two"); + static_assert(_ByteAlignment >= alignof(_ElementType), "aligned_accessor: insufficient byte alignment"); + static_assert(!is_array_v<_ElementType>, "aligned_accessor: template argument may not be an array type"); + static_assert(!is_abstract_v<_ElementType>, "aligned_accessor: template argument may not be an abstract class"); + + using offset_policy = default_accessor<_ElementType>; + using element_type = _ElementType; + using reference = _ElementType&; + using data_handle_type = _ElementType*; + + static constexpr size_t byte_alignment = _ByteAlignment; + + _LIBCPP_HIDE_FROM_ABI constexpr aligned_accessor() noexcept = default; + + template + requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]> && _OtherByteAlignment >= byte_alignment) + _LIBCPP_HIDE_FROM_ABI constexpr aligned_accessor(aligned_accessor<_OtherElementType, _OtherByteAlignment>) noexcept {} + + template + requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]>) + _LIBCPP_HIDE_FROM_ABI explicit constexpr aligned_accessor(default_accessor<_OtherElementType>) noexcept {} + + template + requires(is_convertible_v) + _LIBCPP_HIDE_FROM_ABI constexpr operator default_accessor<_OtherElementType>() const noexcept { + return {}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr reference access(data_handle_type __p, size_t __i) const noexcept { + return std::assume_aligned(__p)[__i]; + } + + _LIBCPP_HIDE_FROM_ABI constexpr typename offset_policy::data_handle_type + offset(data_handle_type __p, size_t __i) const noexcept { + return std::assume_aligned(__p) + __i; + } +}; + +#endif // _LIBCPP_STD_VER >= 26 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H diff --git a/libcxx/include/__mdspan/mdspan.h b/libcxx/include/__mdspan/mdspan.h index 3f9b35b185b167..ef8db9f1f9789a 100644 --- a/libcxx/include/__mdspan/mdspan.h +++ b/libcxx/include/__mdspan/mdspan.h @@ -20,6 +20,7 @@ #include <__assert> #include <__config> #include <__fwd/mdspan.h> +#include <__mdspan/aligned_accessor.h> #include <__mdspan/default_accessor.h> #include <__mdspan/extents.h> #include <__type_traits/extent.h> @@ -266,13 +267,13 @@ class mdspan { # if _LIBCPP_STD_VER >= 26 template requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0)) -explicit mdspan(_ElementType*, - _OtherIndexTypes...) -> mdspan<_ElementType, extents...>>; +explicit mdspan(_ElementType*, _OtherIndexTypes...) + -> mdspan<_ElementType, extents...>>; # else template requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0)) -explicit mdspan(_ElementType*, - _OtherIndexTypes...) -> mdspan<_ElementType, dextents>; +explicit mdspan(_ElementType*, _OtherIndexTypes...) + -> mdspan<_ElementType, dextents>; # endif template diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h new file mode 100644 index 00000000000000..4280920cabb4bc --- /dev/null +++ b/libcxx/include/__memory/is_sufficiently_aligned.h @@ -0,0 +1,34 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H +#define _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H + +#include <__config> +#include <__cstddef/size_t.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 26 + +template +_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) { + return reinterpret_cast(__ptr) % _Alignment == 0; +} + +#endif // _LIBCPP_STD_VER >= 26 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H diff --git a/libcxx/include/mdspan b/libcxx/include/mdspan index a67ed1834e3bde..61f1b210dd03af 100644 --- a/libcxx/include/mdspan +++ b/libcxx/include/mdspan @@ -33,10 +33,14 @@ namespace std { template class default_accessor; + // [mdspan.accessor.aligned], class template aligned_accessor + template + class aligned_accessor; // since C++26 + // [mdspan.mdspan], class template mdspan template> - class mdspan; // not implemented yet + class mdspan; } // extents synopsis @@ -269,6 +273,38 @@ namespace std { }; } +// aligned_accessor synopsis + +namespace std { + template + struct aligned_accessor { + using offset_policy = default_accessor; + using element_type = ElementType; + using reference = ElementType&; + using data_handle_type = ElementType*; + + static constexpr size_t byte_alignment = ByteAlignment; + + constexpr aligned_accessor() noexcept = default; + + template + constexpr aligned_accessor( + aligned_accessor) noexcept; + + template + explicit constexpr aligned_accessor( + default_accessor) noexcept; + + template + constexpr operator default_accessor() const noexcept; + + constexpr reference access(data_handle_type p, size_t i) const noexcept; + + constexpr typename offset_policy::data_handle_type + offset(data_handle_type p, size_t i) const noexcept; + }; +} + // mdspan synopsis namespace std { diff --git a/libcxx/include/memory b/libcxx/include/memory index fc62606ea0fd33..a6400bd29f4437 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -912,6 +912,9 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); template [[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20 +template + bool is_sufficiently_aligned(T* ptr); // since C++26 + // [out.ptr.t], class template out_ptr_t template class out_ptr_t; // since c++23 @@ -945,6 +948,7 @@ template # include <__memory/allocator_traits.h> # include <__memory/auto_ptr.h> # include <__memory/inout_ptr.h> +# include <__memory/is_sufficiently_aligned.h> # include <__memory/out_ptr.h> # include <__memory/pointer_traits.h> # include <__memory/raw_storage_iterator.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 07ab5649ae45cb..c4beb2dfa4f383 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1504,6 +1504,7 @@ module std [system] { } module mdspan { + module aligned_accessor { header "__mdspan/aligned_accessor.h" } module default_accessor { header "__mdspan/default_accessor.h" } module extents { header "__mdspan/extents.h" } module fwd { header "__fwd/mdspan.h" } @@ -1539,6 +1540,7 @@ module std [system] { module destruct_n { header "__memory/destruct_n.h" } module fwd { header "__fwd/memory.h" } module inout_ptr { header "__memory/inout_ptr.h" } + module is_sufficiently_aligned { header "__memory/is_sufficiently_aligned.h" } module noexcept_move_assign_container { header "__memory/noexcept_move_assign_container.h" } module out_ptr { header "__memory/out_ptr.h" } module pointer_traits { header "__memory/pointer_traits.h" } diff --git a/libcxx/modules/std/mdspan.inc b/libcxx/modules/std/mdspan.inc index 5e65993383cdc0..c8cc78badb7d59 100644 --- a/libcxx/modules/std/mdspan.inc +++ b/libcxx/modules/std/mdspan.inc @@ -28,6 +28,11 @@ export namespace std { // [mdspan.accessor.default], class template default_accessor using std::default_accessor; +# if _LIBCPP_STD_VER >= 26 + // [mdspan.accessor.aligned], class template aligned_accessor + using std::aligned_accessor; +# endif // _LIBCPP_STD_VER >= 26 + // [mdspan.mdspan], class template mdspan using std::mdspan; #endif // _LIBCPP_STD_VER >= 23 diff --git a/libcxx/modules/std/memory.inc b/libcxx/modules/std/memory.inc index 82056e426d06c9..c25e9e3443e9cf 100644 --- a/libcxx/modules/std/memory.inc +++ b/libcxx/modules/std/memory.inc @@ -17,6 +17,9 @@ export namespace std { // [ptr.align], pointer alignment using std::align; using std::assume_aligned; +#if _LIBCPP_STD_VER >= 26 + using std::is_sufficiently_aligned; +#endif // [obj.lifetime], explicit lifetime management // using std::start_lifetime_as; diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp new file mode 100644 index 00000000000000..145dc79eda73d4 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// constexpr reference access(data_handle_type p, size_t i) const noexcept; +// +// Effects: Equivalent to: return assume_aligned(p)[i]; + +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +template +constexpr void test_access() { + ElementPool, 10 + N> data; + T* ptr = data.get_ptr(); + std::aligned_accessor acc; + for (size_t i = 0; i < 10 + N; i++) { + if (reinterpret_cast(ptr + i) % N == 0) { + std::same_as::reference> decltype(auto) x = acc.access(ptr, i); + ASSERT_NOEXCEPT(acc.access(ptr, i)); + assert(&x == ptr + i); + } + } +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(T); + test_access(); + test_access(); + test_access(); + test_access(); + test_access(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + return true; +} + +int main(int, char**) { + test(); + //static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp new file mode 100644 index 00000000000000..fbc8386a72dede --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp @@ -0,0 +1,29 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// template +// class aligned_accessor; + +// ByteAlignement is required to be a power of two and greater or equal to alignof(ElementType). + +#include + +void not_power_of_two() { + // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: byte alignment must be a power of two}} + [[maybe_unused]] std::aligned_accessor acc; +} + +struct alignas(8) S {}; + +void insufficiently_aligned() { + // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: insufficient byte alignment}} + [[maybe_unused]] std::aligned_accessor acc; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp new file mode 100644 index 00000000000000..339c12bb7c6c54 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// +// +// template +// explicit constexpr aligned_accessor( +// default_accessor) noexcept {} +// +// Constraints: is_convertible_v is true. + +#include +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +struct Base {}; +struct Derived : public Base {}; + +template +constexpr void test_conversion() { + std::default_accessor from; + ASSERT_NOEXCEPT(std::aligned_accessor(from)); + [[maybe_unused]] std::aligned_accessor to(from); + // check that the constructor is explicit + static_assert(std::is_nothrow_constructible_v, std::default_accessor>); + static_assert(!std::is_convertible_v, std::aligned_accessor>); +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(To); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + + // char is convertible to int, but accessors are not + static_assert(!std::is_constructible_v, std::default_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, std::default_accessor>); + // MinimalElementType is constructible from int, but accessors should not be convertible + static_assert(!std::is_constructible_v, std::default_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, + std::default_accessor>); + // don't allow conversion from Base to Derived + static_assert(!std::is_constructible_v, std::default_accessor>); + // don't allow conversion from Derived to Base + static_assert(!std::is_constructible_v, std::default_accessor>); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp new file mode 100644 index 00000000000000..0cdfc97dea0aae --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// +// +// template +// constexpr aligned_accessor(aligned_accessor) noexcept {} +// +// Constraints: +// - is_convertible_v is true. +// - OtherByteAlignment >= byte_alignment is true. + +#include +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +struct Base {}; +struct Derived : public Base {}; + +template +constexpr void test_conversion() { + std::aligned_accessor acc_from; + ASSERT_NOEXCEPT(std::aligned_accessor(acc_from)); + [[maybe_unused]] std::aligned_accessor acc_to(acc_from); +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(From); + static_assert(N == alignof(To)); + + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + + test_conversion(); + test_conversion(); + test_conversion(); + + test_conversion(); + test_conversion(); + + test_conversion(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + + // char is convertible to int, but accessors are not + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from less to more alignment + static_assert(!std::is_constructible_v, std::aligned_accessor>); + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // MinimalElementType is constructible from int, but accessors should not be convertible + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, + std::aligned_accessor>); + // don't allow conversion from Base to Derived + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from Derived to Base + static_assert(!std::is_constructible_v, std::aligned_accessor>); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp new file mode 100644 index 00000000000000..4e0b4314c51687 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// Test default construction: +// +// constexpr aligned_accessor() noexcept = default; + +#include +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +template +constexpr void test_construction() { + ASSERT_NOEXCEPT(std::aligned_accessor{}); + [[maybe_unused]] std::aligned_accessor acc; + static_assert(std::is_trivially_default_constructible_v>); +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(T); + test_construction(); + test_construction(); + test_construction(); + test_construction(); + test_construction(); + test_construction(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp new file mode 100644 index 00000000000000..91510a99aeec9a --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp @@ -0,0 +1,32 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// template +// class aligned_accessor; + +// ElementType is required to be a complete object type that is neither an abstract class type nor an array type. + +#include + +class AbstractClass { +public: + virtual void method() = 0; +}; + +void not_abstract_class() { + // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an abstract class}} + [[maybe_unused]] std::aligned_accessor acc; +} + +void not_array_type() { + // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an array type}} + [[maybe_unused]] std::aligned_accessor acc; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp new file mode 100644 index 00000000000000..de6d2c6ebf121c --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const noexcept; +// +// Effects: Equivalent to: return assume_aligned(p) + i; + +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +template +constexpr void test_offset() { + ElementPool, 10 + N> data; + T* ptr = data.get_ptr(); + std::aligned_accessor acc; + for (size_t i = 0; i < 10 + N; i++) { + if (reinterpret_cast(ptr + i) % N == 0) { + static_assert(std::is_same_v::data_handle_type>); + ASSERT_NOEXCEPT(acc.offset(ptr, i)); + assert(acc.offset(ptr, i) == ptr + i); + } + } +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(T); + test_offset(); + test_offset(); + test_offset(); + test_offset(); + test_offset(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + return true; +} + +int main(int, char**) { + test(); + //static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp new file mode 100644 index 00000000000000..5b72718c89ec2a --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// +// +// template +// constexpr operator default_accessor() const noexcept; +// +// Constraints: is_convertible_v is true. + +#include +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +struct Base {}; +struct Derived : public Base {}; + +template +constexpr void test_conversion() { + std::aligned_accessor from; + ASSERT_NOEXCEPT(std::default_accessor(from)); + [[maybe_unused]] std::default_accessor to(from); + // check that the conversion is implicit + static_assert(std::is_nothrow_convertible_v, std::default_accessor>); + static_assert(std::is_nothrow_constructible_v, std::aligned_accessor>); +} + +template +constexpr void test_it() { + constexpr size_t N = alignof(From); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); +} + +constexpr bool test() { + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + test_it(); + + // char is convertible to int, but accessors are not + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // MinimalElementType is constructible from int, but accessors should not be convertible + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from const elements to non-const + static_assert(!std::is_constructible_v, + std::aligned_accessor>); + // don't allow conversion from Base to Derived + static_assert(!std::is_constructible_v, std::aligned_accessor>); + // don't allow conversion from Derived to Base + static_assert(!std::is_constructible_v, std::aligned_accessor>); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp new file mode 100644 index 00000000000000..98de91e20c6392 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// + +// template +// struct aligned_accessor { +// using offset_policy = default_accessor; +// using element_type = ElementType; +// using reference = ElementType&; +// using data_handle_type = ElementType*; +// +// static constexpr size_t byte_alignment = ByteAlignment; +// +// ... +// }; +// +// Each specialization of aligned_accessor is a trivially copyable type that models semiregular. + +#include +#include +#include +#include + +#include "test_macros.h" + +#include "../MinimalElementType.h" + +template +void test_types() { + using A = std::aligned_accessor; + ASSERT_SAME_TYPE(typename A::offset_policy, std::default_accessor); + ASSERT_SAME_TYPE(typename A::element_type, T); + ASSERT_SAME_TYPE(typename A::reference, T&); + ASSERT_SAME_TYPE(typename A::data_handle_type, T*); + + ASSERT_SAME_TYPE(decltype(A::byte_alignment), const size_t); + static_assert(A::byte_alignment == N); + + static_assert(std::semiregular); + static_assert(std::is_trivially_copyable_v); + + LIBCPP_STATIC_ASSERT(std::is_empty_v); +} + +template +constexpr void test() { + constexpr size_t N = alignof(T); + test_types(); + test_types(); + test_types(); + test_types(); + test_types(); + test_types(); +} + +int main(int, char**) { + test(); + test(); + test(); + test(); + return 0; +} diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp new file mode 100644 index 00000000000000..38ca87a3a1771a --- /dev/null +++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// #include + +// template +// bool is_sufficiently_aligned(T* ptr); +// +// + +#include +#include +#include + +#include "test_macros.h" + +template +constexpr void test_is_sufficiently_aligned() { + constexpr std::size_t N = alignof(T); + + alignas(8 * N) std::remove_cv_t buf[5]; + + assert(std::is_sufficiently_aligned(&buf[0])); + assert(std::is_sufficiently_aligned<2 * N>(&buf[0])); + assert(std::is_sufficiently_aligned<4 * N>(&buf[0])); + assert(std::is_sufficiently_aligned<8 * N>(&buf[0])); + + assert(std::is_sufficiently_aligned(&buf[1])); + assert(!std::is_sufficiently_aligned<2 * N>(&buf[1])); + assert(!std::is_sufficiently_aligned<4 * N>(&buf[1])); + assert(!std::is_sufficiently_aligned<8 * N>(&buf[1])); + + assert(std::is_sufficiently_aligned(&buf[2])); + assert(std::is_sufficiently_aligned<2 * N>(&buf[2])); + assert(!std::is_sufficiently_aligned<4 * N>(&buf[2])); + assert(!std::is_sufficiently_aligned<8 * N>(&buf[2])); + + assert(std::is_sufficiently_aligned(&buf[3])); + assert(!std::is_sufficiently_aligned<2 * N>(&buf[3])); + assert(!std::is_sufficiently_aligned<4 * N>(&buf[3])); + assert(!std::is_sufficiently_aligned<8 * N>(&buf[3])); + + assert(std::is_sufficiently_aligned(&buf[4])); + assert(std::is_sufficiently_aligned<2 * N>(&buf[4])); + assert(std::is_sufficiently_aligned<4 * N>(&buf[4])); + assert(!std::is_sufficiently_aligned<8 * N>(&buf[4])); +} + +template +constexpr void check(T* p) { + ASSERT_SAME_TYPE(bool, decltype(std::is_sufficiently_aligned(p))); + test_is_sufficiently_aligned(); + test_is_sufficiently_aligned(); +} + +struct S {}; +struct alignas(4) S4 {}; +struct alignas(8) S8 {}; +struct alignas(16) S16 {}; +struct alignas(32) S32 {}; +struct alignas(64) S64 {}; +struct alignas(128) S128 {}; + +constexpr bool tests() { + char c; + int i; + long l; + double d; + long double ld; + check(&c); + check(&i); + check(&l); + check(&d); + check(&ld); + + S s; + S4 s4; + S8 s8; + S16 s16; + S32 s32; + S64 s64; + S128 s128; + check(&s); + check(&s4); + check(&s8); + check(&s16); + check(&s32); + check(&s64); + check(&s128); + + return true; +} + +int main(int, char**) { + tests(); + + return 0; +} From e36bc1cc588e9c668202e789ee3580819d0c438d Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Sat, 11 Jan 2025 21:42:50 -0500 Subject: [PATCH 2/5] Run the generate scripts --- libcxx/docs/FeatureTestMacroTable.rst | 4 +- libcxx/include/version | 4 ++ .../mdspan.version.compile.pass.cpp | 28 ++++++++++ .../memory.version.compile.pass.cpp | 28 ++++++++++ .../version.version.compile.pass.cpp | 56 +++++++++++++++++++ .../generate_feature_test_macro_components.py | 10 ++++ 6 files changed, 128 insertions(+), 2 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index ae8cbe61fd7d17..462b94bc6bc058 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -404,10 +404,10 @@ Status ---------------------------------------------------------- ----------------- **C++26** ---------------------------------------------------------------------------- - ``__cpp_lib_associative_heterogeneous_insertion`` *unimplemented* - ---------------------------------------------------------- ----------------- ``__cpp_lib_aligned_accessor`` ``202411L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_associative_heterogeneous_insertion`` *unimplemented* + ---------------------------------------------------------- ----------------- ``__cpp_lib_atomic_min_max`` *unimplemented* ---------------------------------------------------------- ----------------- ``__cpp_lib_bind_front`` ``202306L`` diff --git a/libcxx/include/version b/libcxx/include/version index f5b5e7a906f504..b81bc3458116b3 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -16,6 +16,7 @@ Macro name Value Headers __cpp_lib_adaptor_iterator_pair_constructor 202106L __cpp_lib_addressof_constexpr 201603L +__cpp_lib_aligned_accessor 202411L __cpp_lib_allocate_at_least 202302L __cpp_lib_allocator_traits_is_always_equal 201411L @@ -145,6 +146,7 @@ __cpp_lib_is_nothrow_convertible 201806L __cpp_lib_is_null_pointer 201309L __cpp_lib_is_pointer_interconvertible 201907L __cpp_lib_is_scoped_enum 202011L +__cpp_lib_is_sufficiently_aligned 202411L __cpp_lib_is_swappable 201603L __cpp_lib_is_virtual_base_of 202406L __cpp_lib_is_within_lifetime 202306L @@ -523,6 +525,7 @@ __cpp_lib_void_t 201411L #endif #if _LIBCPP_STD_VER >= 26 +# define __cpp_lib_aligned_accessor 202411L // # define __cpp_lib_associative_heterogeneous_insertion 202306L // # define __cpp_lib_atomic_min_max 202403L # undef __cpp_lib_bind_front @@ -551,6 +554,7 @@ __cpp_lib_void_t 201411L // # define __cpp_lib_generate_random 202403L // # define __cpp_lib_hazard_pointer 202306L // # define __cpp_lib_inplace_vector 202406L +# define __cpp_lib_is_sufficiently_aligned 202411L # if __has_builtin(__builtin_is_virtual_base_of) # define __cpp_lib_is_virtual_base_of 202406L # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp index 64d1c99b223f42..dbba48047949d9 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp @@ -16,6 +16,7 @@ // Test the feature test macros defined by /* Constant Value + __cpp_lib_aligned_accessor 202411L [C++26] __cpp_lib_freestanding_mdspan 202311L [C++26] __cpp_lib_mdspan 202207L [C++23] 202406L [C++26] @@ -27,6 +28,10 @@ #if TEST_STD_VER < 14 +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should not be defined before c++26" # endif @@ -41,6 +46,10 @@ #elif TEST_STD_VER == 14 +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should not be defined before c++26" # endif @@ -55,6 +64,10 @@ #elif TEST_STD_VER == 17 +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should not be defined before c++26" # endif @@ -69,6 +82,10 @@ #elif TEST_STD_VER == 20 +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should not be defined before c++26" # endif @@ -83,6 +100,10 @@ #elif TEST_STD_VER == 23 +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should not be defined before c++26" # endif @@ -100,6 +121,13 @@ #elif TEST_STD_VER > 23 +# ifndef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should be defined in c++26" +# endif +# if __cpp_lib_aligned_accessor != 202411L +# error "__cpp_lib_aligned_accessor should have the value 202411L in c++26" +# endif + # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_freestanding_mdspan # error "__cpp_lib_freestanding_mdspan should be defined in c++26" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp index 0094bed44be071..5d2ce6042bf6bd 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp @@ -25,6 +25,7 @@ __cpp_lib_constexpr_memory 201811L [C++20] 202202L [C++23] __cpp_lib_enable_shared_from_this 201603L [C++17] + __cpp_lib_is_sufficiently_aligned 202411L [C++26] __cpp_lib_make_unique 201304L [C++14] __cpp_lib_out_ptr 202106L [C++23] 202311L [C++26] @@ -78,6 +79,10 @@ # error "__cpp_lib_enable_shared_from_this should not be defined before c++17" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifdef __cpp_lib_make_unique # error "__cpp_lib_make_unique should not be defined before c++14" # endif @@ -152,6 +157,10 @@ # error "__cpp_lib_enable_shared_from_this should not be defined before c++17" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_make_unique # error "__cpp_lib_make_unique should be defined in c++14" # endif @@ -241,6 +250,10 @@ # error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_make_unique # error "__cpp_lib_make_unique should be defined in c++17" # endif @@ -351,6 +364,10 @@ # error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_make_unique # error "__cpp_lib_make_unique should be defined in c++20" # endif @@ -473,6 +490,10 @@ # error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_make_unique # error "__cpp_lib_make_unique should be defined in c++23" # endif @@ -598,6 +619,13 @@ # error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26" # endif +# ifndef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should be defined in c++26" +# endif +# if __cpp_lib_is_sufficiently_aligned != 202411L +# error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26" +# endif + # ifndef __cpp_lib_make_unique # error "__cpp_lib_make_unique should be defined in c++26" # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 7c03955df681d5..a8614245028ab7 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -18,6 +18,7 @@ /* Constant Value __cpp_lib_adaptor_iterator_pair_constructor 202106L [C++23] __cpp_lib_addressof_constexpr 201603L [C++17] + __cpp_lib_aligned_accessor 202411L [C++26] __cpp_lib_allocate_at_least 202302L [C++23] __cpp_lib_allocator_traits_is_always_equal 201411L [C++17] __cpp_lib_any 201606L [C++17] @@ -132,6 +133,7 @@ __cpp_lib_is_null_pointer 201309L [C++14] __cpp_lib_is_pointer_interconvertible 201907L [C++20] __cpp_lib_is_scoped_enum 202011L [C++23] + __cpp_lib_is_sufficiently_aligned 202411L [C++26] __cpp_lib_is_swappable 201603L [C++17] __cpp_lib_is_virtual_base_of 202406L [C++26] __cpp_lib_is_within_lifetime 202306L [C++26] @@ -264,6 +266,10 @@ # error "__cpp_lib_addressof_constexpr should not be defined before c++17" # endif +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should not be defined before c++23" # endif @@ -704,6 +710,10 @@ # error "__cpp_lib_is_scoped_enum should not be defined before c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifdef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should not be defined before c++17" # endif @@ -1126,6 +1136,10 @@ # error "__cpp_lib_addressof_constexpr should not be defined before c++17" # endif +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should not be defined before c++23" # endif @@ -1590,6 +1604,10 @@ # error "__cpp_lib_is_scoped_enum should not be defined before c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifdef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should not be defined before c++17" # endif @@ -2063,6 +2081,10 @@ # error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17" # endif +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should not be defined before c++23" # endif @@ -2611,6 +2633,10 @@ # error "__cpp_lib_is_scoped_enum should not be defined before c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should be defined in c++17" # endif @@ -3195,6 +3221,10 @@ # error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20" # endif +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifdef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should not be defined before c++23" # endif @@ -3914,6 +3944,10 @@ # error "__cpp_lib_is_scoped_enum should not be defined before c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should be defined in c++20" # endif @@ -4594,6 +4628,10 @@ # error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23" # endif +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + # ifndef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should be defined in c++23" # endif @@ -5388,6 +5426,10 @@ # error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23" # endif +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + # ifndef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should be defined in c++23" # endif @@ -6215,6 +6257,13 @@ # error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26" # endif +# ifndef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should be defined in c++26" +# endif +# if __cpp_lib_aligned_accessor != 202411L +# error "__cpp_lib_aligned_accessor should have the value 202411L in c++26" +# endif + # ifndef __cpp_lib_allocate_at_least # error "__cpp_lib_allocate_at_least should be defined in c++26" # endif @@ -7201,6 +7250,13 @@ # error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26" # endif +# ifndef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should be defined in c++26" +# endif +# if __cpp_lib_is_sufficiently_aligned != 202411L +# error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26" +# endif + # ifndef __cpp_lib_is_swappable # error "__cpp_lib_is_swappable should be defined in c++26" # endif diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index dae827f5de50c2..e35e34bbdd76bc 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -89,6 +89,11 @@ def add_version_header(tc): "values": {"c++17": 201603}, "headers": ["memory"], }, + { + "name": "__cpp_lib_aligned_accessor", + "values": {"c++26": 202411}, + "headers": ["mdspan"], + }, { "name": "__cpp_lib_allocate_at_least", "values": { @@ -781,6 +786,11 @@ def add_version_header(tc): "values": {"c++23": 202011}, "headers": ["type_traits"], }, + { + "name": "__cpp_lib_is_sufficiently_aligned", + "values": {"c++26": 202411}, + "headers": ["memory"], + }, { "name": "__cpp_lib_is_swappable", "values": {"c++17": 201603}, From 1c57f2058899cc9ff5f3ecab929a0fe9180464fc Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Sun, 12 Jan 2025 21:49:31 -0500 Subject: [PATCH 3/5] Add missing header include for default_accessor --- libcxx/include/__mdspan/aligned_accessor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__mdspan/aligned_accessor.h b/libcxx/include/__mdspan/aligned_accessor.h index 441c144c11aebb..2b8d4c52d87374 100644 --- a/libcxx/include/__mdspan/aligned_accessor.h +++ b/libcxx/include/__mdspan/aligned_accessor.h @@ -19,6 +19,7 @@ #include <__config> #include <__cstddef/size_t.h> +#include <__mdspan/default_accessor.h> #include <__memory/assume_aligned.h> #include <__type_traits/is_abstract.h> #include <__type_traits/is_array.h> From 68ea16753e8303d8015bec1638555f359b52c495 Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Sun, 12 Jan 2025 23:53:39 -0500 Subject: [PATCH 4/5] Missing header includes in tests --- .../views/mdspan/aligned_accessor/access.pass.cpp | 2 ++ .../views/mdspan/aligned_accessor/offset.pass.cpp | 6 ++++-- .../memory/ptr.align/is_sufficiently_aligned.pass.cpp | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp index 145dc79eda73d4..40ec85fe56a4dd 100644 --- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include "test_macros.h" diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp index de6d2c6ebf121c..64e37fd7344b27 100644 --- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include "test_macros.h" @@ -29,9 +31,9 @@ constexpr void test_offset() { std::aligned_accessor acc; for (size_t i = 0; i < 10 + N; i++) { if (reinterpret_cast(ptr + i) % N == 0) { - static_assert(std::is_same_v::data_handle_type>); + std::same_as::data_handle_type> decltype(auto) x = acc.offset(ptr, i); ASSERT_NOEXCEPT(acc.offset(ptr, i)); - assert(acc.offset(ptr, i) == ptr + i); + assert(x == ptr + i); } } } diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp index 38ca87a3a1771a..4616018ef87977 100644 --- a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp +++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "test_macros.h" From 1db762c06622806e15ff5fd65b7cfc4bdd607999 Mon Sep 17 00:00:00 2001 From: Damien L-G Date: Mon, 13 Jan 2025 13:12:29 -0500 Subject: [PATCH 5/5] Fix access and offset tests Align the pointer and check 10 elements --- .../views/mdspan/aligned_accessor/access.pass.cpp | 15 ++++++++++----- .../views/mdspan/aligned_accessor/offset.pass.cpp | 15 ++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp index 40ec85fe56a4dd..70ccaff779c515 100644 --- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp @@ -28,14 +28,19 @@ template constexpr void test_access() { ElementPool, 10 + N> data; T* ptr = data.get_ptr(); - std::aligned_accessor acc; - for (size_t i = 0; i < 10 + N; i++) { + // align ptr + for (size_t i = 0; i < N; ++i) { if (reinterpret_cast(ptr + i) % N == 0) { - std::same_as::reference> decltype(auto) x = acc.access(ptr, i); - ASSERT_NOEXCEPT(acc.access(ptr, i)); - assert(&x == ptr + i); + ptr += i; + break; } } + std::aligned_accessor acc; + for (size_t i = 0; i < 10; ++i) { + std::same_as::reference> decltype(auto) x = acc.access(ptr, i); + ASSERT_NOEXCEPT(acc.access(ptr, i)); + assert(&x == ptr + i); + } } template diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp index 64e37fd7344b27..ae4dac5504f66e 100644 --- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp +++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp @@ -28,14 +28,19 @@ template constexpr void test_offset() { ElementPool, 10 + N> data; T* ptr = data.get_ptr(); - std::aligned_accessor acc; - for (size_t i = 0; i < 10 + N; i++) { + // align ptr + for (size_t i = 0; i < N; ++i) { if (reinterpret_cast(ptr + i) % N == 0) { - std::same_as::data_handle_type> decltype(auto) x = acc.offset(ptr, i); - ASSERT_NOEXCEPT(acc.offset(ptr, i)); - assert(x == ptr + i); + ptr += i; + break; } } + std::aligned_accessor acc; + for (size_t i = 0; i < 10; ++i) { + std::same_as::data_handle_type> decltype(auto) x = acc.offset(ptr, i); + ASSERT_NOEXCEPT(acc.offset(ptr, i)); + assert(x == ptr + i); + } } template