From f268971d7160c47765f2e76f660ad4a4b25586ad Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Thu, 12 Jun 2025 12:44:18 -0400 Subject: [PATCH 1/3] Add GitHub clang-format check --- .github/workflows/clang-format-check.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/clang-format-check.yml diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml new file mode 100644 index 00000000..97340df0 --- /dev/null +++ b/.github/workflows/clang-format-check.yml @@ -0,0 +1,15 @@ +name: clang-format check + +on: [push, pull_request] + +permissions: read-all + +jobs: + clang-formatting-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Run clang-format style check. + uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20 + with: + clangFormatVersion: 16 From 3639703da3b8cb3c28b4eea3c68f2315a8eb34fb Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Thu, 12 Jun 2025 12:44:46 -0400 Subject: [PATCH 2/3] Add .clang-format file --- .clang-format | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..090edc2c --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +#Official Tool: clang-format version 16.0.0 +BasedOnStyle: google +SortIncludes: false +AlignConsecutiveAssignments: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true From 3c1cc4cabdfb6999e7aa6a760ca2f5ef24acc41d Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Mon, 16 Jun 2025 08:23:22 -0400 Subject: [PATCH 3/3] Apply clang-format 16 --- benchmarks/copy/copy_layout_stride.cpp | 254 ++-- benchmarks/fill.hpp | 230 ++-- benchmarks/matvec/openmp/matvec_openmp.cpp | 191 +-- .../stencil/openmp/stencil_3d_openmp.cpp | 320 +++-- benchmarks/stencil/stencil_3d.cpp | 84 +- benchmarks/sum/openmp/sum_3d_openmp.cpp | 68 +- benchmarks/sum/sum_3d_common.hpp | 106 +- benchmarks/sum/sum_3d_left.cpp | 50 +- benchmarks/sum/sum_3d_right.cpp | 49 +- benchmarks/sum/sum_submdspan_right.cpp | 191 ++- .../openmp/tiny_matrix_add_openmp.cpp | 315 +++-- .../tiny_matrix_add/tiny_matrix_add.cpp | 77 +- compilation_tests/ctest_common.hpp | 94 +- .../ctest_compressed_pair_layout.cpp | 123 +- .../ctest_constexpr_dereference.cpp | 252 ++-- compilation_tests/ctest_constexpr_layouts.cpp | 21 +- .../ctest_constexpr_submdspan.cpp | 260 ++-- .../ctest_constructor_sfinae.cpp | 148 +- compilation_tests/ctest_extents_ctors.cpp | 279 ++-- .../ctest_extents_type_check.cpp | 115 +- .../ctest_layout_convertible.cpp | 58 +- compilation_tests/ctest_layout_type_check.cpp | 175 ++- .../ctest_mdarray_type_check.cpp | 179 ++- .../ctest_mdspan_convertible.cpp | 19 +- compilation_tests/ctest_namespace_std.cpp | 2 +- compilation_tests/ctest_no_unique_address.cpp | 59 +- compilation_tests/ctest_standard_layout.cpp | 117 +- .../ctest_trivially_copyable.cpp | 132 +- .../aligned_accessor/aligned_accessor.cpp | 600 ++++---- examples/dot_product/dot_product.cpp | 58 +- examples/godbolt_starter/godbolt_starter.cpp | 5 +- .../restrict_accessor/restrict_accessor.cpp | 179 +-- examples/tiled_layout/simple_tiled_layout.cpp | 150 +- .../__p0009_bits/compressed_pair.hpp | 106 +- include/experimental/__p0009_bits/config.hpp | 340 ++--- .../__p0009_bits/default_accessor.hpp | 29 +- .../__p0009_bits/dynamic_extent.hpp | 5 +- include/experimental/__p0009_bits/extents.hpp | 359 +++-- .../__p0009_bits/full_extent_t.hpp | 8 +- .../experimental/__p0009_bits/layout_left.hpp | 447 +++--- .../__p0009_bits/layout_right.hpp | 456 ++++--- .../__p0009_bits/layout_stride.hpp | 609 +++++---- include/experimental/__p0009_bits/macros.hpp | 644 ++++----- include/experimental/__p0009_bits/mdspan.hpp | 700 +++++----- .../__p0009_bits/no_unique_address.hpp | 33 +- .../__p0009_bits/trait_backports.hpp | 49 +- .../experimental/__p0009_bits/type_list.hpp | 35 +- include/experimental/__p0009_bits/utility.hpp | 134 +- include/experimental/__p1684_bits/mdarray.hpp | 570 ++++---- include/experimental/__p2389_bits/dims.hpp | 9 +- .../__p2630_bits/strided_slice.hpp | 22 +- .../experimental/__p2630_bits/submdspan.hpp | 25 +- .../__p2630_bits/submdspan_extents.hpp | 261 ++-- .../__p2630_bits/submdspan_mapping.hpp | 475 ++++--- .../__p2642_bits/layout_padded.hpp | 535 ++++---- .../__p2642_bits/layout_padded_fwd.hpp | 111 +- include/mdspan/mdarray.hpp | 6 +- include/mdspan/mdspan.hpp | 6 +- tests/foo_customizations.hpp | 429 +++--- .../libcxx-backports/ConvertibleToIntegral.h | 22 +- tests/libcxx-backports/CustomTestLayouts.h | 106 +- tests/libcxx-backports/MinimalElementType.h | 20 +- .../default_accessor.access.pass.cpp | 5 +- .../default_accessor.ctor.conversion.pass.cpp | 28 +- .../default_accessor.ctor.default.pass.cpp | 3 +- .../default_accessor.element_type.verify.cpp | 12 +- .../default_accessor.offset.pass.cpp | 9 +- .../default_accessor.types.pass.cpp | 4 +- .../extents/CtorTestCombinations.h | 51 +- .../extents/comparison.pass.cpp | 27 +- .../extents/conversion.pass.cpp | 84 +- tests/libcxx-backports/extents/ctad.pass.cpp | 8 +- .../extents/ctor_default.pass.cpp | 14 +- .../extents/ctor_from_array.pass.cpp | 50 +- .../extents/ctor_from_integral.pass.cpp | 35 +- .../extents/ctor_from_span.pass.cpp | 50 +- .../extents/dextents.pass.cpp | 6 +- .../extents/obs_static.pass.cpp | 9 +- tests/libcxx-backports/extents/types.pass.cpp | 6 +- .../layout_left.comparison.pass.cpp | 85 +- .../layout_left.ctor.extents.pass.cpp | 3 +- .../layout_left.ctor.layout_right.pass.cpp | 65 +- .../layout_left.ctor.layout_stride.pass.cpp | 33 +- .../layout_left.ctor.mapping.pass.cpp | 45 +- .../layout_left.extents.verify.cpp | 9 +- .../layout_left.index_operator.pass.cpp | 50 +- .../layout_left.required_span_size.pass.cpp | 4 +- .../layout_left.static_requirements.pass.cpp | 52 +- .../layout_left/layout_left.stride.pass.cpp | 9 +- .../layout_right.comparison.pass.cpp | 85 +- .../layout_right.ctor.extents.pass.cpp | 3 +- .../layout_right.ctor.layout_left.pass.cpp | 65 +- .../layout_right.ctor.layout_stride.pass.cpp | 33 +- .../layout_right.ctor.mapping.pass.cpp | 45 +- .../layout_right.extents.verify.cpp | 9 +- .../layout_right.index_operator.pass.cpp | 47 +- .../layout_right.required_span_size.pass.cpp | 4 +- .../layout_right.static_requirements.pass.cpp | 54 +- .../layout_right/layout_right.stride.pass.cpp | 9 +- .../layout_stride.comparison.pass.cpp | 229 ++-- .../layout_stride.ctor.default.pass.cpp | 12 +- .../layout_stride.ctor.extents_array.pass.cpp | 42 +- .../layout_stride.ctor.extents_span.pass.cpp | 78 +- ...ayout_stride.ctor.strided_mapping.pass.cpp | 48 +- .../layout_stride.deduction.pass.cpp | 31 +- .../layout_stride.extents.verify.cpp | 11 +- .../layout_stride.index_operator.pass.cpp | 41 +- ..._stride.is_exhaustive_corner_case.pass.cpp | 35 +- .../layout_stride.properties.pass.cpp | 31 +- .../layout_stride.required_span_size.pass.cpp | 31 +- ...layout_stride.static_requirements.pass.cpp | 57 +- .../layout_stride.stride.pass.cpp | 15 +- tests/libcxx-backports/llvm_test_macros.h | 25 +- .../mdspan/CustomTestAccessors.h | 67 +- .../mdspan/mdspan.assign.pass.cpp | 78 +- .../mdspan/mdspan.conversion.pass.cpp | 369 +++-- .../mdspan/mdspan.conversion.verify.cpp | 39 +- .../mdspan/mdspan.ctor.copy.pass.cpp | 65 +- .../mdspan/mdspan.ctor.default.pass.cpp | 57 +- .../mdspan/mdspan.ctor.dh_array.pass.cpp | 133 +- .../mdspan/mdspan.ctor.dh_extents.pass.cpp | 103 +- .../mdspan/mdspan.ctor.dh_integers.pass.cpp | 110 +- .../mdspan/mdspan.ctor.dh_map.pass.cpp | 75 +- .../mdspan/mdspan.ctor.dh_map_acc.pass.cpp | 89 +- .../mdspan/mdspan.ctor.dh_span.pass.cpp | 130 +- .../mdspan/mdspan.ctor.move.pass.cpp | 62 +- .../mdspan/mdspan.deduction.pass.cpp | 69 +- .../mdspan/mdspan.element_type.verify.cpp | 22 +- .../mdspan/mdspan.extents.verify.cpp | 7 +- .../mdspan/mdspan.index_operator.pass.cpp | 159 ++- .../mdspan/mdspan.mapping.verify.cpp | 16 +- .../mdspan/mdspan.move.pass.cpp | 57 +- .../mdspan/mdspan.properties.pass.cpp | 49 +- .../mdspan/mdspan.swap.pass.cpp | 14 +- .../mdspan/mdspan.types.pass.cpp | 59 +- tests/offload_utils.hpp | 136 +- ...ternate_precondition_violation_handler.cpp | 16 +- tests/test_dims.cpp | 44 +- tests/test_element_access.cpp | 11 +- tests/test_exhaustive_layouts.cpp | 744 ++++++---- tests/test_extents.cpp | 370 ++--- tests/test_layout_ctors.cpp | 200 +-- tests/test_layout_padded_left.cpp | 1200 ++++++++++++---- tests/test_layout_padded_right.cpp | 1205 ++++++++++++----- tests/test_layout_preconditions.cpp | 6 +- tests/test_layout_stride.cpp | 217 +-- tests/test_macros.cpp | 15 +- tests/test_mdarray_ctors.cpp | 480 ++++--- tests/test_mdarray_to_mdspan.cpp | 32 +- tests/test_mdspan_at.cpp | 17 +- tests/test_mdspan_conversion.cpp | 2 - tests/test_mdspan_ctors.cpp | 167 +-- tests/test_mdspan_size.cpp | 39 +- tests/test_mdspan_swap.cpp | 97 +- tests/test_submdspan.cpp | 914 +++++++++---- tests/test_submdspan_static_slice.cpp | 1039 ++++++++------ 156 files changed, 12821 insertions(+), 9266 deletions(-) diff --git a/benchmarks/copy/copy_layout_stride.cpp b/benchmarks/copy/copy_layout_stride.cpp index 6ff3d63b..7adaf40b 100644 --- a/benchmarks/copy/copy_layout_stride.cpp +++ b/benchmarks/copy/copy_layout_stride.cpp @@ -26,19 +26,17 @@ MDSPAN_IMPL_INLINE_VARIABLE constexpr auto dyn = Kokkos::dynamic_extent; template void BM_MDSpan_Copy_2D_right(benchmark::State& state, MDSpan, DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto buffer2 = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); auto dest = MDSpan{buffer2.get(), dyn...}; for (auto _ : state) { - for(index_type i = 0; i < s.extent(0); ++i) { + for (index_type i = 0; i < s.extent(0); ++i) { for (index_type j = 0; j < s.extent(1); ++j) { - dest(i, j) = s(i, j); + dest(i, j) = s(i, j); } } auto sdata = s.data_handle(); @@ -50,32 +48,29 @@ void BM_MDSpan_Copy_2D_right(benchmark::State& state, MDSpan, DynSizes... dyn) { } BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_right, size_100_100, Kokkos::mdspan>(nullptr) -); -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_right, size_100_dyn, Kokkos::mdspan>(), 100 -); -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_right, size_dyn_dyn, Kokkos::mdspan>(), 100, 100 -); + BM_MDSpan_Copy_2D_right, size_100_100, + Kokkos::mdspan>(nullptr)); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_right, size_100_dyn, + Kokkos::mdspan>(), + 100); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_right, size_dyn_dyn, + Kokkos::mdspan>(), 100, + 100); //================================================================================ template -void BM_MDSpan_Copy_2D_stride(benchmark::State& state, MDSpan, LayoutMapping map) { +void BM_MDSpan_Copy_2D_stride(benchmark::State& state, MDSpan, + LayoutMapping map) { benchmark::DoNotOptimize(map); using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - map.required_span_size() - ); - auto buffer2 = std::make_unique( - map.required_span_size() - ); - auto s = MDSpan{buffer.get(), map}; + auto buffer = std::make_unique(map.required_span_size()); + auto buffer2 = std::make_unique(map.required_span_size()); + auto s = MDSpan{buffer.get(), map}; mdspan_benchmark::fill_random(s); auto dest = MDSpan{buffer2.get(), map}; for (auto _ : state) { - for(index_type i = 0; i < s.extent(0); ++i) { + for (index_type i = 0; i < s.extent(0); ++i) { for (index_type j = 0; j < s.extent(1); ++j) { dest(i, j) = s(i, j); } @@ -88,64 +83,57 @@ void BM_MDSpan_Copy_2D_stride(benchmark::State& state, MDSpan, LayoutMapping map state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride, size_100_100, - Kokkos::mdspan, Kokkos::layout_stride>(nullptr, - Kokkos::layout_stride::mapping>()), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{}, - // layout right - std::array{100, 1} - ) -); -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride, size_100_100d, - Kokkos::mdspan, Kokkos::layout_stride>(), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100}, - // layout right - std::array{100, 1} - ) -); -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride, size_100d_100, - Kokkos::mdspan, Kokkos::layout_stride>(), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100}, - // layout right - std::array{100, 1} - ) -); -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride, size_100d_100d, - Kokkos::mdspan, Kokkos::layout_stride>(), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{100, 1} - ) -); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride, size_100_100, + Kokkos::mdspan, + Kokkos::layout_stride>( + nullptr, Kokkos::layout_stride::mapping< + Kokkos::extents>()), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{}, + // layout right + std::array{100, 1})); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride, size_100_100d, + Kokkos::mdspan, + Kokkos::layout_stride>(), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100}, + // layout right + std::array{100, 1})); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride, size_100d_100, + Kokkos::mdspan, + Kokkos::layout_stride>(), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100}, + // layout right + std::array{100, 1})); +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride, size_100d_100d, + Kokkos::mdspan, + Kokkos::layout_stride>(), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{100, 1})); //================================================================================ template -void BM_MDSpan_Copy_2D_stride_diff_map(benchmark::State& state, - T, Extents, MapSrc map_src, MapDst map_dest -) { +void BM_MDSpan_Copy_2D_stride_diff_map(benchmark::State& state, T, Extents, + MapSrc map_src, MapDst map_dest) { using value_type = T; - auto buff_src = std::make_unique( - map_src.required_span_size() - ); - auto buff_dest = std::make_unique( - map_dest.required_span_size() - ); + auto buff_src = std::make_unique(map_src.required_span_size()); + auto buff_dest = + std::make_unique(map_dest.required_span_size()); using map_stride_dyn = Kokkos::layout_stride; - using mdspan_type = Kokkos::mdspan; - auto src = mdspan_type{buff_src.get(), map_src}; + using mdspan_type = Kokkos::mdspan; + auto src = mdspan_type{buff_src.get(), map_src}; mdspan_benchmark::fill_random(src); auto dest = mdspan_type{buff_dest.get(), map_dest}; for (auto _ : state) { - for(index_type i = 0; i < src.extent(0); ++i) { + for (index_type i = 0; i < src.extent(0); ++i) { for (index_type j = 0; j < src.extent(1); ++j) { dest(i, j) = src(i, j); } @@ -155,54 +143,48 @@ void BM_MDSpan_Copy_2D_stride_diff_map(benchmark::State& state, benchmark::DoNotOptimize(sdata); benchmark::DoNotOptimize(ddata); } - state.SetBytesProcessed(src.extent(0) * src.extent(1) * sizeof(value_type) * state.iterations()); + state.SetBytesProcessed(src.extent(0) * src.extent(1) * sizeof(value_type) * + state.iterations()); } -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_0, int(), - Kokkos::extents{100, 100}, - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{0, 1} - ), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{100, 1} - ) -); - -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_1, int(), - Kokkos::extents{100, 100}, - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{1, 0} - ), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{100, 1} - ) -); - -BENCHMARK_CAPTURE( - BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_both, int(), - Kokkos::extents{100, 100}, - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{0, 0} - ), - Kokkos::layout_stride::template mapping>( - Kokkos::extents{100, 100}, - // layout right - std::array{100, 1} - ) -); - +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_0, + int(), Kokkos::extents{100, 100}, + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{0, 1}), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{100, 1})); + +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_1, + int(), Kokkos::extents{100, 100}, + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{1, 0}), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{100, 1})); + +BENCHMARK_CAPTURE(BM_MDSpan_Copy_2D_stride_diff_map, size_100d_100d_bcast_both, + int(), Kokkos::extents{100, 100}, + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{0, 0}), + Kokkos::layout_stride::template mapping< + Kokkos::extents>( + Kokkos::extents{100, 100}, + // layout right + std::array{100, 1})); //================================================================================ @@ -210,17 +192,18 @@ template void BM_Raw_Copy_1D(benchmark::State& state, T, size_t size) { benchmark::DoNotOptimize(size); using value_type = T; - auto buffer = std::make_unique(size); + auto buffer = std::make_unique(size); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), size}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), size}; mdspan_benchmark::fill_random(wrapped); } - value_type* src = buffer.get(); - auto buffer2 = std::make_unique(size); + value_type* src = buffer.get(); + auto buffer2 = std::make_unique(size); value_type* dest = buffer2.get(); for (auto _ : state) { - for(size_t i = 0; i < size; ++i) { + for (size_t i = 0; i < size; ++i) { dest[i] = src[i]; } benchmark::DoNotOptimize(src); @@ -229,28 +212,27 @@ void BM_Raw_Copy_1D(benchmark::State& state, T, size_t size) { state.SetBytesProcessed(size * sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE( - BM_Raw_Copy_1D, size_10000, int(), 10000 -); +BENCHMARK_CAPTURE(BM_Raw_Copy_1D, size_10000, int(), 10000); //================================================================================ template void BM_Raw_Copy_2D(benchmark::State& state, T, size_t x, size_t y) { using value_type = T; - auto buffer = std::make_unique(x * y); + auto buffer = std::make_unique(x * y); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x * y}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y}; mdspan_benchmark::fill_random(wrapped); } - value_type* src = buffer.get(); - auto buffer2 = std::make_unique(x * y); + value_type* src = buffer.get(); + auto buffer2 = std::make_unique(x * y); value_type* dest = buffer2.get(); for (auto _ : state) { - for(size_t i = 0; i < x; ++i) { - for(size_t j = 0; j < y; ++j) { - dest[i*y + j] = src[i*y + j]; + for (size_t i = 0; i < x; ++i) { + for (size_t j = 0; j < y; ++j) { + dest[i * y + j] = src[i * y + j]; } } benchmark::DoNotOptimize(src); @@ -259,9 +241,7 @@ void BM_Raw_Copy_2D(benchmark::State& state, T, size_t x, size_t y) { state.SetBytesProcessed(x * y * sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE( - BM_Raw_Copy_2D, size_100_100, int(), 100, 100 -); +BENCHMARK_CAPTURE(BM_Raw_Copy_2D, size_100_100, int(), 100, 100); //================================================================================ diff --git a/benchmarks/fill.hpp b/benchmarks/fill.hpp index cc79fa70..8040f82f 100644 --- a/benchmarks/fill.hpp +++ b/benchmarks/fill.hpp @@ -18,16 +18,16 @@ #include -namespace KokkosEx = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; +namespace KokkosEx = + MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; #include #include #include - - -#if !(defined(__cpp_lib_make_unique) && __cpp_lib_make_unique >= 201304) && !MDSPAN_HAS_CXX_14 +#if !(defined(__cpp_lib_make_unique) && __cpp_lib_make_unique >= 201304) && \ + !MDSPAN_HAS_CXX_14 // Not actually conforming, but it works for the purposes of this file namespace std { template @@ -40,16 +40,14 @@ struct __unique_ptr_new_impl { template struct __unique_ptr_new_impl { - static T* __impl(size_t size) { - return new T[size]; - } + static T* __impl(size_t size) { return new T[size]; } }; template std::unique_ptr make_unique(Args&&... args) { return std::unique_ptr(__unique_ptr_new_impl::__impl((Args&&)args...)); } -} // end namespace std +} // end namespace std #endif namespace mdspan_benchmark { @@ -57,31 +55,30 @@ namespace mdspan_benchmark { namespace _impl { template -T&& _repeated_with(T&& v) noexcept { return std::forward(v); } +T&& _repeated_with(T&& v) noexcept { + return std::forward(v); +} template -void _do_fill_random( - Kokkos::mdspan, Rest...> s, - RNG& gen, - Dist& dist -) -{ +void _do_fill_random(Kokkos::mdspan, Rest...> s, + RNG& gen, Dist& dist) { s() = dist(gen); } -template +template void _do_fill_random( - Kokkos::mdspan, Rest...> s, - RNG& gen, - Dist& dist -) -{ - for(SizeT i = 0; i < s.extent(0); ++i) { - _do_fill_random(Kokkos::submdspan(s, i, _repeated_with(Kokkos::full_extent)...), gen, dist); + Kokkos::mdspan, Rest...> s, RNG& gen, + Dist& dist) { + for (SizeT i = 0; i < s.extent(0); ++i) { + _do_fill_random( + Kokkos::submdspan(s, i, + _repeated_with(Kokkos::full_extent)...), + gen, dist); } } -} // end namespace _impl +} // end namespace _impl template void fill_random(Kokkos::mdspan s, long long seed = 1234) { @@ -90,90 +87,113 @@ void fill_random(Kokkos::mdspan s, long long seed = 1234) { _impl::_do_fill_random(s, gen, val_dist); } -} // namespace mdspan_benchmark +} // namespace mdspan_benchmark //============================================================================== -// {{{1 +// +// {{{1 #define MDSPAN_BENCHMARK_ALL_3D(bench_template, prefix, md_template, X, Y, Z) \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##fixed_##X##_##Y##_##Z, md_template{nullptr} \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_##Y##_d##Z, md_template{}, Z \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_##Z, md_template{}, Y \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_##Z, md_template{}, X \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_d##Z, md_template{}, Y, Z \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_d##Z, md_template{}, X, Z \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_##Z, md_template{}, X, Y \ -); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_d##Z, md_template{}, X, Y, Z \ -) - -#define MDSPAN_BENCHMARK_ALL_3D_MANUAL(bench_template, prefix, md_template, X, Y, Z) \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##fixed_##X##_##Y##_##Z, md_template{nullptr} \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_##Y##_d##Z, md_template{}, Z \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_##Z, md_template{}, Y \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_##Z, md_template{}, X \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_d##Z, md_template{}, Y, Z \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_d##Z, md_template{}, X, Z \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_##Z, md_template{}, X, Y \ -)->UseManualTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_d##Z, md_template{}, X, Y, Z \ -)->UseManualTime() - -#define MDSPAN_BENCHMARK_ALL_3D_REAL_TIME(bench_template, prefix, md_template, X, Y, Z) \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##fixed_##X##_##Y##_##Z, md_template{nullptr} \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_##Y##_d##Z, md_template{}, Z \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_##Z, md_template{}, Y \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_##Z, md_template{}, X \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_##X##_d##Y##_d##Z, md_template{}, Y, Z \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_##Y##_d##Z, md_template{}, X, Z \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_##Z, md_template{}, X, Y \ -)->UseRealTime(); \ -BENCHMARK_CAPTURE( \ - bench_template, prefix##dyn_d##X##_d##Y##_d##Z, md_template{}, X, Y, Z \ -)->UseRealTime() - -// end A helpful template for instantiating all 3D combinations }}}1 + BENCHMARK_CAPTURE(bench_template, prefix##fixed_##X##_##Y##_##Z, \ + md_template{nullptr}); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_##Y##_d##Z, \ + md_template{}, Z); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_d##Y##_##Z, \ + md_template{}, Y); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_d##X##_##Y##_##Z, \ + md_template{}, X); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_##X##_d##Y##_d##Z, \ + md_template{}, \ + Y, Z); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_##Y##_d##Z, \ + md_template{}, \ + X, Z); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_##Z, \ + md_template{}, \ + X, Y); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_d##Z, \ + md_template{}, \ + X, Y, Z) + +#define MDSPAN_BENCHMARK_ALL_3D_MANUAL(bench_template, prefix, md_template, X, \ + Y, Z) \ + BENCHMARK_CAPTURE(bench_template, prefix##fixed_##X##_##Y##_##Z, \ + md_template{nullptr}) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_##Y##_d##Z, \ + md_template{}, Z) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_d##Y##_##Z, \ + md_template{}, Y) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_d##X##_##Y##_##Z, \ + md_template{}, X) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_##X##_d##Y##_d##Z, \ + md_template{}, \ + Y, Z) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_##Y##_d##Z, \ + md_template{}, \ + X, Z) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_##Z, \ + md_template{}, \ + X, Y) \ + ->UseManualTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_d##Z, \ + md_template{}, \ + X, Y, Z) \ + ->UseManualTime() + +#define MDSPAN_BENCHMARK_ALL_3D_REAL_TIME(bench_template, prefix, md_template, \ + X, Y, Z) \ + BENCHMARK_CAPTURE(bench_template, prefix##fixed_##X##_##Y##_##Z, \ + md_template{nullptr}) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_##Y##_d##Z, \ + md_template{}, Z) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_##X##_d##Y##_##Z, \ + md_template{}, Y) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE(bench_template, prefix##dyn_d##X##_##Y##_##Z, \ + md_template{}, X) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_##X##_d##Y##_d##Z, \ + md_template{}, \ + Y, Z) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_##Y##_d##Z, \ + md_template{}, \ + X, Z) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_##Z, \ + md_template{}, \ + X, Y) \ + ->UseRealTime(); \ + BENCHMARK_CAPTURE( \ + bench_template, prefix##dyn_d##X##_d##Y##_d##Z, \ + md_template{}, \ + X, Y, Z) \ + ->UseRealTime() + +// end A helpful template for instantiating all 3D combinations +// }}}1 //============================================================================== -#endif // MDSPAN_BENCHMARKS_FILL_HPP +#endif // MDSPAN_BENCHMARKS_FILL_HPP diff --git a/benchmarks/matvec/openmp/matvec_openmp.cpp b/benchmarks/matvec/openmp/matvec_openmp.cpp index ec84b029..5a9f057e 100644 --- a/benchmarks/matvec/openmp/matvec_openmp.cpp +++ b/benchmarks/matvec/openmp/matvec_openmp.cpp @@ -30,30 +30,32 @@ static constexpr int global_repeat = 1; using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; -void throw_runtime_exception(const std::string &msg) { +void throw_runtime_exception(const std::string& msg) { std::ostringstream o; o << msg; throw std::runtime_error(o.str()); } -template +template void OpenMP_first_touch_2D(MDSpan s) { - #pragma omp parallel for - for(index_type i = 0; i < s.extent(0); i ++) { - for(index_type j = 0; j < s.extent(1); j ++) { - s(i,j) = 0; +#pragma omp parallel for + for (index_type i = 0; i < s.extent(0); i++) { + for (index_type j = 0; j < s.extent(1); j++) { + s(i, j) = 0; } } } -template +template void OpenMP_first_touch_1D(MDSpan s) { - #pragma omp parallel for - for(index_type i = 0; i < s.extent(0); i ++) { +#pragma omp parallel for + for (index_type i = 0; i < s.extent(0); i++) { s(i) = 0; } } @@ -61,34 +63,37 @@ void OpenMP_first_touch_1D(MDSpan s) { //================================================================================ template -void BM_MDSpan_OpenMP_MatVec(benchmark::State& state, MDSpanMatrix, DynSizes... dyn) { +void BM_MDSpan_OpenMP_MatVec(benchmark::State& state, MDSpanMatrix, + DynSizes... dyn) { + using value_type = typename MDSpanMatrix::value_type; + using MDSpanVector = lmdspan; - using value_type = typename MDSpanMatrix::value_type; - using MDSpanVector = lmdspan; - - auto buffer_size_A = MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); + auto buffer_size_A = + MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); auto buffer_A = std::make_unique(buffer_size_A); - auto A = MDSpanMatrix{buffer_A.get(), dyn...}; + auto A = MDSpanMatrix{buffer_A.get(), dyn...}; OpenMP_first_touch_2D(A); mdspan_benchmark::fill_random(A); - auto buffer_size_x = MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); + auto buffer_size_x = + MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); auto buffer_x = std::make_unique(buffer_size_x); - auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; + auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; OpenMP_first_touch_1D(x); mdspan_benchmark::fill_random(x); - auto buffer_size_y = MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); + auto buffer_size_y = + MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); auto buffer_y = std::make_unique(buffer_size_y); - auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; + auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; OpenMP_first_touch_1D(y); mdspan_benchmark::fill_random(y); - #pragma omp parallel for - for(index_type i = 0; i < A.extent(0); i ++) { +#pragma omp parallel for + for (index_type i = 0; i < A.extent(0); i++) { value_type y_i = 0; - for(index_type j = 0; j < A.extent(1); j ++) { - y_i += A(i,j) * x(j); + for (index_type j = 0; j < A.extent(1); j++) { + y_i += A(i, j) * x(j); } y(i) = y_i; } @@ -101,48 +106,57 @@ void BM_MDSpan_OpenMP_MatVec(benchmark::State& state, MDSpanMatrix, DynSizes... benchmark::DoNotOptimize(ah); benchmark::DoNotOptimize(yh); benchmark::DoNotOptimize(xh); - for(int r=0; r(), 100000, 5000); -BENCHMARK_CAPTURE(BM_MDSpan_OpenMP_MatVec, right, rmdspan(), 100000, 5000); - +BENCHMARK_CAPTURE( + BM_MDSpan_OpenMP_MatVec, left, + lmdspan(), 100000, + 5000); +BENCHMARK_CAPTURE( + BM_MDSpan_OpenMP_MatVec, right, + rmdspan(), 100000, + 5000); template -void BM_MDSpan_OpenMP_MatVec_Raw_Left(benchmark::State& state, MDSpanMatrix, DynSizes... dyn) { - - using value_type = typename MDSpanMatrix::value_type; - using MDSpanVector = lmdspan; +void BM_MDSpan_OpenMP_MatVec_Raw_Left(benchmark::State& state, MDSpanMatrix, + DynSizes... dyn) { + using value_type = typename MDSpanMatrix::value_type; + using MDSpanVector = lmdspan; - auto buffer_size_A = MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); + auto buffer_size_A = + MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); auto buffer_A = std::make_unique(buffer_size_A); - auto A = MDSpanMatrix{buffer_A.get(), dyn...}; + auto A = MDSpanMatrix{buffer_A.get(), dyn...}; OpenMP_first_touch_2D(A); mdspan_benchmark::fill_random(A); - auto buffer_size_x = MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); + auto buffer_size_x = + MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); auto buffer_x = std::make_unique(buffer_size_x); - auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; + auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; OpenMP_first_touch_1D(x); mdspan_benchmark::fill_random(x); - auto buffer_size_y = MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); + auto buffer_size_y = + MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); auto buffer_y = std::make_unique(buffer_size_y); - auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; + auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; OpenMP_first_touch_1D(y); mdspan_benchmark::fill_random(y); @@ -153,10 +167,10 @@ void BM_MDSpan_OpenMP_MatVec_Raw_Left(benchmark::State& state, MDSpanMatrix, Dyn value_type* p_x = x.data_handle(); value_type* p_y = y.data_handle(); - #pragma omp parallel for - for(index_type i = 0; i < N; i ++) { +#pragma omp parallel for + for (index_type i = 0; i < N; i++) { value_type y_i = 0; - for(index_type j = 0; j < M; j ++) { + for (index_type j = 0; j < M; j++) { y_i += p_A[i + j * N] * x[j]; } y[i] = y_i; @@ -170,46 +184,53 @@ void BM_MDSpan_OpenMP_MatVec_Raw_Left(benchmark::State& state, MDSpanMatrix, Dyn benchmark::DoNotOptimize(ah); benchmark::DoNotOptimize(yh); benchmark::DoNotOptimize(xh); - for(int r=0; r(), 100000, 5000); +BENCHMARK_CAPTURE( + BM_MDSpan_OpenMP_MatVec_Raw_Left, left, + lmdspan(), 100000, + 5000); template -void BM_MDSpan_OpenMP_MatVec_Raw_Right(benchmark::State& state, MDSpanMatrix, DynSizes... dyn) { - - using value_type = typename MDSpanMatrix::value_type; - using MDSpanVector = lmdspan; +void BM_MDSpan_OpenMP_MatVec_Raw_Right(benchmark::State& state, MDSpanMatrix, + DynSizes... dyn) { + using value_type = typename MDSpanMatrix::value_type; + using MDSpanVector = lmdspan; - auto buffer_size_A = MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); + auto buffer_size_A = + MDSpanMatrix{nullptr, dyn...}.mapping().required_span_size(); auto buffer_A = std::make_unique(buffer_size_A); - auto A = MDSpanMatrix{buffer_A.get(), dyn...}; + auto A = MDSpanMatrix{buffer_A.get(), dyn...}; OpenMP_first_touch_2D(A); mdspan_benchmark::fill_random(A); - auto buffer_size_x = MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); + auto buffer_size_x = + MDSpanVector{nullptr, A.extent(1)}.mapping().required_span_size(); auto buffer_x = std::make_unique(buffer_size_x); - auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; + auto x = MDSpanVector{buffer_x.get(), A.extent(1)}; OpenMP_first_touch_1D(x); mdspan_benchmark::fill_random(x); - auto buffer_size_y = MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); + auto buffer_size_y = + MDSpanVector{nullptr, A.extent(0)}.mapping().required_span_size(); auto buffer_y = std::make_unique(buffer_size_y); - auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; + auto y = MDSpanVector{buffer_y.get(), A.extent(0)}; OpenMP_first_touch_1D(y); mdspan_benchmark::fill_random(y); @@ -220,10 +241,10 @@ void BM_MDSpan_OpenMP_MatVec_Raw_Right(benchmark::State& state, MDSpanMatrix, Dy value_type* p_x = x.data_handle(); value_type* p_y = y.data_handle(); - #pragma omp parallel for - for(index_type i = 0; i < N; i ++) { +#pragma omp parallel for + for (index_type i = 0; i < N; i++) { value_type y_i = 0; - for(index_type j = 0; j < M; j ++) { + for (index_type j = 0; j < M; j++) { y_i += p_A[i * M + j] * x[j]; } y[i] = y_i; @@ -237,24 +258,28 @@ void BM_MDSpan_OpenMP_MatVec_Raw_Right(benchmark::State& state, MDSpanMatrix, Dy benchmark::DoNotOptimize(ah); benchmark::DoNotOptimize(yh); benchmark::DoNotOptimize(xh); - for(int r=0; r(), 100000, 5000); +BENCHMARK_CAPTURE( + BM_MDSpan_OpenMP_MatVec_Raw_Right, right, + rmdspan(), 100000, + 5000); //================================================================================ diff --git a/benchmarks/stencil/openmp/stencil_3d_openmp.cpp b/benchmarks/stencil/openmp/stencil_3d_openmp.cpp index 478dde47..c766eea3 100644 --- a/benchmarks/stencil/openmp/stencil_3d_openmp.cpp +++ b/benchmarks/stencil/openmp/stencil_3d_openmp.cpp @@ -35,23 +35,25 @@ static constexpr int global_delta = 1; using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; -void throw_runtime_exception(const std::string &msg) { +void throw_runtime_exception(const std::string& msg) { std::ostringstream o; o << msg; throw std::runtime_error(o.str()); } -template +template void OpenMP_first_touch_3D(MDSpan s) { - #pragma omp parallel for - for(index_type i = 0; i < s.extent(0); i ++) { - for(index_type j = 0; j < s.extent(1); j ++) { - for(index_type k = 0; k < s.extent(2); k ++) { - s(i,j,k) = 0; +#pragma omp parallel for + for (index_type i = 0; i < s.extent(0); i++) { + for (index_type j = 0; j < s.extent(1); j++) { + for (index_type k = 0; k < s.extent(2); k++) { + s(i, j, k) = 0; } } } @@ -60,266 +62,300 @@ void OpenMP_first_touch_3D(MDSpan s) { //================================================================================ template -void BM_MDSpan_OpenMP_Stencil_3D(benchmark::State& state, MDSpan, DynSizes... dyn) { - +void BM_MDSpan_OpenMP_Stencil_3D(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, dyn...}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), dyn...}; + auto s = MDSpan{buffer_s.get(), dyn...}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), dyn...}; + auto o = MDSpan{buffer_o.get(), dyn...}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); int d = global_delta; - #pragma omp parallel for - for(index_type i = d; i < s.extent(0)-d; i ++) { - for(index_type j = d; j < s.extent(1)-d; j ++) { - for(index_type k = d; k < s.extent(2)-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < s.extent(0) - d; i++) { + for (index_type j = d; j < s.extent(1) - d; j++) { + for (index_type k = d; k < s.extent(2) - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s(di, dj, dk); - }}} - o(i,j,k) = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s(di, dj, dk); + } + } + } + o(i, j, k) = sum_local; } } } for (auto _ : state) { - #pragma omp parallel for - for(index_type i = d; i < s.extent(0)-d; i ++) { - for(index_type j = d; j < s.extent(1)-d; j ++) { - for(index_type k = d; k < s.extent(2)-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < s.extent(0) - d; i++) { + for (index_type j = d; j < s.extent(1) - d; j++) { + for (index_type k = d; k < s.extent(2) - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s(di, dj, dk); - }}} - o(i,j,k) = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s(di, dj, dk); + } + } + } + o(i, j, k) = sum_local; } } } } - size_t num_inner_elements = (s.extent(0)-d) * (s.extent(1)-d) * (s.extent(2)-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); + size_t num_inner_elements = + (s.extent(0) - d) * (s.extent(1) - d) * (s.extent(2) - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); } -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, right_, rmdspan, 80, 80, 80); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, left_, lmdspan, 80, 80, 80); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, right_, rmdspan, 400, 400, 400); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, left_, lmdspan, 400, 400, 400); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, right_, rmdspan, 80, 80, + 80); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, left_, lmdspan, 80, 80, + 80); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, right_, rmdspan, 400, 400, + 400); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_Stencil_3D, left_, lmdspan, 400, 400, + 400); //================================================================================ template -void BM_Raw_OpenMP_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_OpenMP_Stencil_3D_right(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); int d = global_delta; - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[dk + dj*z + di*z*y]; - }}} - o_ptr[k + j*z + i*z*y] = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[dk + dj * z + di * z * y]; + } + } + } + o_ptr[k + j * z + i * z * y] = sum_local; } } } for (auto _ : state) { - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[dk + dj*z + di*z*y]; - }}} - o_ptr[k + j*z + i*z*y] = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[dk + dj * z + di * z * y]; + } + } + } + o_ptr[k + j * z + i * z * y] = sum_local; } } } } - size_t num_inner_elements = (s.extent(0)-d) * (s.extent(1)-d) * (s.extent(2)-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); + size_t num_inner_elements = + (s.extent(0) - d) * (s.extent(1) - d) * (s.extent(2) - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_right, size_80_80_80, int(), 80, 80, 80); -BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_right, size_400_400_400, int(), 400, 400, 400); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_right, size_80_80_80, int(), 80, 80, + 80); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_right, size_400_400_400, int(), 400, + 400, 400); //================================================================================ template -void BM_Raw_OpenMP_Stencil_3D_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_OpenMP_Stencil_3D_left(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); int d = global_delta; - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[dk*x*y + dj*x + di]; - }}} - o_ptr[k*x*y + j*x + i] = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[dk * x * y + dj * x + di]; + } + } + } + o_ptr[k * x * y + j * x + i] = sum_local; } } } for (auto _ : state) { - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[dk*x*y + dj*x + di]; - }}} - o_ptr[k*x*y + j*x + i] = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[dk * x * y + dj * x + di]; + } + } + } + o_ptr[k * x * y + j * x + i] = sum_local; } } } } - size_t num_inner_elements = (s.extent(0)-d) * (s.extent(1)-d) * (s.extent(2)-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); + size_t num_inner_elements = + (s.extent(0) - d) * (s.extent(1) - d) * (s.extent(2) - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_left, size_80_80_80, int(), 80, 80, 80); -BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_left, size_400_400_400, int(), 400, 400, 400); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_left, size_80_80_80, int(), 80, 80, + 80); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_Stencil_3D_left, size_400_400_400, int(), 400, + 400, 400); template typename MDSpan::value_type*** make_3d_ptr_array(MDSpan s) { - static_assert(std::is_same::value,"Creating MD Ptr only works from mdspan with layout_right"); - using value_type = typename MDSpan::value_type; - value_type*** ptr= new value_type**[s.extent(0)]; - for(index_type i = 0; i::value, + "Creating MD Ptr only works from mdspan with layout_right"); + using value_type = typename MDSpan::value_type; + value_type*** ptr = new value_type**[s.extent(0)]; + for (index_type i = 0; i < s.extent(0); i++) { ptr[i] = new value_type*[s.extent(1)]; - for(index_type j = 0; j void free_3d_ptr_array(T*** ptr, size_t extent_0) { - for(size_t i=0; i -void BM_RawMDPtr_OpenMP_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_RawMDPtr_OpenMP_Stencil_3D_right(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T*** s_ptr = make_3d_ptr_array(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T*** o_ptr = make_3d_ptr_array(o); int d = global_delta; - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[0][0][0]; - }}} + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[0][0][0]; + } + } + } o_ptr[i][j][k] = sum_local; } } } for (auto _ : state) { - #pragma omp parallel for - for(index_type i = d; i < x-d; i ++) { - for(index_type j = d; j < y-d; j ++) { - for(index_type k = d; k < z-d; k ++) { +#pragma omp parallel for + for (index_type i = d; i < x - d; i++) { + for (index_type j = d; j < y - d; j++) { + for (index_type k = d; k < z - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[di][dj][dk]; - }}} + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[di][dj][dk]; + } + } + } o_ptr[i][j][k] = sum_local; } } } } - size_t num_inner_elements = (s.extent(0)-d) * (s.extent(1)-d) * (s.extent(2)-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); - free_3d_ptr_array(s_ptr,s.extent(0)); - free_3d_ptr_array(o_ptr,o.extent(0)); + size_t num_inner_elements = + (s.extent(0) - d) * (s.extent(1) - d) * (s.extent(2) - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); + free_3d_ptr_array(s_ptr, s.extent(0)); + free_3d_ptr_array(o_ptr, o.extent(0)); } -BENCHMARK_CAPTURE(BM_RawMDPtr_OpenMP_Stencil_3D_right, size_80_80_80, int(), 80, 80, 80); -BENCHMARK_CAPTURE(BM_RawMDPtr_OpenMP_Stencil_3D_right, size_400_400_400, int(), 400, 400, 400); +BENCHMARK_CAPTURE(BM_RawMDPtr_OpenMP_Stencil_3D_right, size_80_80_80, int(), 80, + 80, 80); +BENCHMARK_CAPTURE(BM_RawMDPtr_OpenMP_Stencil_3D_right, size_400_400_400, int(), + 400, 400, 400); //================================================================================ BENCHMARK_MAIN(); diff --git a/benchmarks/stencil/stencil_3d.cpp b/benchmarks/stencil/stencil_3d.cpp index f1b646c4..e44c9f6a 100644 --- a/benchmarks/stencil/stencil_3d.cpp +++ b/benchmarks/stencil/stencil_3d.cpp @@ -33,24 +33,25 @@ static constexpr int global_delta = 1; using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template void BM_MDSpan_Stencil_3D(benchmark::State& state, MDSpan, DynSizes... dyn) { - using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, dyn...}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), dyn...}; + auto s = MDSpan{buffer_s.get(), dyn...}; mdspan_benchmark::fill_random(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), dyn...}; + auto o = MDSpan{buffer_o.get(), dyn...}; mdspan_benchmark::fill_random(o); int d = global_delta; @@ -58,24 +59,28 @@ void BM_MDSpan_Stencil_3D(benchmark::State& state, MDSpan, DynSizes... dyn) { using index_type = typename MDSpan::index_type; for (auto _ : state) { benchmark::DoNotOptimize(o); - for(index_type i = d; i < s.extent(0)-d; i ++) { - for(index_type j = d; j < s.extent(1)-d; j ++) { - for(index_type k = d; k < s.extent(2)-d; k ++) { + for (index_type i = d; i < s.extent(0) - d; i++) { + for (index_type j = d; j < s.extent(1) - d; j++) { + for (index_type k = d; k < s.extent(2) - d; k++) { value_type sum_local = 0; - for(index_type di = i-d; di < i+d+1; di++) { - for(index_type dj = j-d; dj < j+d+1; dj++) { - for(index_type dk = k-d; dk < k+d+1; dk++) { - sum_local += s(di, dj, dk); - }}} - o(i,j,k) = sum_local; + for (index_type di = i - d; di < i + d + 1; di++) { + for (index_type dj = j - d; dj < j + d + 1; dj++) { + for (index_type dk = k - d; dk < k + d + 1; dk++) { + sum_local += s(di, dj, dk); + } + } + } + o(i, j, k) = sum_local; } } } benchmark::ClobberMemory(); } - size_t num_inner_elements = (s.extent(0)-d) * (s.extent(1)-d) * (s.extent(2)-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); + size_t num_inner_elements = + (s.extent(0) - d) * (s.extent(1) - d) * (s.extent(2) - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); } MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Stencil_3D, right_, rmdspan, 80, 80, 80); MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Stencil_3D, left_, lmdspan, 80, 80, 80); @@ -85,13 +90,13 @@ MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Stencil_3D, left_, lmdspan, 400, 400, 400); //================================================================================ template -void BM_Raw_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); - T* s_ptr = nullptr; + T* s_ptr = nullptr; auto buffer_s = std::make_unique(buffer_size); { auto s = MDSpan{buffer_s.get(), x, y, z}; @@ -99,7 +104,7 @@ void BM_Raw_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ s_ptr = s.data_handle(); } - T* o_ptr = nullptr; + T* o_ptr = nullptr; auto buffer_o = std::make_unique(buffer_size); { auto o = MDSpan{buffer_o.get(), x, y, z}; @@ -111,27 +116,32 @@ void BM_Raw_Stencil_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ for (auto _ : state) { benchmark::DoNotOptimize(o_ptr); - for(size_t i = d; i < x-d; i ++) { - for(size_t j = d; j < y-d; j ++) { - for(size_t k = d; k < z-d; k ++) { + for (size_t i = d; i < x - d; i++) { + for (size_t j = d; j < y - d; j++) { + for (size_t k = d; k < z - d; k++) { value_type sum_local = 0; - for(size_t di = i-d; di < i+d+1; di++) { - for(size_t dj = j-d; dj < j+d+1; dj++) { - for(size_t dk = k-d; dk < k+d+1; dk++) { - sum_local += s_ptr[dk + dj*z + di*z*y]; - }}} - o_ptr[k + j*z + i*z*y] = sum_local; + for (size_t di = i - d; di < i + d + 1; di++) { + for (size_t dj = j - d; dj < j + d + 1; dj++) { + for (size_t dk = k - d; dk < k + d + 1; dk++) { + sum_local += s_ptr[dk + dj * z + di * z * y]; + } + } + } + o_ptr[k + j * z + i * z * y] = sum_local; } } } benchmark::ClobberMemory(); } - size_t num_inner_elements = (x-d) * (y-d) * (z-d); - size_t stencil_num = (2*d+1) * (2*d+1) * (2*d+1); - state.SetBytesProcessed( num_inner_elements * stencil_num * sizeof(value_type) * state.iterations()); + size_t num_inner_elements = (x - d) * (y - d) * (z - d); + size_t stencil_num = (2 * d + 1) * (2 * d + 1) * (2 * d + 1); + state.SetBytesProcessed(num_inner_elements * stencil_num * + sizeof(value_type) * state.iterations()); } -BENCHMARK_CAPTURE(BM_Raw_Stencil_3D_right, size_80_80_80, int(), size_t(80), size_t(80), size_t(80)); -BENCHMARK_CAPTURE(BM_Raw_Stencil_3D_right, size_400_400_400, int(), size_t(400), size_t(400), size_t(400)); +BENCHMARK_CAPTURE(BM_Raw_Stencil_3D_right, size_80_80_80, int(), size_t(80), + size_t(80), size_t(80)); +BENCHMARK_CAPTURE(BM_Raw_Stencil_3D_right, size_400_400_400, int(), size_t(400), + size_t(400), size_t(400)); //================================================================================ diff --git a/benchmarks/sum/openmp/sum_3d_openmp.cpp b/benchmarks/sum/openmp/sum_3d_openmp.cpp index 6e6c954f..8a25e592 100644 --- a/benchmarks/sum/openmp/sum_3d_openmp.cpp +++ b/benchmarks/sum/openmp/sum_3d_openmp.cpp @@ -27,29 +27,31 @@ using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template void BM_MDSpan_Sum_3D_OpenMP(benchmark::State& state, MDSpan, DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; - int repeats = s.size() > (100*100*100) ? 50 : 1000; + int repeats = s.size() > (100 * 100 * 100) ? 50 : 1000; mdspan_benchmark::fill_random(s); for (auto _ : state) { - #pragma omp parallel default(none) shared(repeats, s) +#pragma omp parallel default(none) shared(repeats, s) { for (int r = 0; r < repeats; ++r) { value_type sum = 0; - for (index_type i = omp_get_thread_num(); i < s.extent(0); i += omp_get_num_threads()) { + for (index_type i = omp_get_thread_num(); i < s.extent(0); + i += omp_get_num_threads()) { for (index_type j = 0; j < s.extent(1); ++j) { for (index_type k = 0; k < s.extent(2); ++k) { sum += s(i, j, k); @@ -62,33 +64,35 @@ void BM_MDSpan_Sum_3D_OpenMP(benchmark::State& state, MDSpan, DynSizes... dyn) { } } } - state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations() * repeats); + state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations() * + repeats); state.counters["repeats"] = repeats; } MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_OpenMP, left_, lmdspan, 20, 20, 20); MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_OpenMP, right_, rmdspan, 20, 20, 20); MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_OpenMP, left_, lmdspan, 200, 200, 200); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_OpenMP, right_, rmdspan, 200, 200, 200); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_OpenMP, right_, rmdspan, 200, 200, + 200); //================================================================================ template -void BM_MDSpan_Sum_3D_loop_OpenMP(benchmark::State& state, MDSpan, DynSizes... dyn) { +void BM_MDSpan_Sum_3D_loop_OpenMP(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); auto sums_buffer = std::make_unique(omp_get_max_threads()); - auto* sum = sums_buffer.get(); + auto* sum = sums_buffer.get(); for (auto _ : state) { auto sbv = sums_buffer.get(); - auto sh = s.data_handle(); + auto sh = s.data_handle(); benchmark::DoNotOptimize(sbv); benchmark::DoNotOptimize(sh); - #pragma omp parallel for default(none) shared(s, sum) +#pragma omp parallel for default(none) shared(s, sum) for (index_type i = 0; i < s.extent(0); ++i) { for (index_type j = 0; j < s.extent(1); ++j) { for (index_type k = 0; k < s.extent(2); ++k) { @@ -100,34 +104,39 @@ void BM_MDSpan_Sum_3D_loop_OpenMP(benchmark::State& state, MDSpan, DynSizes... d } state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations()); } -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_loop_OpenMP, right_, rmdspan, 200, 200, 200); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_loop_OpenMP, left_, lmdspan, 200, 200, 200); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_loop_OpenMP, right_, rmdspan, 200, 200, + 200); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_loop_OpenMP, left_, lmdspan, 200, 200, + 200); //================================================================================ template -void BM_Raw_Sum_3D_OpenMP(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { +void BM_Raw_Sum_3D_OpenMP(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = Kokkos::mdspan>{ + buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } - int repeats = x*y*z > (100*100*100) ? 50 : 1000; + int repeats = x * y * z > (100 * 100 * 100) ? 50 : 1000; T* data = buffer.get(); for (auto _ : state) { - #pragma omp parallel default(none) shared(data,x,y,z,repeats) +#pragma omp parallel default(none) shared(data, x, y, z, repeats) { for (int r = 0; r < repeats; ++r) { T sum = 0; benchmark::DoNotOptimize(sum); benchmark::DoNotOptimize(data); - for (index_type i = omp_get_thread_num(); i < x; i += omp_get_num_threads()) { + for (index_type i = omp_get_thread_num(); i < x; + i += omp_get_num_threads()) { for (index_type j = 0; j < y; ++j) { for (index_type k = 0; k < z; ++k) { - sum += data[k + j*z + i*z*y]; + sum += data[k + j * z + i * z * y]; } } } @@ -138,13 +147,8 @@ void BM_Raw_Sum_3D_OpenMP(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) state.SetBytesProcessed(x * y * z * sizeof(T) * state.iterations() * repeats); state.counters["repeats"] = repeats; } -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_OpenMP, size_20_20_20, int(), 20, 20, 20 -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_OpenMP, size_200_200_200, int(), 200, 200, 200 -); - +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_OpenMP, size_20_20_20, int(), 20, 20, 20); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_OpenMP, size_200_200_200, int(), 200, 200, 200); //================================================================================ diff --git a/benchmarks/sum/sum_3d_common.hpp b/benchmarks/sum/sum_3d_common.hpp index e38ec165..6899cb86 100644 --- a/benchmarks/sum/sum_3d_common.hpp +++ b/benchmarks/sum/sum_3d_common.hpp @@ -20,20 +20,22 @@ #include "fill.hpp" -namespace KokkosEx = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; +namespace KokkosEx = + MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; template void BM_Raw_Sum_1D(benchmark::State& state, T, Size size) { auto buffer = std::make_unique(size); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), size}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), size}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); for (auto _ : state) { T sum = 0; - for(Size i = 0; i < size; ++i) { + for (Size i = 0; i < size; ++i) { sum += data[i]; } benchmark::DoNotOptimize(sum); @@ -45,8 +47,8 @@ void BM_Raw_Sum_1D(benchmark::State& state, T, Size size) { //============================================================================== template -void BM_Raw_Sum_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - +void BM_Raw_Sum_3D_right(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { benchmark::DoNotOptimize(x); benchmark::DoNotOptimize(y); benchmark::DoNotOptimize(z); @@ -54,19 +56,19 @@ void BM_Raw_Sum_3D_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); - for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(SizeX i = 0; i < x; ++i) { - for(SizeY j = 0; j < y; ++j) { - for(SizeZ k = 0; k < z; ++k) { - sum += data[k + j*z + i*z*y]; + for (SizeX i = 0; i < x; ++i) { + for (SizeY j = 0; j < y; ++j) { + for (SizeZ k = 0; k < z; ++k) { + sum += data[k + j * z + i * z * y]; } } } @@ -83,17 +85,18 @@ void BM_Raw_Sum_3D_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(SizeZ k = 0; k < z; ++k) { - for(SizeY j = 0; j < y; ++j) { - for(SizeX i = 0; i < x; ++i) { - sum += data[i + j*x + k*x*y]; + for (SizeZ k = 0; k < z; ++k) { + for (SizeY j = 0; j < y; ++j) { + for (SizeX i = 0; i < x; ++i) { + sum += data[i + j * x + k * x * y]; } } } @@ -106,11 +109,13 @@ void BM_Raw_Sum_3D_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { //================================================================================ template -void BM_Raw_Sum_3D_right_iter_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { +void BM_Raw_Sum_3D_right_iter_left(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } @@ -123,10 +128,10 @@ void BM_Raw_Sum_3D_right_iter_left(benchmark::State& state, T, SizeX x, SizeY y, for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(SizeZ k = 0; k < z; ++k) { - for(SizeY j = 0; j < y; ++j) { - for(SizeX i = 0; i < x; ++i) { - sum += data[k + j*z + i*z*y]; + for (SizeZ k = 0; k < z; ++k) { + for (SizeY j = 0; j < y; ++j) { + for (SizeX i = 0; i < x; ++i) { + sum += data[k + j * z + i * z * y]; } } } @@ -142,24 +147,24 @@ void BM_Raw_Sum_3D_right_iter_left(benchmark::State& state, T, SizeX x, SizeY y, template void BM_Raw_Static_Sum_3D_right(benchmark::State& state, T, - std::integral_constant, - std::integral_constant, - std::integral_constant -) { + std::integral_constant, + std::integral_constant, + std::integral_constant) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(size_t i = 0; i < x; ++i) { - for(size_t j = 0; j < y; ++j) { - for(size_t k = 0; k < z; ++k) { - sum += data[k + j*z + i*z*y]; + for (size_t i = 0; i < x; ++i) { + for (size_t j = 0; j < y; ++j) { + for (size_t k = 0; k < z; ++k) { + sum += data[k + j * z + i * z * y]; } } } @@ -173,24 +178,24 @@ void BM_Raw_Static_Sum_3D_right(benchmark::State& state, T, template void BM_Raw_Static_Sum_3D_left(benchmark::State& state, T, - std::integral_constant, - std::integral_constant, - std::integral_constant -) { + std::integral_constant, + std::integral_constant, + std::integral_constant) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(size_t k = 0; k < z; ++k) { - for(size_t j = 0; j < y; ++j) { - for(size_t i = 0; i < x; ++i) { - sum += data[i + j*x + k*x*y]; + for (size_t k = 0; k < z; ++k) { + for (size_t j = 0; j < y; ++j) { + for (size_t i = 0; i < x; ++i) { + sum += data[i + j * x + k * x * y]; } } } @@ -204,24 +209,24 @@ void BM_Raw_Static_Sum_3D_left(benchmark::State& state, T, template void BM_Raw_Static_Sum_3D_right_iter_left(benchmark::State& state, T, - std::integral_constant, - std::integral_constant, - std::integral_constant -) { + std::integral_constant, + std::integral_constant, + std::integral_constant) { auto buffer = std::make_unique(x * y * z); { // just for setup... - auto wrapped = Kokkos::mdspan>{buffer.get(), x*y*z}; + auto wrapped = + Kokkos::mdspan>{buffer.get(), x * y * z}; mdspan_benchmark::fill_random(wrapped); } T* data = buffer.get(); for (auto _ : state) { benchmark::DoNotOptimize(data); T sum = 0; - for(size_t k = 0; k < z; ++k) { - for(size_t j = 0; j < y; ++j) { - for(size_t i = 0; i < x; ++i) { - sum += data[k + j*z + i*z*y]; + for (size_t k = 0; k < z; ++k) { + for (size_t j = 0; j < y; ++j) { + for (size_t i = 0; i < x; ++i) { + sum += data[k + j * z + i * z * y]; } } } @@ -231,5 +236,4 @@ void BM_Raw_Static_Sum_3D_right_iter_left(benchmark::State& state, T, state.SetBytesProcessed(x * y * z * sizeof(T) * state.iterations()); } - -#endif // MDSPAN_BENCHMARKS_SUM_SUM_3D_COMMON_HPP +#endif // MDSPAN_BENCHMARKS_SUM_SUM_3D_COMMON_HPP diff --git a/benchmarks/sum/sum_3d_left.cpp b/benchmarks/sum/sum_3d_left.cpp index 1a7e1f4b..e5aee75d 100644 --- a/benchmarks/sum/sum_3d_left.cpp +++ b/benchmarks/sum/sum_3d_left.cpp @@ -25,25 +25,26 @@ using index_type = int; //================================================================================ template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template void BM_MDSpan_Sum_3D_left(benchmark::State& state, MDSpan, DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); for (auto _ : state) { value_type sum = 0; for (index_type k = 0; k < s.extent(2); ++k) { for (index_type j = 0; j < s.extent(1); ++j) { - for(index_type i = 0; i < s.extent(0); ++i) { + for (index_type i = 0; i < s.extent(0); ++i) { sum += s(i, j, k); } } @@ -61,35 +62,22 @@ MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_left, right_, rmdspan, 200, 200, 200); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Sum_1D, size_8000, int(), 8000 -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_1D, size_8000000, int(), 8000000 -); +BENCHMARK_CAPTURE(BM_Raw_Sum_1D, size_8000, int(), 8000); +BENCHMARK_CAPTURE(BM_Raw_Sum_1D, size_8000000, int(), 8000000); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_left, size_20_20_20, int(), 20, 20, 20 -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_left, size_200_200_200, int(), 200, 200, 200 -); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_left, size_20_20_20, int(), 20, 20, 20); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_left, size_200_200_200, int(), 200, 200, 200); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_left, size_20_20_20, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_left, size_200_200_200, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); - +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_left, size_20_20_20, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_left, size_200_200_200, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); //================================================================================ diff --git a/benchmarks/sum/sum_3d_right.cpp b/benchmarks/sum/sum_3d_right.cpp index d630309e..a835d8f0 100644 --- a/benchmarks/sum/sum_3d_right.cpp +++ b/benchmarks/sum/sum_3d_right.cpp @@ -26,19 +26,19 @@ using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template void BM_MDSpan_Sum_3D_right(benchmark::State& state, MDSpan, DynSizes... dyn) { - using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); @@ -48,7 +48,7 @@ void BM_MDSpan_Sum_3D_right(benchmark::State& state, MDSpan, DynSizes... dyn) { auto sdata = s.data_handle(); benchmark::DoNotOptimize(sdata); value_type sum = 0; - for(index_type i = 0; i < s.extent(0); ++i) { + for (index_type i = 0; i < s.extent(0); ++i) { for (index_type j = 0; j < s.extent(1); ++j) { for (index_type k = 0; k < s.extent(2); ++k) { sum += s(i, j, k); @@ -67,34 +67,25 @@ MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_3D_right, left_, lmdspan, 200, 200, 200); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right, size_20_20_20, int(), size_t(20), size_t(20), size_t(20) -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right, size_200_200_200, int(), size_t(200), size_t(200), size_t(200) -); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right, size_20_20_20, int(), size_t(20), + size_t(20), size_t(20)); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right, size_200_200_200, int(), size_t(200), + size_t(200), size_t(200)); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right, size_20_20_20, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right, size_200_200_200, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); - +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right, size_20_20_20, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right, size_200_200_200, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Sum_1D, size_8000, int(), 8000 -); +BENCHMARK_CAPTURE(BM_Raw_Sum_1D, size_8000, int(), 8000); //================================================================================ diff --git a/benchmarks/sum/sum_submdspan_right.cpp b/benchmarks/sum/sum_submdspan_right.cpp index 8ee0fb0f..50b4a516 100644 --- a/benchmarks/sum/sum_submdspan_right.cpp +++ b/benchmarks/sum/sum_submdspan_right.cpp @@ -26,19 +26,20 @@ using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template -void BM_MDSpan_Sum_Subspan_3D_right(benchmark::State& state, MDSpan, DynSizes... dyn) { - +void BM_MDSpan_Sum_Subspan_3D_right(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); @@ -47,10 +48,11 @@ void BM_MDSpan_Sum_Subspan_3D_right(benchmark::State& state, MDSpan, DynSizes... benchmark::DoNotOptimize(s); auto sdata = s.data_handle(); benchmark::DoNotOptimize(sdata); - value_type sum = 0; + value_type sum = 0; using index_type = typename MDSpan::index_type; - for(index_type i = 0; i < s.extent(0); ++i) { - auto sub_i = Kokkos::submdspan(s, i, Kokkos::full_extent, Kokkos::full_extent); + for (index_type i = 0; i < s.extent(0); ++i) { + auto sub_i = + Kokkos::submdspan(s, i, Kokkos::full_extent, Kokkos::full_extent); for (index_type j = 0; j < s.extent(1); ++j) { auto sub_i_j = Kokkos::submdspan(sub_i, j, Kokkos::full_extent); for (index_type k = 0; k < s.extent(2); ++k) { @@ -63,92 +65,78 @@ void BM_MDSpan_Sum_Subspan_3D_right(benchmark::State& state, MDSpan, DynSizes... } state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations()); } -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, right_, rmdspan, 20, 20, 20); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, left_, lmdspan, 20, 20, 20); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, right_, rmdspan, 200, 200, 200); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, left_, lmdspan, 200, 200, 200); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, right_, rmdspan, 20, 20, + 20); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, left_, lmdspan, 20, 20, + 20); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, right_, rmdspan, 200, + 200, 200); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_Sum_Subspan_3D_right, left_, lmdspan, 200, + 200, 200); //================================================================================ -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right, size_20_20_20, int(), size_t(20), size_t(20), size_t(20) -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right, size_200_200_200, int(), size_t(200), size_t(200), size_t(200) -); - -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right, size_20_20_20, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right, size_200_200_200, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); - -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right_iter_left, size_20_20_20, int(), 20, 20, 20 -); -BENCHMARK_CAPTURE( - BM_Raw_Sum_3D_right_iter_left, size_200_200_200, int(), 200, 200, 200 -); -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right_iter_left, size_20_20_20, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); -BENCHMARK_CAPTURE( - BM_Raw_Static_Sum_3D_right_iter_left, size_200_200_200, int(), - std::integral_constant{}, - std::integral_constant{}, - std::integral_constant{} -); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right, size_20_20_20, int(), size_t(20), + size_t(20), size_t(20)); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right, size_200_200_200, int(), size_t(200), + size_t(200), size_t(200)); + +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right, size_20_20_20, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right, size_200_200_200, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); + +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right_iter_left, size_20_20_20, int(), 20, 20, + 20); +BENCHMARK_CAPTURE(BM_Raw_Sum_3D_right_iter_left, size_200_200_200, int(), 200, + 200, 200); +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right_iter_left, size_20_20_20, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); +BENCHMARK_CAPTURE(BM_Raw_Static_Sum_3D_right_iter_left, size_200_200_200, int(), + std::integral_constant{}, + std::integral_constant{}, + std::integral_constant{}); //================================================================================ namespace _impl { template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr T&& _repeated_with(T&& v) noexcept { return std::forward(v); } +MDSPAN_FORCE_INLINE_FUNCTION constexpr T&& _repeated_with(T&& v) noexcept { + return std::forward(v); +} template -MDSPAN_FORCE_INLINE_FUNCTION -MDSPAN_IMPL_CONSTEXPR_14 void _do_sum_submdspan( - T& sum, - Kokkos::mdspan, Rest...> s -) -{ +MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 void _do_sum_submdspan( + T& sum, Kokkos::mdspan, Rest...> s) { sum += s(); } template -MDSPAN_FORCE_INLINE_FUNCTION -MDSPAN_IMPL_CONSTEXPR_14 void _do_sum_submdspan( - T& sum, - Kokkos::mdspan, Rest...> s -) -{ - for(index_type i = 0; i < s.extent(0); ++i) { - _impl::_do_sum_submdspan(sum, Kokkos::submdspan( - s, i, _repeated_with(Kokkos::full_extent)...) - ); +MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 void _do_sum_submdspan( + T& sum, + Kokkos::mdspan, Rest...> s) { + for (index_type i = 0; i < s.extent(0); ++i) { + _impl::_do_sum_submdspan( + sum, Kokkos::submdspan( + s, i, _repeated_with(Kokkos::full_extent)...)); } } -} // end namespace _impl +} // end namespace _impl template -void BM_MDSpan_Sum_Subspan_MD_right(benchmark::State& state, MDSpan, DynSizes... dyn) { +void BM_MDSpan_Sum_Subspan_MD_right(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; - auto buffer = std::make_unique( - MDSpan{nullptr, dyn...}.mapping().required_span_size() - ); + auto buffer = std::make_unique( + MDSpan{nullptr, dyn...}.mapping().required_span_size()); auto s = MDSpan{buffer.get(), dyn...}; mdspan_benchmark::fill_random(s); for (auto _ : state) { @@ -161,38 +149,33 @@ void BM_MDSpan_Sum_Subspan_MD_right(benchmark::State& state, MDSpan, DynSizes... state.SetBytesProcessed(s.size() * sizeof(value_type) * state.iterations()); } +BENCHMARK_CAPTURE(BM_MDSpan_Sum_Subspan_MD_right, fixed_10D_size_1024, + Kokkos::mdspan>{nullptr}); +BENCHMARK_CAPTURE(BM_MDSpan_Sum_Subspan_MD_right, dyn_10D_size_1024, + Kokkos::mdspan>{}, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2); BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, fixed_10D_size_1024, - Kokkos::mdspan>{nullptr} -); -BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, dyn_10D_size_1024, - Kokkos::mdspan>{}, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2 -); -BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, fixed5_dyn5_10D_alternate_size_1024, - Kokkos::mdspan>{}, - 2, 2, 2, 2, 2 -); -BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, fixed8_dyn2_10D_alternate_size_1024, - Kokkos::mdspan>{}, - 2, 2 -); -BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, fixed_5D_size_1024, - Kokkos::mdspan>{nullptr} -); + BM_MDSpan_Sum_Subspan_MD_right, fixed5_dyn5_10D_alternate_size_1024, + Kokkos::mdspan< + int, + Kokkos::extents>{}, + 2, 2, 2, 2, 2); BENCHMARK_CAPTURE( - BM_MDSpan_Sum_Subspan_MD_right, dyn_5D_size_1024, - Kokkos::mdspan>{}, - 4, 4, 4, 4, 4 -); + BM_MDSpan_Sum_Subspan_MD_right, fixed8_dyn2_10D_alternate_size_1024, + Kokkos::mdspan< + int, Kokkos::extents>{}, + 2, 2); BENCHMARK_CAPTURE( - BM_Raw_Sum_1D, size_1024, int(), 1024 -); + BM_MDSpan_Sum_Subspan_MD_right, fixed_5D_size_1024, + Kokkos::mdspan>{nullptr}); +BENCHMARK_CAPTURE(BM_MDSpan_Sum_Subspan_MD_right, dyn_5D_size_1024, + Kokkos::mdspan>{}, 4, 4, + 4, 4, 4); +BENCHMARK_CAPTURE(BM_Raw_Sum_1D, size_1024, int(), 1024); //================================================================================ diff --git a/benchmarks/tiny_matrix_add/openmp/tiny_matrix_add_openmp.cpp b/benchmarks/tiny_matrix_add/openmp/tiny_matrix_add_openmp.cpp index 5fd228f6..ffd998d2 100644 --- a/benchmarks/tiny_matrix_add/openmp/tiny_matrix_add_openmp.cpp +++ b/benchmarks/tiny_matrix_add/openmp/tiny_matrix_add_openmp.cpp @@ -32,23 +32,25 @@ static constexpr int global_repeat = 1; using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; -void throw_runtime_exception(const std::string &msg) { +void throw_runtime_exception(const std::string& msg) { std::ostringstream o; o << msg; throw std::runtime_error(o.str()); } -template +template void OpenMP_first_touch_3D(MDSpan s) { - #pragma omp parallel for - for(index_type i = 0; i < s.extent(0); i ++) { - for(index_type j = 0; j < s.extent(1); j ++) { - for(index_type k = 0; k < s.extent(2); k ++) { - s(i,j,k) = 0; +#pragma omp parallel for + for (index_type i = 0; i < s.extent(0); i++) { + for (index_type j = 0; j < s.extent(1); j++) { + for (index_type k = 0; k < s.extent(2); k++) { + s(i, j, k) = 0; } } } @@ -57,22 +59,21 @@ void OpenMP_first_touch_3D(MDSpan s) { //================================================================================ template -void BM_MDSpan_OpenMP_noloop_TinyMatrixSum(benchmark::State& state, MDSpan, DynSizes... dyn) { - +void BM_MDSpan_OpenMP_noloop_TinyMatrixSum(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, dyn...}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), dyn...}; + auto s = MDSpan{buffer_s.get(), dyn...}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), dyn...}; + auto o = MDSpan{buffer_o.get(), dyn...}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); - for (auto _ : state) { auto oh = o.data_handle(); auto sh = s.data_handle(); @@ -80,9 +81,9 @@ void BM_MDSpan_OpenMP_noloop_TinyMatrixSum(benchmark::State& state, MDSpan, DynS benchmark::DoNotOptimize(sh); #pragma omp parallel { - auto chunk_size = s.extent(0) / omp_get_num_threads(); + auto chunk_size = s.extent(0) / omp_get_num_threads(); auto chunk_start = chunk_size * omp_get_thread_num(); - auto extra = s.extent(0) % chunk_size; + auto extra = s.extent(0) % chunk_size; if (omp_get_thread_num() < extra) { chunk_size += 1; chunk_start += omp_get_thread_num(); @@ -103,37 +104,40 @@ void BM_MDSpan_OpenMP_noloop_TinyMatrixSum(benchmark::State& state, MDSpan, DynS benchmark::ClobberMemory(); } size_t num_elements = (s.extent(0) * s.extent(1) * s.extent(2)); - state.SetBytesProcessed( num_elements * 3 * sizeof(value_type) * state.iterations() * global_repeat); + state.SetBytesProcessed(num_elements * 3 * sizeof(value_type) * + state.iterations() * global_repeat); state.counters["repeats"] = global_repeat; } -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_noloop_TinyMatrixSum, right_, rmdspan, 1000000, 3, 3); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_noloop_TinyMatrixSum, left_, lmdspan, 1000000, 3, 3); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_noloop_TinyMatrixSum, right_, rmdspan, + 1000000, 3, 3); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_OpenMP_noloop_TinyMatrixSum, left_, lmdspan, + 1000000, 3, 3); //================================================================================ template -void BM_MDSpan_OpenMP_TinyMatrixSum(benchmark::State& state, MDSpan, DynSizes... dyn) { - +void BM_MDSpan_OpenMP_TinyMatrixSum(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; using index_type = typename MDSpan::index_type; auto buffer_size = MDSpan{nullptr, dyn...}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), dyn...}; + auto s = MDSpan{buffer_s.get(), dyn...}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), dyn...}; + auto o = MDSpan{buffer_o.get(), dyn...}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); - #pragma omp parallel for - for(index_type i = 0; i < s.extent(0); i ++) { - for(int r = 0; r -void BM_Raw_Static_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_Static_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, + SizeX x, SizeY y, SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); - #pragma omp parallel for - for(SizeX i = 0; i < x; i ++) { - for(int r = 0; rUseRealTime(); +BENCHMARK_CAPTURE(BM_Raw_Static_OpenMP_TinyMatrixSum_right, size_1000000_3_3, + int(), 1000000, 3, 3) + ->UseRealTime(); template -void BM_Raw_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); #pragma omp parallel for - for(SizeX i = 0; i < x; i ++) { - for(int r = 0; rUseRealTime(); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_TinyMatrixSum_right, size_1000000_3_3, int(), + 1000000, 3, 3) + ->UseRealTime(); //================================================================================ template -void BM_Raw_Static_OpenMP_TinyMatrixSum_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_Static_OpenMP_TinyMatrixSum_left(benchmark::State& state, T, + SizeX x, SizeY y, SizeZ z) { + using MDSpan = + Kokkos::mdspan>; using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, x}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x}; + auto s = MDSpan{buffer_s.get(), x}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x}; + auto o = MDSpan{buffer_o.get(), x}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); - #pragma omp parallel for - for(SizeX i = 0; i < x; i ++) { - for(int r = 0; rUseRealTime(); +BENCHMARK_CAPTURE(BM_Raw_Static_OpenMP_TinyMatrixSum_left, size_1000000_3_3, + int(), 1000000, 3, 3) + ->UseRealTime(); //================================================================================ template -void BM_Raw_OpenMP_TinyMatrixSum_left(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_OpenMP_TinyMatrixSum_left(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = + Kokkos::mdspan>; using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, x}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x}; + auto s = MDSpan{buffer_s.get(), x}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x}; + auto o = MDSpan{buffer_o.get(), x}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); - #pragma omp parallel for - for(SizeX i = 0; i < x; i ++) { - for(int r = 0; rUseRealTime(); +BENCHMARK_CAPTURE(BM_Raw_OpenMP_TinyMatrixSum_left, size_1000000_3_3, int(), + 1000000, 3, 3) + ->UseRealTime(); template typename MDSpan::value_type*** make_3d_ptr_array(MDSpan s) { - static_assert(std::is_same::value,"Creating MD Ptr only works from mdspan with layout_right"); + static_assert( + std::is_same::value, + "Creating MD Ptr only works from mdspan with layout_right"); using value_type = typename MDSpan::value_type; using index_type = typename MDSpan::index_type; - value_type*** ptr= new value_type**[s.extent(0)]; - for(index_type i = 0; i void free_3d_ptr_array(T*** ptr, size_t extent_0) { - for(size_t i=0; i -void BM_RawMDPtr_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_RawMDPtr_OpenMP_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = + Kokkos::mdspan>; using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, x}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x}; + auto s = MDSpan{buffer_s.get(), x}; OpenMP_first_touch_3D(s); mdspan_benchmark::fill_random(s); T*** s_ptr = make_3d_ptr_array(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x}; + auto o = MDSpan{buffer_o.get(), x}; OpenMP_first_touch_3D(o); mdspan_benchmark::fill_random(o); T*** o_ptr = make_3d_ptr_array(o); - #pragma omp parallel for - for(SizeX i = 0; i < x; i ++) { - for(int r = 0; rUseRealTime(); - +BENCHMARK_CAPTURE(BM_RawMDPtr_OpenMP_TinyMatrixSum_right, size_1000000_3_3, + int(), 1000000, 3, 3) + ->UseRealTime(); //================================================================================ diff --git a/benchmarks/tiny_matrix_add/tiny_matrix_add.cpp b/benchmarks/tiny_matrix_add/tiny_matrix_add.cpp index ca1a320c..edf67a9e 100644 --- a/benchmarks/tiny_matrix_add/tiny_matrix_add.cpp +++ b/benchmarks/tiny_matrix_add/tiny_matrix_add.cpp @@ -25,24 +25,26 @@ using index_type = int; template -using lmdspan = Kokkos::mdspan, Kokkos::layout_left>; +using lmdspan = + Kokkos::mdspan, Kokkos::layout_left>; template -using rmdspan = Kokkos::mdspan, Kokkos::layout_right>; +using rmdspan = + Kokkos::mdspan, Kokkos::layout_right>; //================================================================================ template -void BM_MDSpan_TinyMatrixSum_right(benchmark::State& state, MDSpan, DynSizes... dyn) { - +void BM_MDSpan_TinyMatrixSum_right(benchmark::State& state, MDSpan, + DynSizes... dyn) { using value_type = typename MDSpan::value_type; auto buffer_size = MDSpan{nullptr, dyn...}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), dyn...}; + auto s = MDSpan{buffer_s.get(), dyn...}; mdspan_benchmark::fill_random(s); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), dyn...}; + auto o = MDSpan{buffer_o.get(), dyn...}; mdspan_benchmark::fill_random(o); for (auto _ : state) { @@ -52,67 +54,72 @@ void BM_MDSpan_TinyMatrixSum_right(benchmark::State& state, MDSpan, DynSizes... benchmark::DoNotOptimize(s); auto sdata = s.data_handle(); benchmark::DoNotOptimize(sdata); - for(index_type i = 0; i < s.extent(0); i ++) { - for(index_type j = 0; j < s.extent(1); j ++) { - for(index_type k = 0; k < s.extent(2); k ++) { - o(i,j,k) += s(i,j,k); + for (index_type i = 0; i < s.extent(0); i++) { + for (index_type j = 0; j < s.extent(1); j++) { + for (index_type k = 0; k < s.extent(2); k++) { + o(i, j, k) += s(i, j, k); } } } benchmark::ClobberMemory(); } size_t num_elements = (s.extent(0) * s.extent(1) * s.extent(2)); - state.SetBytesProcessed( num_elements * 3 * sizeof(value_type) * state.iterations() ); + state.SetBytesProcessed(num_elements * 3 * sizeof(value_type) * + state.iterations()); } -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_TinyMatrixSum_right, right_, lmdspan, 1000000, 3, 3); -MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_TinyMatrixSum_right, left_, lmdspan, 1000000, 3, 3); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_TinyMatrixSum_right, right_, lmdspan, 1000000, + 3, 3); +MDSPAN_BENCHMARK_ALL_3D(BM_MDSpan_TinyMatrixSum_right, left_, lmdspan, 1000000, + 3, 3); //================================================================================ template -void BM_Raw_Static_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - - using MDSpan = Kokkos::mdspan>; +void BM_Raw_Static_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, + SizeY y, SizeZ z) { + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; - auto buffer_size = MDSpan{nullptr, x,y,z}.mapping().required_span_size(); + auto buffer_size = MDSpan{nullptr, x, y, z}.mapping().required_span_size(); auto buffer_s = std::make_unique(buffer_size); - auto s = MDSpan{buffer_s.get(), x,y,z}; + auto s = MDSpan{buffer_s.get(), x, y, z}; mdspan_benchmark::fill_random(s); T* s_ptr = s.data_handle(); auto buffer_o = std::make_unique(buffer_size); - auto o = MDSpan{buffer_o.get(), x,y,z}; + auto o = MDSpan{buffer_o.get(), x, y, z}; mdspan_benchmark::fill_random(o); T* o_ptr = o.data_handle(); for (auto _ : state) { benchmark::DoNotOptimize(o_ptr); benchmark::DoNotOptimize(s_ptr); - for(index_type i = 0; i < 1000000; i ++) { - for(index_type j = 0; j < 3; j ++) { - for(index_type k = 0; k < 3; k ++) { - o_ptr[k + j*3 + i*3*3] += s_ptr[k + j*3 + i*3*3]; + for (index_type i = 0; i < 1000000; i++) { + for (index_type j = 0; j < 3; j++) { + for (index_type k = 0; k < 3; k++) { + o_ptr[k + j * 3 + i * 3 * 3] += s_ptr[k + j * 3 + i * 3 * 3]; } } } benchmark::ClobberMemory(); } size_t num_inner_elements = x * y * z; - state.SetBytesProcessed( num_inner_elements * 3 * sizeof(value_type) * state.iterations()); + state.SetBytesProcessed(num_inner_elements * 3 * sizeof(value_type) * + state.iterations()); } -BENCHMARK_CAPTURE(BM_Raw_Static_TinyMatrixSum_right, size_1000000_3_3, int(), 1000000, 3, 3); +BENCHMARK_CAPTURE(BM_Raw_Static_TinyMatrixSum_right, size_1000000_3_3, int(), + 1000000, 3, 3); //================================================================================ template -void BM_Raw_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, SizeZ z) { - +void BM_Raw_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, + SizeZ z) { benchmark::DoNotOptimize(x); benchmark::DoNotOptimize(y); benchmark::DoNotOptimize(z); - using MDSpan = Kokkos::mdspan>; + using MDSpan = Kokkos::mdspan>; using value_type = typename MDSpan::value_type; auto buffer_s = std::make_unique(x * y * z); @@ -132,19 +139,21 @@ void BM_Raw_TinyMatrixSum_right(benchmark::State& state, T, SizeX x, SizeY y, Si for (auto _ : state) { benchmark::DoNotOptimize(o_ptr); benchmark::DoNotOptimize(s_ptr); - for(SizeX i = 0; i < x; i ++) { - for(SizeY j = 0; j < y; j ++) { - for(SizeZ k = 0; k < z; k ++) { - o_ptr[k + j*z + i*z*y] += s_ptr[k + j*z + i*z*y]; + for (SizeX i = 0; i < x; i++) { + for (SizeY j = 0; j < y; j++) { + for (SizeZ k = 0; k < z; k++) { + o_ptr[k + j * z + i * z * y] += s_ptr[k + j * z + i * z * y]; } } } benchmark::ClobberMemory(); } size_t num_inner_elements = x * y * z; - state.SetBytesProcessed( num_inner_elements * y * sizeof(value_type) * state.iterations()); + state.SetBytesProcessed(num_inner_elements * y * sizeof(value_type) * + state.iterations()); } -BENCHMARK_CAPTURE(BM_Raw_TinyMatrixSum_right, size_1000000_3_3, int(), size_t(1000000), size_t(3), size_t(3)); +BENCHMARK_CAPTURE(BM_Raw_TinyMatrixSum_right, size_1000000_3_3, int(), + size_t(1000000), size_t(3), size_t(3)); //================================================================================ diff --git a/compilation_tests/ctest_common.hpp b/compilation_tests/ctest_common.hpp index 0c79a684..dc0a7083 100644 --- a/compilation_tests/ctest_common.hpp +++ b/compilation_tests/ctest_common.hpp @@ -22,8 +22,9 @@ #define MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS 0 -#define MDSPAN_STATIC_TEST(...) \ - static_assert(__VA_ARGS__, "MDSpan compile time test failed at " __FILE__ ":" MDSPAN_PP_STRINGIFY(__LINE__)) +#define MDSPAN_STATIC_TEST(...) \ + static_assert(__VA_ARGS__, "MDSpan compile time test failed at " __FILE__ \ + ":" MDSPAN_PP_STRINGIFY(__LINE__)) //============================================================================== // {{{1 @@ -35,17 +36,25 @@ #if MDSPAN_IMPL_USE_CONSTEXPR_14 -// A nice marker in the compiler output. Also, use std::is_constant_evaluated if we have it +// A nice marker in the compiler output. Also, use std::is_constant_evaluated if +// we have it #if __cpp_lib_is_constant_evaluated > 201811 -# define __________CONSTEXPR_ASSERTION_FAILED__________ \ - /* do something we can't do in constexpr like access an array out of bounds */ \ - if(std::is_constant_evaluated()) return __str[-!(checker(__val, _exp))]; \ - else { assert(checker(__val, _exp) && __str); return 0; } +#define __________CONSTEXPR_ASSERTION_FAILED__________ \ + /* do something we can't do in constexpr like access an array out of bounds \ + */ \ + if (std::is_constant_evaluated()) \ + return __str[-!(checker(__val, _exp))]; \ + else { \ + assert(checker(__val, _exp) && __str); \ + return 0; \ + } #else -# define __________CONSTEXPR_ASSERTION_FAILED__________ \ - /* try to protect from bad memory access... */ \ - char a[] = { 0 }; char b[] = { 0 }; char c[] = { 0 }; \ - return b[(a[0] + c[0] + -!(checker(__val, _exp)))]; +#define __________CONSTEXPR_ASSERTION_FAILED__________ \ + /* try to protect from bad memory access... */ \ + char a[] = {0}; \ + char b[] = {0}; \ + char c[] = {0}; \ + return b[(a[0] + c[0] + -!(checker(__val, _exp)))]; #endif // More sugar around the compiler output to print some values of things @@ -58,25 +67,34 @@ struct _____constexpr_assertion_failed_ { const char* __str; template constexpr char but_actual_value_was_(U __val) const { - // Put this macro here so that failures are easy to find in compiler output + // Put this macro here so that failures are easy to find in compiler + // output __________CONSTEXPR_ASSERTION_FAILED__________ } }; struct _check_eq { template - constexpr bool operator()(T val, U exp) const { return val == exp; } + constexpr bool operator()(T val, U exp) const { + return val == exp; + } }; struct _check_not_eq { template - constexpr bool operator()(T val, U exp) const { return val != exp; } + constexpr bool operator()(T val, U exp) const { + return val != exp; + } }; struct _check_less { template - constexpr bool operator()(T val, U exp) const { return val != exp; } + constexpr bool operator()(T val, U exp) const { + return val != exp; + } }; struct _check_greater { template - constexpr bool operator()(T val, U exp) const { return val != exp; } + constexpr bool operator()(T val, U exp) const { + return val != exp; + } }; template @@ -89,7 +107,8 @@ struct _____constexpr_assertion_failed_ { } template constexpr auto _rhs_expected_to_not_be_(T _exp) const { - return _expected_impl{_exp, _check_not_eq{}, _expr_string}; + return _expected_impl{_exp, _check_not_eq{}, + _expr_string}; } template constexpr auto _expected_to_be_less_than_(T _exp) const { @@ -97,30 +116,41 @@ struct _____constexpr_assertion_failed_ { } template constexpr auto _expected_to_be_greater_than_(T _exp) const { - return _expected_impl{_exp, _check_greater{}, _expr_string}; + return _expected_impl{_exp, _check_greater{}, + _expr_string}; } }; // Macros for the assertions themselves -#define constexpr_assert(...) \ - _____constexpr_assertion_failed_{#__VA_ARGS__}._expected_to_be_(true).but_actual_value_was_(__VA_ARGS__); - -#define constexpr_assert_equal(expr, ...) \ - _____constexpr_assertion_failed_{#__VA_ARGS__ "==" #expr}._rhs_expected_to_be_(expr).but_actual_value_was_((__VA_ARGS__)); - -#define constexpr_assert_not_equal(expr, ...) \ - _____constexpr_assertion_failed_{#__VA_ARGS__ "!=" #expr}._rhs_expected_to_not_be_(expr).but_actual_value_was_((__VA_ARGS__)); - -#define constexpr_assert_less_than(expr, ...) \ - _____constexpr_assertion_failed_{#__VA_ARGS__}._expected_to_be_less_than_(expr).but_actual_value_was_((__VA_ARGS__)); +#define constexpr_assert(...) \ + _____constexpr_assertion_failed_{#__VA_ARGS__} \ + ._expected_to_be_(true) \ + .but_actual_value_was_(__VA_ARGS__); + +#define constexpr_assert_equal(expr, ...) \ + _____constexpr_assertion_failed_{#__VA_ARGS__ "==" #expr} \ + ._rhs_expected_to_be_(expr) \ + .but_actual_value_was_((__VA_ARGS__)); + +#define constexpr_assert_not_equal(expr, ...) \ + _____constexpr_assertion_failed_{#__VA_ARGS__ "!=" #expr} \ + ._rhs_expected_to_not_be_(expr) \ + .but_actual_value_was_((__VA_ARGS__)); + +#define constexpr_assert_less_than(expr, ...) \ + _____constexpr_assertion_failed_{#__VA_ARGS__} \ + ._expected_to_be_less_than_(expr) \ + .but_actual_value_was_((__VA_ARGS__)); #define constexpr_assert_greater_than(expr, ...) \ - _____constexpr_assertion_failed_{#__VA_ARGS__}._expected_to_be_greater_than_(expr).but_actual_value_was_((__VA_ARGS__)); + _____constexpr_assertion_failed_{#__VA_ARGS__} \ + ._expected_to_be_greater_than_(expr) \ + .but_actual_value_was_((__VA_ARGS__)); -#endif // MDSPAN_IMPL_USE_CONSTEXPR_14 +#endif // MDSPAN_IMPL_USE_CONSTEXPR_14 // end assert-like macros that don't break constexpr }}}1 //============================================================================== // All tests need a main so that they'll link -int main() { } +int main() {} diff --git a/compilation_tests/ctest_compressed_pair_layout.cpp b/compilation_tests/ctest_compressed_pair_layout.cpp index b5b48f2d..8dc5c6c4 100644 --- a/compilation_tests/ctest_compressed_pair_layout.cpp +++ b/compilation_tests/ctest_compressed_pair_layout.cpp @@ -19,11 +19,7 @@ #include - -enum emptyness { - non_empty = false, - empty = true -}; +enum emptyness { non_empty = false, empty = true }; enum standard_layoutness { non_standard_layout = false, @@ -35,15 +31,14 @@ enum trivially_copyableness { trivially_copyable = true }; -template void test() { MDSPAN_STATIC_TEST(sizeof(T) == Size); MDSPAN_STATIC_TEST(std::is_empty::value == Empty); -#if (!defined(__INTEL_COMPILER) || (__INTEL_COMPILER>=1900)) && \ - (!defined(__clang__) || (defined(__GNUC__) && (__GNUC__> 10))) +#if (!defined(__INTEL_COMPILER) || (__INTEL_COMPILER >= 1900)) && \ + (!defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 10))) MDSPAN_STATIC_TEST(std::is_standard_layout::value == StandardLayout); #endif MDSPAN_STATIC_TEST(std::is_trivially_copyable::value == TriviallyCopyable); @@ -61,83 +56,89 @@ void instantiate_tests() { //============================================================================== // {{{1 #ifdef MDSPAN_IMPL_COMPILER_MSVC -test, 1, empty, non_standard_layout>(); -test, 1, empty, standard_layout>(); + test, 1, empty, non_standard_layout>(); + test, 1, empty, standard_layout>(); #else -test, 2, empty>(); -test, 1, empty>(); + test, 2, empty>(); + test, 1, empty>(); #endif -test, sizeof(int*), non_empty>(); -test, sizeof(int*), non_empty>(); -test, 2 * sizeof(int*), non_empty>(); + test, sizeof(int*), non_empty>(); + test, sizeof(int*), non_empty>(); + test, 2 * sizeof(int*), non_empty>(); // end compressed pair layout: 2 leaf elements }}}1 //============================================================================== //============================================================================== -// {{{1 +// +// {{{1 #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -test>, 3, empty>(); // Emulation can't handle this correctly. + test>, 3, + empty>(); // Emulation can't handle this correctly. #endif #ifdef MDSPAN_IMPL_COMPILER_MSVC -test>, 2, empty>(); + test>, 2, empty>(); #else -test>, 1, empty>(); + test>, 1, empty>(); #endif -test>, sizeof(int*), non_empty>(); -test>, sizeof(int*), non_empty>(); -test>, 2 * sizeof(int*), non_empty>(); + test>, sizeof(int*), non_empty>(); + test>, sizeof(int*), non_empty>(); + test>, 2 * sizeof(int*), non_empty>(); #ifdef MDSPAN_IMPL_COMPILER_MSVC -test>, 2 * sizeof(int*), non_empty>(); + test>, 2 * sizeof(int*), non_empty>(); #else -test>, sizeof(int*), non_empty>(); + test>, sizeof(int*), non_empty>(); #endif -test>, 2 * sizeof(int*), non_empty>(); -test>, 2 * sizeof(int*), non_empty>(); -test>, 3 * sizeof(int*), non_empty>(); + test>, 2 * sizeof(int*), non_empty>(); + test>, 2 * sizeof(int*), non_empty>(); + test>, 3 * sizeof(int*), non_empty>(); #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -test, E0>, 3, empty>(); // Emulation can't handle this correctly. + test, E0>, 3, + empty>(); // Emulation can't handle this correctly. #endif #ifdef MDSPAN_IMPL_COMPILER_MSVC -test, E2>, 2, empty>(); -test, int*>, 2 * sizeof(int*), non_empty>(); + test, E2>, 2, empty>(); + test, int*>, 2 * sizeof(int*), non_empty>(); #else -test, E2>, 1, empty>(); -test, int*>, sizeof(int*), non_empty>(); + test, E2>, 1, empty>(); + test, int*>, sizeof(int*), non_empty>(); #endif -test, E2>, sizeof(int*), non_empty>(); -test, int*>, 2 * sizeof(int*), non_empty>(); -test, E2>, sizeof(int*), non_empty>(); -test, int*>, 2 * sizeof(int*), non_empty>(); -test, E2>, 2 * sizeof(int*), non_empty>(); -test, int*>, 3 * sizeof(int*), non_empty>(); + test, E2>, sizeof(int*), non_empty>(); + test, int*>, 2 * sizeof(int*), non_empty>(); + test, E2>, sizeof(int*), non_empty>(); + test, int*>, 2 * sizeof(int*), non_empty>(); + test, E2>, 2 * sizeof(int*), non_empty>(); + test, int*>, 3 * sizeof(int*), non_empty>(); // end compressed pair layout: 1 nested pair, 3 leaf element }}}1 //============================================================================== //============================================================================== -// {{{1 +// +// {{{1 #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -test, CP>, 4, empty>(); // Emulation can't handle this correctly. + test, CP>, 4, + empty>(); // Emulation can't handle this correctly. #endif #ifdef MDSPAN_IMPL_COMPILER_MSVC -test, CP>, 3, empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 3 * sizeof(int*), non_empty>(); + test, CP>, 3, empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 3 * sizeof(int*), non_empty>(); #else -test, CP>, 1, empty>(); -test, CP>, sizeof(int*), non_empty>(); -test, CP>, sizeof(int*), non_empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 1, empty>(); + test, CP>, sizeof(int*), non_empty>(); + test, CP>, sizeof(int*), non_empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); #endif -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 3 * sizeof(int*), non_empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 2 * sizeof(int*), non_empty>(); -test, CP>, 3 * sizeof(int*), non_empty>(); -test, CP>, 3 * sizeof(int*), non_empty>(); -test, CP>, 3 * sizeof(int*), non_empty>(); -test, CP>, 4 * sizeof(int*), non_empty>(); -// end compressed pair layout: 2 nested pairs, 4 leaf elements }}}1 -//============================================================================== + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 3 * sizeof(int*), non_empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 2 * sizeof(int*), non_empty>(); + test, CP>, 3 * sizeof(int*), non_empty>(); + test, CP>, 3 * sizeof(int*), non_empty>(); + test, CP>, 3 * sizeof(int*), non_empty>(); + test, CP>, 4 * sizeof(int*), non_empty>(); + // end compressed pair layout: 2 nested pairs, 4 leaf elements + // }}}1 + //============================================================================== } diff --git a/compilation_tests/ctest_constexpr_dereference.cpp b/compilation_tests/ctest_constexpr_dereference.cpp index d81c5882..e314c627 100644 --- a/compilation_tests/ctest_constexpr_dereference.cpp +++ b/compilation_tests/ctest_constexpr_dereference.cpp @@ -17,23 +17,17 @@ #include - // Only works with newer constexpr #if defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 //============================================================================== -constexpr int -simple_static_sum_test_1(int add_to_row) { - int data[] = { - 1, 2, 3, - 4, 5, 6, - 7, 8, 9 - }; - auto s = Kokkos::mdspan>(data); +constexpr int simple_static_sum_test_1(int add_to_row) { + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + auto s = Kokkos::mdspan>(data); int result = 0; - for(int col = 0; col < 3; ++col) { - for(int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + for (int row = 0; row < 3; ++row) { result += MDSPAN_IMPL_OP(s, row, col) * (row + add_to_row); } } @@ -41,52 +35,42 @@ simple_static_sum_test_1(int add_to_row) { } MDSPAN_STATIC_TEST( - // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 - simple_static_sum_test_1(1) == 108 -); + // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 + simple_static_sum_test_1(1) == 108); MDSPAN_STATIC_TEST( - // -1 - 2 - 3 + 7 + 8 + 9 = 18 - simple_static_sum_test_1(-1) == 18 -); + // -1 - 2 - 3 + 7 + 8 + 9 = 18 + simple_static_sum_test_1(-1) == 18); -#if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER>=1800) +#if !defined(__INTEL_COMPILER) || (__INTEL_COMPILER >= 1800) MDSPAN_STATIC_TEST( - // -1 - 2 - 3 + 7 + 8 + 9 = 18 - Kokkos::mdspan>{nullptr}.extent(0) == 18 -); + // -1 - 2 - 3 + 7 + 8 + 9 = 18 + Kokkos::mdspan>{ + nullptr} + .extent(0) == 18); #endif //============================================================================== -constexpr int -simple_test_1d_constexpr_in_type() { - int data[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18 - }; - auto s = Kokkos::mdspan>(data); +constexpr int simple_test_1d_constexpr_in_type() { + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; + auto s = Kokkos::mdspan< + int, Kokkos::extents>(data); // 4 + 14 + 18 + 1 = 37 return s[3] + s[13] + s[17] + s[0]; } -MDSPAN_STATIC_TEST( - simple_test_1d_constexpr_in_type() == 37 -); +MDSPAN_STATIC_TEST(simple_test_1d_constexpr_in_type() == 37); //============================================================================== -constexpr int -simple_dynamic_sum_test_2(int add_to_row) { - int data[] = { - 1, 2, 3, 0, - 4, 5, 6, 0, - 7, 8, 9, 0 - }; - auto s = Kokkos::mdspan>(data, 3, 4); +constexpr int simple_dynamic_sum_test_2(int add_to_row) { + int data[] = {1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9, 0}; + auto s = Kokkos::mdspan>(data, 3, 4); int result = 0; - for(int col = 0; col < 3; ++col) { - for(int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + for (int row = 0; row < 3; ++row) { result += MDSPAN_IMPL_OP(s, row, col) * (row + add_to_row); } } @@ -94,32 +78,24 @@ simple_dynamic_sum_test_2(int add_to_row) { } MDSPAN_STATIC_TEST( - // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 - simple_dynamic_sum_test_2(1) == 108 -); + // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 + simple_dynamic_sum_test_2(1) == 108); MDSPAN_STATIC_TEST( - // -1 - 2 - 3 + 7 + 8 + 9 = 18 - simple_dynamic_sum_test_2(-1) == 18 -); + // -1 - 2 - 3 + 7 + 8 + 9 = 18 + simple_dynamic_sum_test_2(-1) == 18); //============================================================================== -constexpr int -simple_mixed_layout_left_sum_test_3(int add_to_row) { - int data[] = { - 1, 4, 7, - 2, 5, 8, - 3, 6, 9, - 0, 0, 0 - }; - auto s = Kokkos::mdspan< - int, Kokkos::extents, - Kokkos::layout_left - >(data, 3, 4); +constexpr int simple_mixed_layout_left_sum_test_3(int add_to_row) { + int data[] = {1, 4, 7, 2, 5, 8, 3, 6, 9, 0, 0, 0}; + auto s = Kokkos::mdspan< + int, + Kokkos::extents, + Kokkos::layout_left>(data, 3, 4); int result = 0; - for(int col = 0; col < 3; ++col) { - for(int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) { + for (int row = 0; row < 3; ++row) { result += MDSPAN_IMPL_OP(s, row, col) * (row + add_to_row); } } @@ -127,30 +103,31 @@ simple_mixed_layout_left_sum_test_3(int add_to_row) { } MDSPAN_STATIC_TEST( - // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 - simple_mixed_layout_left_sum_test_3(1) == 108 -); + // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 + simple_mixed_layout_left_sum_test_3(1) == 108); //============================================================================== -#if defined(MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS) && MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS +#if defined(MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS) && \ + MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS template constexpr auto _repeated_ptrdiff_t = Val; template -constexpr bool -multidimensional_single_element_stress_test_impl_2( - std::integer_sequence -) { +constexpr bool multidimensional_single_element_stress_test_impl_2( + std::integer_sequence) { using mdspan_t = Kokkos::mdspan< - int, Kokkos::extents...>, Layout>; + int, Kokkos::extents...>, Layout>; using dyn_mdspan_t = Kokkos::mdspan< - int, Kokkos::extents...>, Layout>; - int data[] = { 42 }; - auto s = mdspan_t(data); - auto s_dyn = dyn_mdspan_t(data, _repeated_ptrdiff_t<1, Idxs>...); - auto val = MDSPAN_IMPL_OP(s, _repeated_ptrdiff_t<0, Idxs>...); + int, + Kokkos::extents...>, + Layout>; + int data[] = {42}; + auto s = mdspan_t(data); + auto s_dyn = dyn_mdspan_t(data, _repeated_ptrdiff_t<1, Idxs>...); + auto val = MDSPAN_IMPL_OP(s, _repeated_ptrdiff_t<0, Idxs>...); auto val_dyn = MDSPAN_IMPL_OP(s_dyn, _repeated_ptrdiff_t<0, Idxs>...); constexpr_assert_equal(42, val); constexpr_assert_equal(42, val_dyn); @@ -158,116 +135,99 @@ multidimensional_single_element_stress_test_impl_2( } template -constexpr bool -multidimensional_single_element_stress_test_impl_1( - std::integer_sequence -) { +constexpr bool multidimensional_single_element_stress_test_impl_1( + std::integer_sequence) { return MDSPAN_IMPL_FOLD_AND( - multidimensional_single_element_stress_test_impl_2( - std::make_index_sequence{} - ) /* && ... */ + multidimensional_single_element_stress_test_impl_2( + std::make_index_sequence{}) /* && ... */ ); } template -constexpr bool -multidimensional_single_element_stress_test() { +constexpr bool multidimensional_single_element_stress_test() { return multidimensional_single_element_stress_test_impl_1( - std::make_index_sequence{} - ); + std::make_index_sequence{}); } MDSPAN_STATIC_TEST( - multidimensional_single_element_stress_test() -); + multidimensional_single_element_stress_test()); MDSPAN_STATIC_TEST( - multidimensional_single_element_stress_test() -); + multidimensional_single_element_stress_test()); template -constexpr bool -stress_test_2d_single_element_stress_test_impl_2( - std::integral_constant, - std::integral_constant -) { - using mdspan_t = Kokkos::mdspan< - int, Kokkos::extents, Layout>; - using dyn_mdspan_1_t = Kokkos::mdspan< - int, Kokkos::extents, Layout>; - using dyn_mdspan_2_t = Kokkos::mdspan< - int, Kokkos::extents, Layout>; +constexpr bool stress_test_2d_single_element_stress_test_impl_2( + std::integral_constant, + std::integral_constant) { + using mdspan_t = + Kokkos::mdspan, Layout>; + using dyn_mdspan_1_t = + Kokkos::mdspan, + Layout>; + using dyn_mdspan_2_t = + Kokkos::mdspan, + Layout>; using dyn_mdspan_t = Kokkos::mdspan< - int, Kokkos::extents, Layout>; - int data[Idx1*Idx2] = { }; - auto s = mdspan_t(data); - auto s1 = dyn_mdspan_1_t(data, Idx1); - auto s2 = dyn_mdspan_2_t(data, Idx2); - auto s12 = dyn_mdspan_t(data, Idx1, Idx2); - for(ptrdiff_t i = 0; i < Idx1; ++i) { - for(ptrdiff_t j = 0; j < Idx2; ++j) { - MDSPAN_IMPL_OP(s, i, j) = MDSPAN_IMPL_OP(s1, i, j) = MDSPAN_IMPL_OP(s2, i, j) = MDSPAN_IMPL_OP(s12, i, j) = 1; + int, + Kokkos::extents, + Layout>; + int data[Idx1 * Idx2] = {}; + auto s = mdspan_t(data); + auto s1 = dyn_mdspan_1_t(data, Idx1); + auto s2 = dyn_mdspan_2_t(data, Idx2); + auto s12 = dyn_mdspan_t(data, Idx1, Idx2); + for (ptrdiff_t i = 0; i < Idx1; ++i) { + for (ptrdiff_t j = 0; j < Idx2; ++j) { + MDSPAN_IMPL_OP(s, i, j) = MDSPAN_IMPL_OP(s1, i, j) = + MDSPAN_IMPL_OP(s2, i, j) = MDSPAN_IMPL_OP(s12, i, j) = 1; } } int result = 0; - for(ptrdiff_t i = 0; i < Idx1; ++i) { - for(ptrdiff_t j = 0; j < Idx2; ++j) { - result += MDSPAN_IMPL_OP(s, i, j) + MDSPAN_IMPL_OP(s1, i, j) + MDSPAN_IMPL_OP(s2, i, j) + MDSPAN_IMPL_OP(s12, i, j); + for (ptrdiff_t i = 0; i < Idx1; ++i) { + for (ptrdiff_t j = 0; j < Idx2; ++j) { + result += MDSPAN_IMPL_OP(s, i, j) + MDSPAN_IMPL_OP(s1, i, j) + + MDSPAN_IMPL_OP(s2, i, j) + MDSPAN_IMPL_OP(s12, i, j); } } result /= 4; - constexpr_assert_equal(Idx1*Idx2, result); + constexpr_assert_equal(Idx1 * Idx2, result); return result == Idx1 * Idx2; } template -constexpr bool -stress_test_2d_single_element_stress_test_impl_1( - std::integral_constant idx1, - std::integer_sequence -) -{ +constexpr bool stress_test_2d_single_element_stress_test_impl_1( + std::integral_constant idx1, + std::integer_sequence) { return MDSPAN_IMPL_FOLD_AND( - stress_test_2d_single_element_stress_test_impl_2( - idx1, std::integral_constant{} - ) /* && ... */ + stress_test_2d_single_element_stress_test_impl_2( + idx1, std::integral_constant{}) /* && ... */ ); } template -constexpr bool -stress_test_2d_single_element_stress_test_impl_0( - std::integer_sequence, - std::integer_sequence idxs2 -) -{ +constexpr bool stress_test_2d_single_element_stress_test_impl_0( + std::integer_sequence, + std::integer_sequence idxs2) { return MDSPAN_IMPL_FOLD_AND( - stress_test_2d_single_element_stress_test_impl_1( - std::integral_constant{}, idxs2 - ) /* && ... */ + stress_test_2d_single_element_stress_test_impl_1( + std::integral_constant{}, idxs2) /* && ... */ ); } template -constexpr bool -stress_test_2d_single_element_stress_test() { +constexpr bool stress_test_2d_single_element_stress_test() { return stress_test_2d_single_element_stress_test_impl_0( - std::make_index_sequence{}, - std::make_index_sequence{} - ); + std::make_index_sequence{}, std::make_index_sequence{}); } MDSPAN_STATIC_TEST( - stress_test_2d_single_element_stress_test() -); + stress_test_2d_single_element_stress_test()); MDSPAN_STATIC_TEST( - stress_test_2d_single_element_stress_test() -); + stress_test_2d_single_element_stress_test()); // Not evaluated at constexpr time to get around limits, but still compiled static bool _stress_2d_result = - stress_test_2d_single_element_stress_test() - && stress_test_2d_single_element_stress_test(); - -#endif // MDSPAN_DISABLE_EXPENSIVE_COMPILATION_TESTS + stress_test_2d_single_element_stress_test() && + stress_test_2d_single_element_stress_test(); +#endif // MDSPAN_DISABLE_EXPENSIVE_COMPILATION_TESTS -#endif //defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 +#endif // defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 diff --git a/compilation_tests/ctest_constexpr_layouts.cpp b/compilation_tests/ctest_constexpr_layouts.cpp index 9ee4d1fc..517895e3 100644 --- a/compilation_tests/ctest_constexpr_layouts.cpp +++ b/compilation_tests/ctest_constexpr_layouts.cpp @@ -17,23 +17,16 @@ #include - // Only works with newer constexpr #if defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 -constexpr std::ptrdiff_t -layout_stride_simple(int i) { - using map_t = Kokkos::layout_stride::template mapping< - Kokkos::extents - >; - return map_t(Kokkos::extents{}, std::array{1})(i); +constexpr std::ptrdiff_t layout_stride_simple(int i) { + using map_t = + Kokkos::layout_stride::template mapping >; + return map_t(Kokkos::extents{}, std::array{1})(i); } -MDSPAN_STATIC_TEST( - layout_stride_simple(0) == 0 -); -MDSPAN_STATIC_TEST( - layout_stride_simple(1) == 1 -); +MDSPAN_STATIC_TEST(layout_stride_simple(0) == 0); +MDSPAN_STATIC_TEST(layout_stride_simple(1) == 1); -#endif // MDSPAN_IMPL_USE_CONSTEXPR_14 +#endif // MDSPAN_IMPL_USE_CONSTEXPR_14 diff --git a/compilation_tests/ctest_constexpr_submdspan.cpp b/compilation_tests/ctest_constexpr_submdspan.cpp index fb778c53..76726c40 100644 --- a/compilation_tests/ctest_constexpr_submdspan.cpp +++ b/compilation_tests/ctest_constexpr_submdspan.cpp @@ -23,11 +23,10 @@ //============================================================================== // {{{1 -template -constexpr bool -dynamic_extent_1d() { +template +constexpr bool dynamic_extent_1d() { int data[] = {1, 2, 3, 4, 5}; - auto s = Kokkos::mdspan, Layout>(data, 5); + auto s = Kokkos::mdspan, Layout>(data, 5); int result = 0; for (size_t i = 0; i < s.extent(0); ++i) { auto ss = Kokkos::submdspan(s, i); @@ -41,21 +40,19 @@ dynamic_extent_1d() { MDSPAN_STATIC_TEST(dynamic_extent_1d()); MDSPAN_STATIC_TEST(dynamic_extent_1d()); - // end 1D dynamic extent ptrdiff_t submdspan }}}1 //============================================================================== //============================================================================== // {{{1 -template -constexpr bool -dynamic_extent_1d_all_slice() { +template +constexpr bool dynamic_extent_1d_all_slice() { int data[] = {1, 2, 3, 4, 5}; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>(data, 5); + auto s = Kokkos::mdspan, + Layout>(data, 5); int result = 0; - auto ss = Kokkos::submdspan(s, Kokkos::full_extent); + auto ss = Kokkos::submdspan(s, Kokkos::full_extent); for (size_t i = 0; i < s.extent(0); ++i) { result += MDSPAN_IMPL_OP(ss, i); } @@ -73,14 +70,14 @@ MDSPAN_STATIC_TEST(dynamic_extent_1d_all_slice()); //============================================================================== // {{{1 -template -constexpr bool -dynamic_extent_1d_pair_full() { +template +constexpr bool dynamic_extent_1d_pair_full() { int data[] = {1, 2, 3, 4, 5}; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>(data, 5); + auto s = Kokkos::mdspan, + Layout>(data, 5); int result = 0; - auto ss = Kokkos::submdspan(s, std::pair{0, 5}); + auto ss = + Kokkos::submdspan(s, std::pair{0, 5}); for (size_t i = 0; i < s.extent(0); ++i) { result += MDSPAN_IMPL_OP(ss, i); } @@ -91,16 +88,15 @@ dynamic_extent_1d_pair_full() { MDSPAN_STATIC_TEST(dynamic_extent_1d_pair_full()); MDSPAN_STATIC_TEST(dynamic_extent_1d_pair_full()); -template -constexpr bool -dynamic_extent_1d_pair_each() { +template +constexpr bool dynamic_extent_1d_pair_each() { int data[] = {1, 2, 3, 4, 5}; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>(data, 5); + auto s = Kokkos::mdspan, + Layout>(data, 5); int result = 0; for (size_t i = 0; i < s.extent(0); ++i) { - auto ss = Kokkos::submdspan(s, - std::pair{i, i+1}); + auto ss = Kokkos::submdspan( + s, std::pair{i, i + 1}); result += MDSPAN_IMPL_OP(ss, 0); } constexpr_assert_equal(15, result); @@ -119,14 +115,14 @@ MDSPAN_STATIC_TEST(dynamic_extent_1d_pair_each()); //============================================================================== // {{{1 -template -constexpr bool -dynamic_extent_1d_all_three() { +template +constexpr bool dynamic_extent_1d_all_three() { int data[] = {1, 2, 3, 4, 5}; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>(data, 5); - auto s1 = Kokkos::submdspan(s, std::pair{0, 5}); - auto s2 = Kokkos::submdspan(s1, Kokkos::full_extent); + auto s = Kokkos::mdspan, + Layout>(data, 5); + auto s1 = + Kokkos::submdspan(s, std::pair{0, 5}); + auto s2 = Kokkos::submdspan(s1, Kokkos::full_extent); int result = 0; for (size_t i = 0; i < s.extent(0); ++i) { auto ss = Kokkos::submdspan(s2, i); @@ -145,16 +141,16 @@ MDSPAN_STATIC_TEST(dynamic_extent_1d_all_three()); // end 1D dynamic extent pair, all, ptrdifft slice }}}1 //============================================================================== -template -constexpr bool -dynamic_extent_2d_idx_idx() { - int data[] = { 1, 2, 3, 4, 5, 6 }; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>( - data, 2, 3); +template +constexpr bool dynamic_extent_2d_idx_idx() { + int data[] = {1, 2, 3, 4, 5, 6}; + auto s = Kokkos::mdspan< + int, + Kokkos::extents, + Layout>(data, 2, 3); int result = 0; - for(size_t row = 0; row < s.extent(0); ++row) { - for(size_t col = 0; col < s.extent(1); ++col) { + for (size_t row = 0; row < s.extent(0); ++row) { + for (size_t col = 0; col < s.extent(1); ++col) { auto ss = Kokkos::submdspan(s, row, col); result += MDSPAN_IMPL_OP0(ss); } @@ -165,17 +161,17 @@ dynamic_extent_2d_idx_idx() { MDSPAN_STATIC_TEST(dynamic_extent_2d_idx_idx()); MDSPAN_STATIC_TEST(dynamic_extent_2d_idx_idx()); -template -constexpr bool -dynamic_extent_2d_idx_all_idx() { - int data[] = { 1, 2, 3, 4, 5, 6 }; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>( - data, 2, 3); +template +constexpr bool dynamic_extent_2d_idx_all_idx() { + int data[] = {1, 2, 3, 4, 5, 6}; + auto s = Kokkos::mdspan< + int, + Kokkos::extents, + Layout>(data, 2, 3); int result = 0; - for(size_t row = 0; row < s.extent(0); ++row) { + for (size_t row = 0; row < s.extent(0); ++row) { auto srow = Kokkos::submdspan(s, row, Kokkos::full_extent); - for(size_t col = 0; col < s.extent(1); ++col) { + for (size_t col = 0; col < s.extent(1); ++col) { auto scol = Kokkos::submdspan(srow, col); constexpr_assert_equal(MDSPAN_IMPL_OP0(scol), MDSPAN_IMPL_OP(srow, col)); result += MDSPAN_IMPL_OP0(scol); @@ -193,18 +189,13 @@ MDSPAN_STATIC_TEST(dynamic_extent_2d_idx_all_idx()); //============================================================================== -constexpr int -simple_static_submdspan_test_1(int add_to_row) { - int data[] = { - 1, 2, 3, - 4, 5, 6, - 7, 8, 9 - }; - auto s = Kokkos::mdspan>(data); +constexpr int simple_static_submdspan_test_1(int add_to_row) { + int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + auto s = Kokkos::mdspan>(data); int result = 0; - for(int col = 0; col < 3; ++col) { + for (int col = 0; col < 3; ++col) { auto scol = Kokkos::submdspan(s, Kokkos::full_extent, col); - for(int row = 0; row < 3; ++row) { + for (int row = 0; row < 3; ++row) { auto srow = Kokkos::submdspan(scol, row); result += MDSPAN_IMPL_OP0(srow) * (row + add_to_row); } @@ -213,49 +204,44 @@ simple_static_submdspan_test_1(int add_to_row) { } // MSVC ICE -#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && (!defined(__GNUC__) || (__GNUC__>=6 && __GNUC_MINOR__>=4)) +#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && \ + (!defined(__GNUC__) || (__GNUC__ >= 6 && __GNUC_MINOR__ >= 4)) MDSPAN_STATIC_TEST( - // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 - simple_static_submdspan_test_1(1) == 108 -); + // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9) = 108 + simple_static_submdspan_test_1(1) == 108); MDSPAN_STATIC_TEST( - // -1 - 2 - 3 + 7 + 8 + 9 = 18 - simple_static_submdspan_test_1(-1) == 18 -); + // -1 - 2 - 3 + 7 + 8 + 9 = 18 + simple_static_submdspan_test_1(-1) == 18); MDSPAN_STATIC_TEST( - // -1 - 2 - 3 + 7 + 8 + 9 = 18 - Kokkos::mdspan>{nullptr}.extent(0) == 18 -); + // -1 - 2 - 3 + 7 + 8 + 9 = 18 + Kokkos::mdspan>{ + nullptr} + .extent(0) == 18); #endif //============================================================================== -constexpr bool -mixed_submdspan_left_test_2() { - int data[] = { - 1, 4, 7, - 2, 5, 8, - 3, 6, 9, - 0, 0, 0, - 0, 0, 0 - }; - auto s = Kokkos::mdspan, Kokkos::layout_left>(data, 5); +constexpr bool mixed_submdspan_left_test_2() { + int data[] = {1, 4, 7, 2, 5, 8, 3, 6, 9, 0, 0, 0, 0, 0, 0}; + auto s = + Kokkos::mdspan, + Kokkos::layout_left>(data, 5); int result = 0; - for(int col = 0; col < 5; ++col) { + for (int col = 0; col < 5; ++col) { auto scol = Kokkos::submdspan(s, Kokkos::full_extent, col); - for(int row = 0; row < 3; ++row) { + for (int row = 0; row < 3; ++row) { auto srow = Kokkos::submdspan(scol, row); result += MDSPAN_IMPL_OP0(srow) * (row + 1); } } // 1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9)= 108 constexpr_assert_equal(108, result); - for(int row = 0; row < 3; ++row) { + for (int row = 0; row < 3; ++row) { auto srow = Kokkos::submdspan(s, row, Kokkos::full_extent); - for(int col = 0; col < 5; ++col) { + for (int col = 0; col < 5; ++col) { auto scol = Kokkos::submdspan(srow, col); result += MDSPAN_IMPL_OP0(scol) * (row + 1); } @@ -267,37 +253,33 @@ mixed_submdspan_left_test_2() { } // MSVC ICE -#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && (!defined(__GNUC__) || (__GNUC__>=6 && __GNUC_MINOR__>=4)) +#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && \ + (!defined(__GNUC__) || (__GNUC__ >= 6 && __GNUC_MINOR__ >= 4)) MDSPAN_STATIC_TEST( - // 2 * (1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9)) / 2 = 108 - mixed_submdspan_left_test_2() -); + // 2 * (1 + 2 + 3 + 2*(4 + 5 + 6) + 3*(7 + 8 + 9)) / 2 = 108 + mixed_submdspan_left_test_2()); #endif //============================================================================== template -constexpr bool -mixed_submdspan_test_3() { - int data[] = { - 1, 4, 7, 2, 5, - 8, 3, 6, 9, 0, - 0, 0, 0, 0, 0 - }; - auto s = Kokkos::mdspan< - int, Kokkos::extents, Layout>(data, 5); +constexpr bool mixed_submdspan_test_3() { + int data[] = {1, 4, 7, 2, 5, 8, 3, 6, 9, 0, 0, 0, 0, 0, 0}; + auto s = + Kokkos::mdspan, + Layout>(data, 5); int result = 0; - for(int col = 0; col < 5; ++col) { + for (int col = 0; col < 5; ++col) { auto scol = Kokkos::submdspan(s, Kokkos::full_extent, col); - for(int row = 0; row < 3; ++row) { + for (int row = 0; row < 3; ++row) { auto srow = Kokkos::submdspan(scol, row); result += MDSPAN_IMPL_OP0(srow) * (row + 1); } } constexpr_assert_equal(71, result); - for(int row = 0; row < 3; ++row) { + for (int row = 0; row < 3; ++row) { auto srow = Kokkos::submdspan(s, row, Kokkos::full_extent); - for(int col = 0; col < 5; ++col) { + for (int col = 0; col < 5; ++col) { auto scol = Kokkos::submdspan(srow, col); result += MDSPAN_IMPL_OP0(scol) * (row + 1); } @@ -310,14 +292,13 @@ mixed_submdspan_test_3() { // MSVC ICE #ifndef MDSPAN_IMPL_COMPILER_MSVC -MDSPAN_STATIC_TEST( - mixed_submdspan_test_3() -); +MDSPAN_STATIC_TEST(mixed_submdspan_test_3()); #endif //============================================================================== -#if defined(MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS) && MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS +#if defined(MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS) && \ + MDSPAN_ENABLE_EXPENSIVE_COMPILATION_TESTS template constexpr auto _repeated_ptrdiff_t = Val; @@ -325,63 +306,64 @@ template using _repeated_with_idxs_t = T; template -constexpr bool -submdspan_single_element_stress_test_impl_2( - std::integer_sequence -) { +constexpr bool submdspan_single_element_stress_test_impl_2( + std::integer_sequence) { using mdspan_t = Kokkos::mdspan< - int, Kokkos::extents...>, Layout>; + int, Kokkos::extents...>, Layout>; using dyn_mdspan_t = Kokkos::mdspan< - int, Kokkos::extents...>, Layout>; - int data[] = { 42 }; - auto s = mdspan_t(data); - auto s_dyn = dyn_mdspan_t(data, _repeated_ptrdiff_t<1, Idxs>...); - auto ss = Kokkos::submdspan(s, _repeated_ptrdiff_t<0, Idxs>...); + int, + Kokkos::extents...>, + Layout>; + int data[] = {42}; + auto s = mdspan_t(data); + auto s_dyn = dyn_mdspan_t(data, _repeated_ptrdiff_t<1, Idxs>...); + auto ss = Kokkos::submdspan(s, _repeated_ptrdiff_t<0, Idxs>...); auto ss_dyn = Kokkos::submdspan(s_dyn, _repeated_ptrdiff_t<0, Idxs>...); - auto ss_all = Kokkos::submdspan(s, _repeated_with_idxs_t{}...); - auto ss_all_dyn = Kokkos::submdspan(s_dyn, _repeated_with_idxs_t{}...); - auto val = MDSPAN_IMPL_OP(ss_all, (_repeated_ptrdiff_t<0, Idxs>...)); + auto ss_all = Kokkos::submdspan( + s, _repeated_with_idxs_t{}...); + auto ss_all_dyn = Kokkos::submdspan( + s_dyn, _repeated_with_idxs_t{}...); + auto val = MDSPAN_IMPL_OP(ss_all, (_repeated_ptrdiff_t<0, Idxs>...)); auto val_dyn = MDSPAN_IMPL_OP(ss_all_dyn, (_repeated_ptrdiff_t<0, Idxs>...)); - auto ss_pair = Kokkos::submdspan(s, _repeated_with_idxs_t, Idxs>{0, 1}...); - auto ss_pair_dyn = Kokkos::submdspan(s_dyn, _repeated_with_idxs_t, Idxs>{0, 1}...); + auto ss_pair = Kokkos::submdspan( + s, _repeated_with_idxs_t, Idxs>{0, 1}...); + auto ss_pair_dyn = Kokkos::submdspan( + s_dyn, + _repeated_with_idxs_t, Idxs>{0, 1}...); auto val_pair = MDSPAN_IMPL_OP(ss_pair, (_repeated_ptrdiff_t<0, Idxs>...)); - auto val_pair_dyn = MDSPAN_IMPL_OP(ss_pair_dyn, (_repeated_ptrdiff_t<0, Idxs>...)); + auto val_pair_dyn = + MDSPAN_IMPL_OP(ss_pair_dyn, (_repeated_ptrdiff_t<0, Idxs>...)); constexpr_assert_equal(42, ss()); constexpr_assert_equal(42, ss_dyn()); constexpr_assert_equal(42, val); constexpr_assert_equal(42, val_dyn); constexpr_assert_equal(42, val_pair); constexpr_assert_equal(42, val_pair_dyn); - return MDSPAN_IMPL_OP0(ss) == 42 && MDSPAN_IMPL_OP0(ss_dyn) == 42 && val == 42 && val_dyn == 42 && val_pair == 42 && val_pair_dyn == 42; + return MDSPAN_IMPL_OP0(ss) == 42 && MDSPAN_IMPL_OP0(ss_dyn) == 42 && + val == 42 && val_dyn == 42 && val_pair == 42 && val_pair_dyn == 42; } template -constexpr bool -submdspan_single_element_stress_test_impl_1( - std::integer_sequence -) { +constexpr bool submdspan_single_element_stress_test_impl_1( + std::integer_sequence) { return MDSPAN_IMPL_FOLD_AND( - submdspan_single_element_stress_test_impl_2( - std::make_index_sequence{} - ) /* && ... */ + submdspan_single_element_stress_test_impl_2( + std::make_index_sequence{}) /* && ... */ ); } template -constexpr bool -submdspan_single_element_stress_test() { +constexpr bool submdspan_single_element_stress_test() { return submdspan_single_element_stress_test_impl_1( - std::make_index_sequence{} - ); + std::make_index_sequence{}); } MDSPAN_STATIC_TEST( - submdspan_single_element_stress_test() -); + submdspan_single_element_stress_test()); MDSPAN_STATIC_TEST( - submdspan_single_element_stress_test() -); + submdspan_single_element_stress_test()); -#endif // MDSPAN_DISABLE_EXPENSIVE_COMPILATION_TESTS +#endif // MDSPAN_DISABLE_EXPENSIVE_COMPILATION_TESTS -#endif // defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 +#endif // defined(MDSPAN_IMPL_USE_CONSTEXPR_14) && MDSPAN_IMPL_USE_CONSTEXPR_14 diff --git a/compilation_tests/ctest_constructor_sfinae.cpp b/compilation_tests/ctest_constructor_sfinae.cpp index d6ecd36d..23b89a07 100644 --- a/compilation_tests/ctest_constructor_sfinae.cpp +++ b/compilation_tests/ctest_constructor_sfinae.cpp @@ -19,164 +19,110 @@ #include - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::array - >::value -); + std::is_constructible, + std::array>::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::array - >::value -); + std::is_constructible, + std::array>::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - int - >::value -); + std::is_constructible, + int>::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - int, int64_t - >::value -); + std::is_constructible, + int, int64_t>::value); // TODO @proposal-bug: not sure we really intended this??? MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::array - >::value -); + std::is_constructible, + std::array>::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - float, double - >::value -); + std::is_constructible, + float, double>::value); -MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::mdspan>, - int* - >::value -); +MDSPAN_STATIC_TEST(std::is_constructible< + Kokkos::mdspan>, int*>::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::mdspan>, - int* - >::value -); + std::is_constructible>, + int*>::value); MDSPAN_STATIC_TEST( std::is_constructible< - Kokkos::mdspan>, - int*, int - >::value -); + Kokkos::mdspan>, + int*, int>::value); MDSPAN_STATIC_TEST( std::is_constructible< - Kokkos::mdspan>, - double*, unsigned, int - >::value -); + Kokkos::mdspan>, + double*, unsigned, int>::value); MDSPAN_STATIC_TEST( std::is_constructible< - Kokkos::mdspan>, - int*, int, int - >::value -); + Kokkos::mdspan>, + int*, int, int>::value); MDSPAN_STATIC_TEST( std::is_constructible< - Kokkos::mdspan>, - int*, std::array - >::value -); + Kokkos::mdspan>, + int*, std::array>::value); MDSPAN_STATIC_TEST( std::is_constructible< - Kokkos::mdspan>, - int*, std::array - >::value -); + Kokkos::mdspan>, + int*, std::array>::value); // end Test allowed pointer + extents ctors }}}1 //============================================================================== - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - std::array - >::value -); + !std::is_constructible, + std::array>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - int, int, int - >::value -); + !std::is_constructible, + int, int, int>::value); MDSPAN_STATIC_TEST( !std::is_constructible< - Kokkos::mdspan>, - int*, std::array - >::value -); + Kokkos::mdspan>, + int*, std::array>::value); MDSPAN_STATIC_TEST( !std::is_constructible< - Kokkos::mdspan>, - double*, int - >::value -); - + Kokkos::mdspan>, + double*, int>::value); MDSPAN_STATIC_TEST( !std::is_constructible< - Kokkos::mdspan>, - int*, int, int, int - >::value -); + Kokkos::mdspan>, + int*, int, int, int>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::mdspan, Kokkos::layout_stride>, - int*, int, int - >::value -); + !std::is_constructible< + Kokkos::mdspan, Kokkos::layout_stride>, + int*, int, int>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::mdspan, Kokkos::layout_stride>, - int*, std::array - >::value -); + !std::is_constructible< + Kokkos::mdspan, Kokkos::layout_stride>, + int*, std::array>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::mdspan, Kokkos::layout_stride>, - int*, Kokkos::dextents - >::value -); + !std::is_constructible< + Kokkos::mdspan, Kokkos::layout_stride>, + int*, Kokkos::dextents>::value); // end Test forbidden pointer + extents ctors }}}1 //============================================================================== diff --git a/compilation_tests/ctest_extents_ctors.cpp b/compilation_tests/ctest_extents_ctors.cpp index 357b116d..266e4b71 100644 --- a/compilation_tests/ctest_extents_ctors.cpp +++ b/compilation_tests/ctest_extents_ctors.cpp @@ -17,287 +17,184 @@ #include - - MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - int - >::value -); + std::is_constructible, + int>::value); MDSPAN_STATIC_TEST( - std::is_copy_constructible< - Kokkos::extents - >::value -); + std::is_copy_constructible< + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_copy_constructible< - Kokkos::extents - >::value -); + std::is_copy_constructible >::value); -MDSPAN_STATIC_TEST( - std::is_copy_constructible< - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_copy_constructible< + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_move_constructible< - Kokkos::extents - >::value -); + std::is_move_constructible< + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_default_constructible< - Kokkos::extents - >::value -); + std::is_default_constructible >::value); // constructibility test from integrals MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - int, size_t, int - >::value -); + std::is_constructible< + Kokkos::extents, + int, size_t, int>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - int, int - >::value -); + !std::is_constructible< + Kokkos::extents, + int, int>::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - int - >::value -); + !std::is_constructible< + Kokkos::extents, + int>::value); // conversion construction from extents MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - Kokkos::extents - >::value -); + std::is_constructible< + Kokkos::extents, + Kokkos::extents >::value); +MDSPAN_STATIC_TEST(std::is_convertible< + Kokkos::extents, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_convertible< - Kokkos::extents, - Kokkos::extents - >::value -); - -MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - Kokkos::extents - >::value -); + std::is_constructible, + Kokkos::extents >::value); #if MDSPAN_HAS_CXX_20 // GNU gets the is_convertible with conditional explicit // wrong in some older versions. #if !defined(__GNUC__) || (__GNUC__ > 10) MDSPAN_STATIC_TEST( - !std::is_convertible< - Kokkos::extents, - Kokkos::extents - >::value -); + !std::is_convertible, + Kokkos::extents >::value); #endif #endif +MDSPAN_STATIC_TEST(std::is_constructible, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - Kokkos::extents - >::value -); - -MDSPAN_STATIC_TEST( - std::is_convertible< - Kokkos::extents, - Kokkos::extents - >::value -); + std::is_convertible, Kokkos::extents >::value); -MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_constructible, + Kokkos::extents >::value); #if MDSPAN_HAS_CXX_20 // GNU gets the is_convertible with conditional explicit // wrong in some older versions. #if !defined(__GNUC__) || (__GNUC__ > 10) -MDSPAN_STATIC_TEST( - !std::is_convertible< - Kokkos::extents, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(!std::is_convertible, + Kokkos::extents >::value); #endif #endif MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::array - >::value -); + std::is_constructible, + std::array >::value); -MDSPAN_STATIC_TEST( - std::is_convertible< - std::array, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_convertible< + std::array, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::array - >::value -); + std::is_constructible, + std::array >::value); #if MDSPAN_HAS_CXX_20 // GNU gets the is_convertible with conditional explicit // wrong in some older versions. #if !defined(__GNUC__) || (__GNUC__ > 10) -MDSPAN_STATIC_TEST( - !std::is_convertible< - std::array, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(!std::is_convertible< + std::array, + Kokkos::extents >::value); #endif #endif MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - std::array - >::value -); + !std::is_constructible, + std::array >::value); #ifdef __cpp_lib_span MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::span - >::value -); + std::is_constructible, + std::span >::value); -MDSPAN_STATIC_TEST( - std::is_convertible< - std::span, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_convertible< + std::span, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - std::span - >::value -); + std::is_constructible, + std::span >::value); #if MDSPAN_HAS_CXX_20 // GNU gets the is_convertible with conditional explicit // wrong in some older versions. #if !defined(__GNUC__) || (__GNUC__ > 10) -MDSPAN_STATIC_TEST( - !std::is_convertible< - std::span, - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(!std::is_convertible< + std::span, + Kokkos::extents >::value); #endif #endif // this is not supported in the standard MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - std::span - >::value -); + !std::is_constructible, + std::span >::value); MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - std::span - >::value -); -#endif // __cpp_lib_span + !std::is_constructible, + std::span >::value); +#endif // __cpp_lib_span MDSPAN_STATIC_TEST( - !std::is_constructible< - Kokkos::extents, - Kokkos::extents - >::value -); + !std::is_constructible, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_assignable< - Kokkos::extents, - Kokkos::extents - >::value -); + std::is_assignable, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_same< - Kokkos::dextents, - Kokkos::extents - >::value -); + std::is_same, Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_same< - Kokkos::dextents, - Kokkos::extents - >::value -); + std::is_same, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_same< - Kokkos::dextents, - Kokkos::extents - >::value -); + std::is_same, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_same< - Kokkos::dextents, - Kokkos::extents - >::value -); + std::is_same< + Kokkos::dextents, + Kokkos::extents >::value); MDSPAN_STATIC_TEST( - std::is_constructible< - Kokkos::extents, - int, int - >::value -); + std::is_constructible, + int, int>::value); MDSPAN_STATIC_TEST( - Kokkos::extents{ 7, 4 }.extent( 0 ) == 7 -); + Kokkos::extents{7, 4}.extent(0) == 7); MDSPAN_STATIC_TEST( - Kokkos::dextents{std::array{1}}.extent(0) == 1 -); + Kokkos::dextents{std::array{1}}.extent(0) == 1); -MDSPAN_STATIC_TEST( - Kokkos::extents{Kokkos::extents{}}.extent(0) == 0 -); +MDSPAN_STATIC_TEST(Kokkos::extents{ + Kokkos::extents{}} + .extent(0) == 0); diff --git a/compilation_tests/ctest_extents_type_check.cpp b/compilation_tests/ctest_extents_type_check.cpp index 5d5ad931..250126c3 100644 --- a/compilation_tests/ctest_extents_type_check.cpp +++ b/compilation_tests/ctest_extents_type_check.cpp @@ -17,63 +17,76 @@ #include - using E1 = Kokkos::extents; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E1::index_type>::value && - std::is_same().extent(1)), typename E1::index_type>::value && - (E1::rank()==2) && - (E1::rank_dynamic()==1) && - (E1::static_extent(0) == Kokkos::dynamic_extent) && - (E1::static_extent(1) == 3) -); + std::is_same::value&& std::is_same< + typename E1::size_type, + uint32_t>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extent(0)), + typename E1::index_type>::value&& + std::is_same().extent(1)), + typename E1::index_type>::value && + (E1::rank() == 2) && (E1::rank_dynamic() == 1) && + (E1::static_extent(0) == Kokkos::dynamic_extent) && + (E1::static_extent(1) == 3)); -using E2 = Kokkos::extents; +using E2 = + Kokkos::extents; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E2::index_type>::value && - std::is_same().extent(1)), typename E2::index_type>::value && - std::is_same().extent(2)), typename E2::index_type>::value && - (E2::rank()==3) && - (E2::rank_dynamic()==2) && - (E2::static_extent(0) == Kokkos::dynamic_extent) && - (E2::static_extent(1) == 3) && - (E2::static_extent(2) == Kokkos::dynamic_extent) -); + std::is_same::value&& std::is_same< + typename E2::size_type, + uint64_t>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extent(0)), + typename E2::index_type>::value&& std:: + is_same().extent(1)), + typename E2::index_type>::value&& + std::is_same< + decltype(std::declval().extent(2)), + typename E2::index_type>::value && + (E2::rank() == 3) && (E2::rank_dynamic() == 2) && + (E2::static_extent(0) == Kokkos::dynamic_extent) && + (E2::static_extent(1) == 3) && + (E2::static_extent(2) == Kokkos::dynamic_extent)); -using E3 = Kokkos::extents; +using E3 = Kokkos::extents; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E3::index_type>::value && - std::is_same().extent(1)), typename E3::index_type>::value && - std::is_same().extent(2)), typename E3::index_type>::value && - (E3::rank()==3) && - (E3::rank_dynamic()==2) && - (E3::static_extent(0) == Kokkos::dynamic_extent) && - (E3::static_extent(1) == 3) && - (E3::static_extent(2) == Kokkos::dynamic_extent) -); + std::is_same::value&& std::is_same< + typename E3::size_type, + uint32_t>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extent(0)), + typename E3::index_type>::value&& std:: + is_same().extent(1)), + typename E3::index_type>::value&& + std::is_same< + decltype(std::declval().extent(2)), + typename E3::index_type>::value && + (E3::rank() == 3) && (E3::rank_dynamic() == 2) && + (E3::static_extent(0) == Kokkos::dynamic_extent) && + (E3::static_extent(1) == 3) && + (E3::static_extent(2) == Kokkos::dynamic_extent)); diff --git a/compilation_tests/ctest_layout_convertible.cpp b/compilation_tests/ctest_layout_convertible.cpp index 2da8b84e..a925ea5e 100644 --- a/compilation_tests/ctest_layout_convertible.cpp +++ b/compilation_tests/ctest_layout_convertible.cpp @@ -17,42 +17,45 @@ #include - struct NotARealLayout { - template + template struct mapping { using extents_type = Extents; - using rank_type = typename extents_type::rank_type; - using index_type = typename extents_type::index_type; - using layout_type = NotARealLayout; + using rank_type = typename extents_type::rank_type; + using index_type = typename extents_type::index_type; + using layout_type = NotARealLayout; constexpr extents_type& extents() const { return ext; } - template - index_type operator()(Idx ...) const { return 0; } + template + index_type operator()(Idx...) const { + return 0; + } index_type required_span_size() const { return 0; } index_type stride(rank_type) const { return 1; } - private: - extents_type ext; + private: + extents_type ext; }; }; -template +template struct AStridedLayout { - template + template struct mapping { using extents_type = Extents; - using rank_type = typename extents_type::rank_type; - using index_type = typename extents_type::index_type; - using layout_type = AStridedLayout; + using rank_type = typename extents_type::rank_type; + using index_type = typename extents_type::index_type; + using layout_type = AStridedLayout; constexpr extents_type& extents() const { return ext; } - template - index_type operator()(Idx ...) const { return 0; } + template + index_type operator()(Idx...) const { + return 0; + } index_type required_span_size() const { return 0; } @@ -65,30 +68,25 @@ struct AStridedLayout { constexpr bool is_unique() { return unique; } constexpr bool is_exhaustive() { return true; } - private: - extents_type ext; + private: + extents_type ext; }; }; -using E1 = Kokkos::extents; -using E2 = Kokkos::extents; +using E1 = Kokkos::extents; +using E2 = Kokkos::extents; using LS1 = Kokkos::layout_stride::mapping; using LS2 = Kokkos::layout_stride::mapping; MDSPAN_STATIC_TEST( - !std::is_constructible::mapping>::value && - !std::is_convertible::mapping, LS1>::value -); + !std::is_constructible::mapping>::value && + !std::is_convertible::mapping, LS1>::value); #if !MDSPAN_HAS_CXX_14 && !MDSPAN_HAS_CXX_20 MDSPAN_STATIC_TEST( - std::is_constructible::mapping>::value && - !std::is_convertible::mapping, LS2>::value -); + std::is_constructible::mapping>::value && + !std::is_convertible::mapping, LS2>::value); #endif MDSPAN_STATIC_TEST( - !std::is_constructible>::value -); - - + !std::is_constructible>::value); diff --git a/compilation_tests/ctest_layout_type_check.cpp b/compilation_tests/ctest_layout_type_check.cpp index d6e77755..52ffb3ad 100644 --- a/compilation_tests/ctest_layout_type_check.cpp +++ b/compilation_tests/ctest_layout_type_check.cpp @@ -17,71 +17,132 @@ #include - -using E1 = Kokkos::extents; +using E1 = Kokkos::extents; using MLR1 = Kokkos::layout_right::mapping; // Note we already separately tested that the extents interface is correct MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extents()), const E1&>::value && - std::is_same().stride(0)), typename E1::index_type>::value && - std::is_same().required_span_size()), typename E1::index_type>::value && - std::is_same().is_unique()), bool>::value && - std::is_same().is_exhaustive()), bool>::value && - std::is_same().is_strided()), bool>::value && - std::is_same()(1,1)), typename E1::index_type>::value && - (MLR1::is_always_unique() == true) && - (MLR1::is_always_exhaustive()== true) && - (MLR1::is_always_strided() == true) -); + std::is_same< + typename MLR1::index_type, + typename E1::index_type>::value&& std::is_same:: + value&& std::is_same< + typename MLR1::rank_type, + typename E1:: + rank_type>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extents()), + const E1&>::value&& std:: + is_same().stride(0)), + typename E1::index_type>::value&& std:: + is_same() + .required_span_size()), + typename E1::index_type>::value&& + std::is_same() + .is_unique()), + bool>::value&& std:: + is_same() + .is_exhaustive()), + bool>::value&& + std::is_same< + decltype(std::declval() + .is_strided()), + bool>::value&& + std::is_same< + decltype(std::declval< + MLR1>()(1, 1)), + typename E1::index_type>:: + value && + (MLR1::is_always_unique() == true) && + (MLR1::is_always_exhaustive() == true) && + (MLR1::is_always_strided() == true)); using MLL1 = Kokkos::layout_left::mapping; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extents()), const E1&>::value && - std::is_same().stride(0)), typename E1::index_type>::value && - std::is_same().required_span_size()), typename E1::index_type>::value && - std::is_same().is_unique()), bool>::value && - std::is_same().is_exhaustive()), bool>::value && - std::is_same().is_strided()), bool>::value && - std::is_same()(1,1)), typename E1::index_type>::value && - (MLL1::is_always_unique() == true) && - (MLL1::is_always_exhaustive()== true) && - (MLL1::is_always_strided() == true) -); - + std::is_same< + typename MLL1::index_type, + typename E1::index_type>::value&& std::is_same:: + value&& std::is_same< + typename MLL1::rank_type, + typename E1:: + rank_type>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extents()), + const E1&>::value&& std:: + is_same().stride(0)), + typename E1::index_type>::value&& std:: + is_same() + .required_span_size()), + typename E1::index_type>::value&& + std::is_same() + .is_unique()), + bool>::value&& std:: + is_same() + .is_exhaustive()), + bool>::value&& + std::is_same< + decltype(std::declval() + .is_strided()), + bool>::value&& + std::is_same< + decltype(std::declval< + MLL1>()(1, 1)), + typename E1::index_type>:: + value && + (MLL1::is_always_unique() == true) && + (MLL1::is_always_exhaustive() == true) && + (MLL1::is_always_strided() == true)); using MLS1 = Kokkos::layout_stride::mapping; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extents()), const E1&>::value && - std::is_same().stride(0)), typename E1::index_type>::value && - std::is_same().required_span_size()), typename E1::index_type>::value && - std::is_same().is_unique()), bool>::value && - std::is_same().is_exhaustive()), bool>::value && - std::is_same().is_strided()), bool>::value && - std::is_same()(1,1)), typename E1::index_type>::value && - (MLS1::is_always_unique() == true) && - (MLS1::is_always_exhaustive()== false) && - (MLS1::is_always_strided() == true) -); + std::is_same< + typename MLS1::index_type, + typename E1::index_type>::value&& std::is_same:: + value&& std::is_same< + typename MLS1::rank_type, + typename E1:: + rank_type>::value&& std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same().extents()), + const E1&>::value&& std:: + is_same().stride(0)), + typename E1::index_type>::value&& std:: + is_same() + .required_span_size()), + typename E1::index_type>::value&& + std::is_same() + .is_unique()), + bool>::value&& std:: + is_same() + .is_exhaustive()), + bool>::value&& + std::is_same< + decltype(std::declval() + .is_strided()), + bool>::value&& + std::is_same< + decltype(std::declval< + MLS1>()(1, 1)), + typename E1::index_type>:: + value && + (MLS1::is_always_unique() == true) && + (MLS1::is_always_exhaustive() == false) && + (MLS1::is_always_strided() == true)); diff --git a/compilation_tests/ctest_mdarray_type_check.cpp b/compilation_tests/ctest_mdarray_type_check.cpp index 3accf6ef..420ff152 100644 --- a/compilation_tests/ctest_mdarray_type_check.cpp +++ b/compilation_tests/ctest_mdarray_type_check.cpp @@ -22,94 +22,127 @@ #include #endif -namespace KokkosEx = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; +namespace KokkosEx = + MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE; using E1 = Kokkos::extents; using M1 = KokkosEx::mdarray; #if defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 -template +template constexpr bool is_copyable = std::copyable; #else -template +template constexpr bool is_copyable = - std::is_assignable::value && - std::is_move_assignable::value && - std::is_copy_constructible::value && - std::is_move_constructible::value; + std::is_assignable::value && std::is_move_assignable::value && + std::is_copy_constructible::value && + std::is_move_constructible::value; #endif MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same>::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E1::index_type>::value && - std::is_same().extent(1)), typename E1::index_type>::value && - (M1::rank()==2) && - (M1::rank_dynamic()==1) && - (M1::static_extent(0) == Kokkos::dynamic_extent) && - (M1::static_extent(1) == 3) && - is_copyable && - std::is_default_constructible::value -); + std::is_same::value&& std::is_same< + typename M1::index_type, int32_t>::value&& + std::is_same::value&& std::is_same< + typename M1::rank_type, + size_t>::value&& std::is_same::value&& + std::is_same>::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& std:: + is_same().extent(0)), + typename E1::index_type>::value&& + std::is_same< + decltype(std::declval().extent(1)), + typename E1::index_type>::value && + (M1::rank() == 2) && (M1::rank_dynamic() == 1) && + (M1::static_extent(0) == Kokkos::dynamic_extent) && + (M1::static_extent(1) == 3) && is_copyable && + std::is_default_constructible::value); -using E2 = Kokkos::extents; -using M2 = KokkosEx::mdarray, E2, Kokkos::layout_right, std::array,24>>; +using E2 = + Kokkos::extents; +using M2 = KokkosEx::mdarray, E2, Kokkos::layout_right, + std::array, 24>>; MDSPAN_STATIC_TEST( - std::is_same>::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same,24>>::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E2::index_type>::value && - std::is_same().extent(1)), typename E2::index_type>::value && - std::is_same().extent(2)), typename E2::index_type>::value && - (M2::rank()==3) && - (M2::rank_dynamic()==2) && - (M2::static_extent(0) == Kokkos::dynamic_extent) && - (M2::static_extent(1) == 3) && - (M2::static_extent(2) == Kokkos::dynamic_extent) && - is_copyable && - std::is_default_constructible::value -); + std::is_same>::value&& + std::is_same::value&& std::is_same< + typename M2::size_type, uint64_t>::value&& + std::is_same::value&& std::is_same< + typename M2::layout_type, Kokkos::layout_right>::value&& + std::is_same, 24>>::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same() + .extent(0)), + typename E2::index_type>:: + value&& std::is_same< + decltype(std::declval() + .extent(1)), + typename E2::index_type>:: + value&& std::is_same< + decltype(std::declval() + .extent(2)), + typename E2::index_type>:: + value && + (M2::rank() == 3) && (M2::rank_dynamic() == 2) && + (M2::static_extent(0) == Kokkos::dynamic_extent) && + (M2::static_extent(1) == 3) && + (M2::static_extent(2) == Kokkos::dynamic_extent) && is_copyable && + std::is_default_constructible::value); -using E3 = Kokkos::extents; +using E3 = Kokkos::extents; using M3 = KokkosEx::mdarray; MDSPAN_STATIC_TEST( - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same>::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same::value && - std::is_same().extent(0)), typename E3::index_type>::value && - std::is_same().extent(1)), typename E3::index_type>::value && - std::is_same().extent(2)), typename E3::index_type>::value && - (M3::rank()==3) && - (M3::rank_dynamic()==2) && - (M3::static_extent(0) == Kokkos::dynamic_extent) && - (M3::static_extent(1) == 3) && - (M3::static_extent(2) == Kokkos::dynamic_extent) && - is_copyable && - std::is_default_constructible::value -); + std::is_same::value&& std::is_same< + typename M3::index_type, uint32_t>::value&& + std::is_same::value&& std::is_same< + typename M3::rank_type, + size_t>::value&& std::is_same::value&& + std::is_same>::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same::value&& + std::is_same< + decltype(std::declval().extent(0)), + typename E3::index_type>::value&& + std::is_same() + .extent(1)), + typename E3::index_type>:: + value&& std::is_same< + decltype(std::declval() + .extent(2)), + typename E3::index_type>:: + value && + (M3::rank() == 3) && (M3::rank_dynamic() == 2) && + (M3::static_extent(0) == Kokkos::dynamic_extent) && + (M3::static_extent(1) == 3) && + (M3::static_extent(2) == Kokkos::dynamic_extent) && is_copyable && + std::is_default_constructible::value); diff --git a/compilation_tests/ctest_mdspan_convertible.cpp b/compilation_tests/ctest_mdspan_convertible.cpp index 60007961..6b0cc8ed 100644 --- a/compilation_tests/ctest_mdspan_convertible.cpp +++ b/compilation_tests/ctest_mdspan_convertible.cpp @@ -19,24 +19,17 @@ #include - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - std::is_convertible< - Kokkos::mdspan>, - Kokkos::mdspan> - >::value -); + std::is_convertible< + Kokkos::mdspan>, + Kokkos::mdspan>>::value); -MDSPAN_STATIC_TEST( - !std::is_convertible< - Kokkos::mdspan>, - Kokkos::mdspan> - >::value -); +MDSPAN_STATIC_TEST(!std::is_convertible< + Kokkos::mdspan>, + Kokkos::mdspan>>::value); // end mdspan }}}1 //============================================================================== - diff --git a/compilation_tests/ctest_namespace_std.cpp b/compilation_tests/ctest_namespace_std.cpp index abab92df..0f1b730f 100644 --- a/compilation_tests/ctest_namespace_std.cpp +++ b/compilation_tests/ctest_namespace_std.cpp @@ -21,5 +21,5 @@ #include "ctest_common.hpp" using test_extents_type = std::extents; -using test_mdspan_type = std::mdspan; +using test_mdspan_type = std::mdspan; using test_mdarray_type = std::experimental::mdarray; diff --git a/compilation_tests/ctest_no_unique_address.cpp b/compilation_tests/ctest_no_unique_address.cpp index 23d1a264..5ecb223c 100644 --- a/compilation_tests/ctest_no_unique_address.cpp +++ b/compilation_tests/ctest_no_unique_address.cpp @@ -19,38 +19,32 @@ #include - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - sizeof(Kokkos::extents) == sizeof(ptrdiff_t) -); + sizeof(Kokkos::extents) == + sizeof(ptrdiff_t)); -MDSPAN_STATIC_TEST( - sizeof(Kokkos::extents) == sizeof(ptrdiff_t) -); +MDSPAN_STATIC_TEST(sizeof(Kokkos::extents) == + sizeof(ptrdiff_t)); -MDSPAN_STATIC_TEST( - sizeof(Kokkos::extents) == 2 * sizeof(ptrdiff_t) -); +MDSPAN_STATIC_TEST(sizeof(Kokkos::extents) == + 2 * sizeof(ptrdiff_t)); MDSPAN_STATIC_TEST( - sizeof(Kokkos::extents) == sizeof(ptrdiff_t) -); + sizeof(Kokkos::extents) == + sizeof(ptrdiff_t)); MDSPAN_STATIC_TEST( - sizeof(Kokkos::extents) == sizeof(ptrdiff_t) -); + sizeof(Kokkos::extents) == + sizeof(ptrdiff_t)); #ifdef MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS -MDSPAN_STATIC_TEST( - std::is_empty>::value -); +MDSPAN_STATIC_TEST(std::is_empty>::value); -MDSPAN_STATIC_TEST( - std::is_empty>::value -); +MDSPAN_STATIC_TEST(std::is_empty>::value); #endif // end extents }}}1 @@ -60,25 +54,20 @@ MDSPAN_STATIC_TEST( // {{{1 MDSPAN_STATIC_TEST( - sizeof(Kokkos::layout_left::template mapping< - Kokkos::extents - >) == sizeof(size_t) -); - -#if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) && !defined(MDSPAN_IMPL_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -MDSPAN_STATIC_TEST( - std::is_empty - >>::value -); + sizeof(Kokkos::layout_left::template mapping< + Kokkos::extents>) == + sizeof(size_t)); + +#if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) && \ + !defined(MDSPAN_IMPL_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS) +MDSPAN_STATIC_TEST(std::is_empty>>::value); #endif MDSPAN_STATIC_TEST( - sizeof(Kokkos::layout_stride::template mapping< - Kokkos::extents - >) == 4 * sizeof(size_t) -); - + sizeof(Kokkos::layout_stride::template mapping< + Kokkos::extents>) == + 4 * sizeof(size_t)); // end layouts }}}1 //============================================================================== diff --git a/compilation_tests/ctest_standard_layout.cpp b/compilation_tests/ctest_standard_layout.cpp index ba9677fe..7450ce0c 100644 --- a/compilation_tests/ctest_standard_layout.cpp +++ b/compilation_tests/ctest_standard_layout.cpp @@ -19,52 +19,32 @@ #include - - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); + std::is_standard_layout< + Kokkos::extents>::value); -MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_standard_layout< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); + std::is_standard_layout>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); + std::is_standard_layout< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); + std::is_standard_layout< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); + std::is_standard_layout>::value); -MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_standard_layout>::value); // end extents }}}1 //============================================================================== @@ -73,52 +53,30 @@ MDSPAN_STATIC_TEST( // {{{1 MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_left::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_right::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_right::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout< + Kokkos::layout_right::template mapping>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); + std::is_standard_layout< + Kokkos::layout_stride::template mapping>>::value); // TODO: Remove this test alltogether? // CT: Fails with GCC too after I removed the template parameter @@ -146,25 +104,16 @@ MDSPAN_STATIC_TEST( // {{{1 MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::mdspan> - >::value -); + std::is_standard_layout< + Kokkos::mdspan>>::value); -MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::mdspan> - >::value -); +MDSPAN_STATIC_TEST(std::is_standard_layout< + Kokkos::mdspan>>::value); MDSPAN_STATIC_TEST( - std::is_standard_layout< - Kokkos::mdspan< - double, Kokkos::dextents, - Kokkos::layout_left, Kokkos::default_accessor - > - >::value -); + std::is_standard_layout< + Kokkos::mdspan, Kokkos::layout_left, + Kokkos::default_accessor>>::value); // end mdspan }}}1 //============================================================================== diff --git a/compilation_tests/ctest_trivially_copyable.cpp b/compilation_tests/ctest_trivially_copyable.cpp index 8680d3a2..99bf1cb2 100644 --- a/compilation_tests/ctest_trivially_copyable.cpp +++ b/compilation_tests/ctest_trivially_copyable.cpp @@ -19,52 +19,33 @@ #include - - //============================================================================== // {{{1 MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable< + Kokkos::extents>::value); -MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); +MDSPAN_STATIC_TEST(std::is_trivially_copyable< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable< + Kokkos::extents>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::extents - >::value -); + std::is_trivially_copyable>::value); // end extents }}}1 //============================================================================== @@ -73,66 +54,41 @@ MDSPAN_STATIC_TEST( // {{{1 MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_left::template mapping< - Kokkos::extents - > - >::value -); + std::is_trivially_copyable>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_right::template mapping< - Kokkos::extents - > - >::value -); + std::is_trivially_copyable>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_right::template mapping< - Kokkos::extents - > - >::value -); + std::is_trivially_copyable< + Kokkos::layout_right::template mapping>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); + std::is_trivially_copyable>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); + std::is_trivially_copyable>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::layout_stride::template mapping< - Kokkos::extents - > - >::value -); - -struct layout_stride_as_member_should_be_standard_layout : - Kokkos::layout_stride::template mapping< - Kokkos::extents - > -{ + std::is_trivially_copyable< + Kokkos::layout_stride::template mapping>>::value); + +struct layout_stride_as_member_should_be_standard_layout + : Kokkos::layout_stride::template mapping< + Kokkos::extents> { int foo; }; // Fails with MSVC which adds some padding #ifndef MDSPAN_IMPL_COMPILER_MSVC -MDSPAN_STATIC_TEST( - std::is_trivially_copyable::value -); +MDSPAN_STATIC_TEST(std::is_trivially_copyable< + layout_stride_as_member_should_be_standard_layout>::value); #endif // end layouts }}}1 @@ -142,25 +98,17 @@ MDSPAN_STATIC_TEST( // {{{1 MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::mdspan> - >::value -); + std::is_trivially_copyable< + Kokkos::mdspan>>::value); -MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::mdspan> - >::value -); +MDSPAN_STATIC_TEST(std::is_trivially_copyable< + Kokkos::mdspan>>::value); MDSPAN_STATIC_TEST( - std::is_trivially_copyable< - Kokkos::mdspan< - double, Kokkos::extents, - Kokkos::layout_left, Kokkos::default_accessor - > - >::value -); + std::is_trivially_copyable, + Kokkos::layout_left, Kokkos::default_accessor>>::value); // end mdspan }}}1 //============================================================================== diff --git a/examples/aligned_accessor/aligned_accessor.cpp b/examples/aligned_accessor/aligned_accessor.cpp index 60f746c8..65d5452a 100644 --- a/examples/aligned_accessor/aligned_accessor.cpp +++ b/examples/aligned_accessor/aligned_accessor.cpp @@ -18,76 +18,88 @@ // Just checking __cpp_lib_int_pow2 isn't enough for some GCC versions. // The header exists, but std::has_single_bit does not. #if defined(__cpp_lib_int_pow2) && __cplusplus >= 202002L -# include +#include #endif #include #include -#include // aligned_alloc, posix_memalign (if applicable) +#include // aligned_alloc, posix_memalign (if applicable) #include #include #include #include #include -#include // stoi +#include // stoi // mfh 2022/08/08: This is based on my comment on RAPIDS RAFT issue 725: // https://github.com/rapidsai/raft/pull/725#discussion_r937991701 namespace { -using test_value_type = float; +using test_value_type = float; constexpr std::size_t min_overalignment_factor = 8; -constexpr std::size_t min_byte_alignment = min_overalignment_factor * sizeof(float); +constexpr std::size_t min_byte_alignment = + min_overalignment_factor * sizeof(float); // Use int, not size_t, as the index_type. -// Some compilers have trouble optimizing loops with unsigned or 64-bit index types. +// Some compilers have trouble optimizing loops with unsigned or 64-bit index +// types. using index_type = int; - // Prefer std::assume_aligned if available, as it is in the C++ Standard. // Otherwise, use a compiler-specific equivalent if available. // NOTE (mfh 2022/08/08) BYTE_ALIGNMENT must be unsigned and a power of 2. #if defined(__cpp_lib_assume_aligned) -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) (std::assume_aligned< BYTE_ALIGNMENT >( POINTER )) - constexpr char assume_aligned_method[] = "std::assume_aligned"; +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + (std::assume_aligned(POINTER)) +constexpr char assume_aligned_method[] = "std::assume_aligned"; #elif defined(__ICL) -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) POINTER - constexpr char assume_aligned_method[] = "(none)"; +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + POINTER +constexpr char assume_aligned_method[] = "(none)"; #elif defined(__ICC) -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) POINTER - constexpr char assume_aligned_method[] = "(none)"; +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + POINTER +constexpr char assume_aligned_method[] = "(none)"; #elif defined(__clang__) -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) POINTER - constexpr char assume_aligned_method[] = "(none)"; +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + POINTER +constexpr char assume_aligned_method[] = "(none)"; #elif defined(__GNUC__) - // __builtin_assume_aligned returns void* -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) reinterpret_cast< ELEMENT_TYPE* >(__builtin_assume_aligned( POINTER, BYTE_ALIGNMENT )) - constexpr char assume_aligned_method[] = "__builtin_assume_aligned"; +// __builtin_assume_aligned returns void* +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + reinterpret_cast( \ + __builtin_assume_aligned(POINTER, BYTE_ALIGNMENT)) +constexpr char assume_aligned_method[] = "__builtin_assume_aligned"; #else -# define MDSPAN_IMPL_ASSUME_ALIGNED( ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT ) POINTER - constexpr char assume_aligned_method[] = "(none)"; +#define MDSPAN_IMPL_ASSUME_ALIGNED(ELEMENT_TYPE, POINTER, BYTE_ALIGNMENT) \ + POINTER +constexpr char assume_aligned_method[] = "(none)"; #endif // Some compilers other than Clang or GCC like to define __clang__ or __GNUC__. // Thus, we order the tests from most to least specific. #if defined(__ICL) -# define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE( BYTE_ALIGNMENT ) __declspec(align_value( BYTE_ALIGNMENT )) - constexpr char align_attribute_method[] = "__declspec(align_value(BYTE_ALIGNMENT))"; +#define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE(BYTE_ALIGNMENT) \ + __declspec(align_value(BYTE_ALIGNMENT)) +constexpr char align_attribute_method[] = + "__declspec(align_value(BYTE_ALIGNMENT))"; #elif defined(__ICC) -# define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE( BYTE_ALIGNMENT ) __attribute__((align_value( BYTE_ALIGNMENT ))) - constexpr char align_attribute_method[] = "__attribute__((align_value(BYTE_ALIGNMENT)))"; +#define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE(BYTE_ALIGNMENT) \ + __attribute__((align_value(BYTE_ALIGNMENT))) +constexpr char align_attribute_method[] = + "__attribute__((align_value(BYTE_ALIGNMENT)))"; #elif defined(__clang__) -# define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE( BYTE_ALIGNMENT ) __attribute__((align_value( BYTE_ALIGNMENT ))) - constexpr char align_attribute_method[] = "__attribute__((align_value(BYTE_ALIGNMENT)))"; +#define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE(BYTE_ALIGNMENT) \ + __attribute__((align_value(BYTE_ALIGNMENT))) +constexpr char align_attribute_method[] = + "__attribute__((align_value(BYTE_ALIGNMENT)))"; #else -# define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE( BYTE_ALIGNMENT ) - constexpr char align_attribute_method[] = "(none)"; +#define MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE(BYTE_ALIGNMENT) +constexpr char align_attribute_method[] = "(none)"; #endif -constexpr bool -is_nonzero_power_of_two(const std::size_t x) -{ +constexpr bool is_nonzero_power_of_two(const std::size_t x) { // Just checking __cpp_lib_int_pow2 isn't enough for some GCC versions. // The header exists, but std::has_single_bit does not. #if defined(__cpp_lib_int_pow2) && __cplusplus >= 202002L @@ -97,76 +109,78 @@ is_nonzero_power_of_two(const std::size_t x) #endif } -template -constexpr bool -valid_byte_alignment(const std::size_t byte_alignment) -{ - return is_nonzero_power_of_two(byte_alignment) && byte_alignment >= alignof(ElementType); +template +constexpr bool valid_byte_alignment(const std::size_t byte_alignment) { + return is_nonzero_power_of_two(byte_alignment) && + byte_alignment >= alignof(ElementType); } // We define aligned_pointer_t through a struct // so we can check whether the byte alignment is valid. // This makes it impossible to use the alias // with an invalid byte alignment. -template +template struct aligned_pointer { static_assert(valid_byte_alignment(byte_alignment), - "byte_alignment must be a power of two no less than " - "the minimum required alignment of ElementType."); + "byte_alignment must be a power of two no less than " + "the minimum required alignment of ElementType."); #if defined(__ICC) - // x86-64 ICC 2021.5.0 emits warning #3186 ("expected typedef declaration") here. - // No other compiler (including Clang, which has a similar type attribute) has this issue. -# pragma warning push -# pragma warning disable 3186 + // x86-64 ICC 2021.5.0 emits warning #3186 ("expected typedef declaration") + // here. No other compiler (including Clang, which has a similar type + // attribute) has this issue. +#pragma warning push +#pragma warning disable 3186 #endif - using type = ElementType* MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE( byte_alignment ); + using type = ElementType* MDSPAN_IMPL_ALIGN_VALUE_ATTRIBUTE(byte_alignment); #if defined(__ICC) -# pragma warning pop +#pragma warning pop #endif }; -template -using aligned_pointer_t = typename aligned_pointer::type; +template +using aligned_pointer_t = + typename aligned_pointer::type; -template -aligned_pointer_t -bless(ElementType* ptr, std::integral_constant /* ba */ ) -{ - return MDSPAN_IMPL_ASSUME_ALIGNED( ElementType, ptr, byte_alignment ); +template +aligned_pointer_t bless( + ElementType* ptr, + std::integral_constant /* ba */) { + return MDSPAN_IMPL_ASSUME_ALIGNED(ElementType, ptr, byte_alignment); } -template +template struct aligned_accessor { - using offset_policy = Kokkos::default_accessor; - using element_type = ElementType; - using reference = ElementType&; + using offset_policy = Kokkos::default_accessor; + using element_type = ElementType; + using reference = ElementType&; using data_handle_type = aligned_pointer_t; constexpr aligned_accessor() noexcept = default; MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, - std::size_t other_byte_alignment, - /* requires */ (std::is_convertible::value && other_byte_alignment == byte_alignment) - ) - constexpr aligned_accessor(aligned_accessor) noexcept {} + class OtherElementType, std::size_t other_byte_alignment, + /* requires */ + (std::is_convertible::value&& + other_byte_alignment == byte_alignment)) + constexpr aligned_accessor( + aligned_accessor) noexcept {} constexpr reference access(data_handle_type p, size_t i) const noexcept { // This may declare alignment twice, depending on // if we have an attribute for marking pointer types. - return MDSPAN_IMPL_ASSUME_ALIGNED( ElementType, p, byte_alignment )[i]; + return MDSPAN_IMPL_ASSUME_ALIGNED(ElementType, p, byte_alignment)[i]; } - constexpr typename offset_policy::data_handle_type - offset(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 { return p + i; } }; -template +template struct delete_raw { void operator()(ElementType* p) const { if (p != nullptr) { @@ -178,39 +192,38 @@ struct delete_raw { } }; -template -using allocation_t = std::unique_ptr< - ElementType[], - delete_raw - >; +template +using allocation_t = std::unique_ptr>; -template -allocation_t -allocate_raw(const std::size_t num_elements) -{ +template +allocation_t allocate_raw(const std::size_t num_elements) { static_assert(byte_alignment >= sizeof(ElementType), - "byte_alignment must be at least sizeof(ElementType)."); - static constexpr std::size_t overalignment = byte_alignment / sizeof(ElementType); - static_assert(overalignment * sizeof(ElementType) == byte_alignment, - "overalignment * sizeof(ElementType) must equal byte_alignment."); + "byte_alignment must be at least sizeof(ElementType)."); + static constexpr std::size_t overalignment = + byte_alignment / sizeof(ElementType); + static_assert( + overalignment * sizeof(ElementType) == byte_alignment, + "overalignment * sizeof(ElementType) must equal byte_alignment."); const std::size_t num_bytes = num_elements * sizeof(ElementType); - auto deleter = delete_raw{}; + auto deleter = delete_raw{}; void* ptr = nullptr; #ifdef _MSC_VER // MSVC 19.32 (or "latest" on godbolt.org) does NOT have aligned_alloc, // even with /std:c++latest. Instead, we use MSVC-specific _aligned_malloc. ptr = _aligned_malloc(num_bytes, byte_alignment); -#elif __cplusplus < 201703L || (defined(__APPLE__) && defined(__apple_build_version__)) - // aligned_alloc is a C11 function. Apple Clang and GCC do not provide it with - // -std=c++14. We have coverage for the Windows case (at least with MSVC) above, - // so we can resort to the POSIX function posix_memalign. +#elif __cplusplus < 201703L || \ + (defined(__APPLE__) && defined(__apple_build_version__)) + // aligned_alloc is a C11 function. Apple Clang and GCC do not provide it + // with -std=c++14. We have coverage for the Windows case (at least with + // MSVC) above, so we can resort to the POSIX function posix_memalign. const int err = posix_memalign(&ptr, byte_alignment, num_bytes); - if(err != 0) { - if(err == EINVAL) { - throw std::runtime_error("posix_memalign failed: alignment not a power of two"); - } else if(err == ENOMEM) { + if (err != 0) { + if (err == EINVAL) { + throw std::runtime_error( + "posix_memalign failed: alignment not a power of two"); + } else if (err == ENOMEM) { throw std::runtime_error("posix_memalign failed: insufficient memory"); } else { throw std::runtime_error("posix_memalign failed: unknown error"); @@ -231,26 +244,28 @@ allocate_raw(const std::size_t num_elements) // // This needs to be a class in order to preserve the invariant that // "pointer" points to the allocation. -template +template class aligned_array_allocation { static_assert(byte_alignment >= sizeof(ElementType), - "byte_alignment must be at least sizeof(ElementType)."); - static constexpr std::size_t overalignment = byte_alignment / sizeof(ElementType); - static_assert(overalignment * sizeof(ElementType) == byte_alignment, - "overalignment * sizeof(ElementType) must equal byte_alignment."); -public: - aligned_array_allocation(std::size_t number_of_elements) : - allocation(allocate_raw(number_of_elements)), - pointer(allocation.get()), - num_elements(number_of_elements) - {} - - aligned_pointer_t data() const - { - return MDSPAN_IMPL_ASSUME_ALIGNED( ElementType, pointer, byte_alignment ); + "byte_alignment must be at least sizeof(ElementType)."); + static constexpr std::size_t overalignment = + byte_alignment / sizeof(ElementType); + static_assert( + overalignment * sizeof(ElementType) == byte_alignment, + "overalignment * sizeof(ElementType) must equal byte_alignment."); + + public: + aligned_array_allocation(std::size_t number_of_elements) + : allocation( + allocate_raw(number_of_elements)), + pointer(allocation.get()), + num_elements(number_of_elements) {} + + aligned_pointer_t data() const { + return MDSPAN_IMPL_ASSUME_ALIGNED(ElementType, pointer, byte_alignment); } -private: + private: allocation_t allocation{nullptr, delete_raw{}}; aligned_pointer_t pointer{nullptr}; std::size_t num_elements{0}; @@ -266,33 +281,30 @@ class aligned_array_allocation { // 2-wide SIMD code without needing a loop prelude or postlude to // handle the "unaligned remainder." Forcing "unalignment" will thus // give us a better performance comparison with the aligned case. -template +template class deliberately_unaligned_array_allocation { -public: - deliberately_unaligned_array_allocation(std::size_t number_of_elements) : - allocation(allocate_raw(number_of_elements + 1)), - pointer(unaligned_pointer(allocation.get())), - num_elements(number_of_elements) - {} - - ElementType* data() const { - return pointer; - } + public: + deliberately_unaligned_array_allocation(std::size_t number_of_elements) + : allocation(allocate_raw( + number_of_elements + 1)), + pointer(unaligned_pointer(allocation.get())), + num_elements(number_of_elements) {} + + ElementType* data() const { return pointer; } -private: + private: // Just asking for the minimum alignment of sizeof(ElementType) // bytes isn't enough, because the allocator might overalign that // allocation. Instead, we ask for an extra element, check whether // the allocation is "odd" or "even," and add one if needed. - static ElementType* - unaligned_pointer(ElementType* allocation_pointer) - { - if(allocation_pointer == nullptr) { + static ElementType* unaligned_pointer(ElementType* allocation_pointer) { + if (allocation_pointer == nullptr) { return nullptr; } - const auto ptr_as_uint = reinterpret_cast(allocation_pointer); + const auto ptr_as_uint = + reinterpret_cast(allocation_pointer); const auto bias = ptr_as_uint % std::uintptr_t(2 * sizeof(ElementType)); - if(bias == 0) { + if (bias == 0) { // It's aligned to sizeof(ElementType) times 2^k for integer k > 0. // Add one (that is, sizeof(ElementType) bytes) to make it "odd" again. return allocation_pointer + 1; @@ -306,45 +318,42 @@ class deliberately_unaligned_array_allocation { std::size_t num_elements{0}; }; -template +template using aligned_mdspan_1d = - Kokkos::mdspan, - Kokkos::layout_right, - aligned_accessor>; + Kokkos::mdspan, + Kokkos::layout_right, + aligned_accessor>; -template +template using mdspan_1d = - Kokkos::mdspan, - Kokkos::layout_right, - Kokkos::default_accessor>; + Kokkos::mdspan, + Kokkos::layout_right, Kokkos::default_accessor>; #define TICK() const auto tick = std::chrono::steady_clock::now() using double_seconds = std::chrono::duration>; -#define TOCK() std::chrono::duration_cast(std::chrono::steady_clock::now() - tick).count() +#define TOCK() \ + std::chrono::duration_cast( \ + std::chrono::steady_clock::now() - tick) \ + .count() -template -void add_aligned_mdspan_1d(aligned_mdspan_1d x, - aligned_mdspan_1d y, - aligned_mdspan_1d z) -{ +template +void add_aligned_mdspan_1d( + aligned_mdspan_1d x, + aligned_mdspan_1d y, + aligned_mdspan_1d z) { const index_type n = z.extent(0); for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_aligned_mdspan_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant /* ba */ ) -{ +template +auto benchmark_add_aligned_mdspan_1d( + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant /* ba */) { TICK(); aligned_mdspan_1d x2{x, n}; aligned_mdspan_1d y2{y, n}; @@ -355,24 +364,19 @@ auto benchmark_add_aligned_mdspan_1d(const std::size_t num_trials, return TOCK(); } -template +template void add_mdspan_1d(mdspan_1d x, - mdspan_1d y, - mdspan_1d z) -{ + mdspan_1d y, mdspan_1d z) { const index_type n = z.extent(0); for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_mdspan_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ +template +auto benchmark_add_mdspan_1d(const std::size_t num_trials, const index_type n, + const ElementType x[], const ElementType y[], + ElementType z[]) { TICK(); mdspan_1d x2{x, n}; mdspan_1d y2{y, n}; @@ -383,24 +387,18 @@ auto benchmark_add_mdspan_1d(const std::size_t num_trials, return TOCK(); } -template -void add_raw_1d(const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ +template +void add_raw_1d(const index_type n, const ElementType x[], + const ElementType y[], ElementType z[]) { for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_raw_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ +template +auto benchmark_add_raw_1d(const std::size_t num_trials, const index_type n, + const ElementType x[], const ElementType y[], + ElementType z[]) { TICK(); for (std::size_t trial = 0; trial < num_trials; ++trial) { add_raw_1d(n, x, y, z); @@ -409,42 +407,39 @@ auto benchmark_add_raw_1d(const std::size_t num_trials, } // Assume that x, y, and z all have the same alignment. -template +template void add_aligned_raw_1d(const index_type n, - aligned_pointer_t x, - aligned_pointer_t y, - aligned_pointer_t z) -{ + aligned_pointer_t x, + aligned_pointer_t y, + aligned_pointer_t z) { for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } // Assume that x, y, and z all have the same alignment. -template -auto benchmark_add_aligned_raw_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant ba) -{ +template +auto benchmark_add_aligned_raw_1d( + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant ba) { TICK(); auto x_blessed = bless(x, ba); auto y_blessed = bless(y, ba); auto z_blessed = bless(z, ba); for (std::size_t trial = 0; trial < num_trials; ++trial) { - add_aligned_raw_1d(n, x_blessed, y_blessed, z_blessed); + add_aligned_raw_1d(n, x_blessed, y_blessed, + z_blessed); } return TOCK(); } #ifdef _OPENMP -template -void add_omp_simd_aligned_mdspan_1d(aligned_mdspan_1d x, - aligned_mdspan_1d y, - aligned_mdspan_1d z) -{ +template +void add_omp_simd_aligned_mdspan_1d( + aligned_mdspan_1d x, + aligned_mdspan_1d y, + aligned_mdspan_1d z) { const index_type n = z.extent(0); // Test whether OpenMP can figure out that the pointers are aligned. #pragma omp simd @@ -453,14 +448,11 @@ void add_omp_simd_aligned_mdspan_1d(aligned_mdspan_1d -auto benchmark_add_omp_simd_aligned_mdspan_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant /* ba */ ) -{ +template +auto benchmark_add_omp_simd_aligned_mdspan_1d( + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant /* ba */) { TICK(); aligned_mdspan_1d x2{x, n}; aligned_mdspan_1d y2{y, n}; @@ -471,11 +463,10 @@ auto benchmark_add_omp_simd_aligned_mdspan_1d(const std::size_t num_trials, return TOCK(); } -template +template void add_omp_simd_mdspan_1d(mdspan_1d x, - mdspan_1d y, - mdspan_1d z) -{ + mdspan_1d y, + mdspan_1d z) { const index_type n = z.extent(0); #pragma omp simd for (index_type i = 0; i < n; ++i) { @@ -483,13 +474,10 @@ void add_omp_simd_mdspan_1d(mdspan_1d x, } } -template +template auto benchmark_add_omp_simd_mdspan_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ + const index_type n, const ElementType x[], + const ElementType y[], ElementType z[]) { TICK(); mdspan_1d x2{x, n}; mdspan_1d y2{y, n}; @@ -500,25 +488,19 @@ auto benchmark_add_omp_simd_mdspan_1d(const std::size_t num_trials, return TOCK(); } -template -void add_omp_simd_raw_1d(const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ +template +void add_omp_simd_raw_1d(const index_type n, const ElementType x[], + const ElementType y[], ElementType z[]) { #pragma omp simd for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template +template auto benchmark_add_omp_simd_raw_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[]) -{ + const index_type n, const ElementType x[], + const ElementType y[], ElementType z[]) { TICK(); for (std::size_t trial = 0; trial < num_trials; ++trial) { add_omp_simd_raw_1d(n, x, y, z); @@ -526,31 +508,26 @@ auto benchmark_add_omp_simd_raw_1d(const std::size_t num_trials, return TOCK(); } -template -void add_omp_aligned_simd_raw_1d(const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant /* ba */ ) -{ +template +void add_omp_aligned_simd_raw_1d( + const index_type n, const ElementType x[], const ElementType y[], + ElementType z[], + std::integral_constant /* ba */) { // The "aligned" clause might only work // for pointers or (raw) arrays. // C++23 adopting mdspan might change that, // at least for the default layout and accessor. -#pragma omp simd aligned(z,x,y:byte_alignment) +#pragma omp simd aligned(z, x, y : byte_alignment) for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_omp_aligned_simd_raw_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant ba) -{ +template +auto benchmark_add_omp_aligned_simd_raw_1d( + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant ba) { TICK(); for (std::size_t trial = 0; trial < num_trials; ++trial) { add_omp_aligned_simd_raw_1d(n, x, y, z, ba); @@ -558,12 +535,11 @@ auto benchmark_add_omp_aligned_simd_raw_1d(const std::size_t num_trials, return TOCK(); } -template -void add_omp_simd_aligned_raw_1d(const index_type n, - aligned_pointer_t x, - aligned_pointer_t y, - aligned_pointer_t z) -{ +template +void add_omp_simd_aligned_raw_1d( + const index_type n, aligned_pointer_t x, + aligned_pointer_t y, + aligned_pointer_t z) { #pragma omp simd for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; @@ -571,46 +547,39 @@ void add_omp_simd_aligned_raw_1d(const index_type n, } // Assume that x, y, and z all have the same alignment. -template -auto benchmark_add_omp_simd_aligned_raw_1d(const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant ba) -{ +template +auto benchmark_add_omp_simd_aligned_raw_1d( + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant ba) { TICK(); auto x_blessed = bless(x, ba); auto y_blessed = bless(y, ba); auto z_blessed = bless(z, ba); for (std::size_t trial = 0; trial < num_trials; ++trial) { - add_omp_simd_aligned_raw_1d(n, x_blessed, y_blessed, z_blessed); + add_omp_simd_aligned_raw_1d( + n, x_blessed, y_blessed, z_blessed); } return TOCK(); } -template -void add_omp_aligned_simd_aligned_raw_1d(const index_type n, - aligned_pointer_t x, - aligned_pointer_t y, - aligned_pointer_t z) -{ -#pragma omp simd aligned(z,x,y:byte_alignment) +template +void add_omp_aligned_simd_aligned_raw_1d( + const index_type n, aligned_pointer_t x, + aligned_pointer_t y, + aligned_pointer_t z) { +#pragma omp simd aligned(z, x, y : byte_alignment) for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } // Assume that x, y, and z all have the same alignment. -template +template auto benchmark_add_omp_aligned_simd_aligned_raw_1d( - const std::size_t num_trials, - const index_type n, - const ElementType x[], - const ElementType y[], - ElementType z[], - std::integral_constant ba) -{ + const std::size_t num_trials, const index_type n, const ElementType x[], + const ElementType y[], ElementType z[], + std::integral_constant ba) { TICK(); auto x_blessed = bless(x, ba); auto y_blessed = bless(y, ba); @@ -619,18 +588,16 @@ auto benchmark_add_omp_aligned_simd_aligned_raw_1d( // Passing in ba doesn't help the compiler // deduce the template parameters, // so we just specify them explicitly. - add_omp_aligned_simd_aligned_raw_1d(n, x_blessed, y_blessed, z_blessed); + add_omp_aligned_simd_aligned_raw_1d( + n, x_blessed, y_blessed, z_blessed); } return TOCK(); } -#endif // _OPENMP - -template -void set_elements_of_arrays(const index_type n, - ElementType x[], - ElementType y[], - ElementType z[]) -{ +#endif // _OPENMP + +template +void set_elements_of_arrays(const index_type n, ElementType x[], + ElementType y[], ElementType z[]) { for (index_type i = 0; i < n; ++i) { x[i] = 1.0; y[i] = 2.0; @@ -638,75 +605,73 @@ void set_elements_of_arrays(const index_type n, } } -} // namespace (anonymous) +} // namespace -int main(int argc, char* argv[]) -{ - using std::cout; +int main(int argc, char* argv[]) { using std::cerr; + using std::cout; using std::endl; - constexpr std::integral_constant byte_alignment; + constexpr std::integral_constant + byte_alignment; - if(argc != 3) { + if (argc != 3) { cerr << "Usage: main " << endl; return -1; } - const int n = std::stoi(argv[1]); + const int n = std::stoi(argv[1]); const int num_trials = std::stoi(argv[2]); aligned_array_allocation x_aligned(n); aligned_array_allocation y_aligned(n); aligned_array_allocation z_aligned(n); - set_elements_of_arrays(n, x_aligned.data(), y_aligned.data(), z_aligned.data()); - - auto aligned_mdspan_result = - benchmark_add_aligned_mdspan_1d(num_trials, n, x_aligned.data(), - y_aligned.data(), z_aligned.data(), - byte_alignment); - auto aligned_raw_result = - benchmark_add_aligned_raw_1d(num_trials, n, x_aligned.data(), - y_aligned.data(), z_aligned.data(), - byte_alignment); + set_elements_of_arrays(n, x_aligned.data(), y_aligned.data(), + z_aligned.data()); + + auto aligned_mdspan_result = benchmark_add_aligned_mdspan_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); + auto aligned_raw_result = benchmark_add_aligned_raw_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); #ifdef _OPENMP auto omp_simd_aligned_mdspan_result = - benchmark_add_omp_simd_aligned_mdspan_1d(num_trials, n, x_aligned.data(), - y_aligned.data(), z_aligned.data(), - byte_alignment); - auto omp_aligned_simd_raw_result = - benchmark_add_omp_aligned_simd_raw_1d(num_trials, n, - x_aligned.data(), y_aligned.data(), - z_aligned.data(), byte_alignment); - auto omp_simd_aligned_raw_result = - benchmark_add_omp_simd_aligned_raw_1d(num_trials, n, - x_aligned.data(), y_aligned.data(), - z_aligned.data(), byte_alignment); + benchmark_add_omp_simd_aligned_mdspan_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); + auto omp_aligned_simd_raw_result = benchmark_add_omp_aligned_simd_raw_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); + auto omp_simd_aligned_raw_result = benchmark_add_omp_simd_aligned_raw_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); auto omp_aligned_simd_aligned_raw_result = - benchmark_add_omp_aligned_simd_aligned_raw_1d(num_trials, n, - x_aligned.data(), y_aligned.data(), - z_aligned.data(), byte_alignment); -#endif // _OPENMP + benchmark_add_omp_aligned_simd_aligned_raw_1d( + num_trials, n, x_aligned.data(), y_aligned.data(), z_aligned.data(), + byte_alignment); +#endif // _OPENMP deliberately_unaligned_array_allocation x_unaligned(n); deliberately_unaligned_array_allocation y_unaligned(n); deliberately_unaligned_array_allocation z_unaligned(n); - set_elements_of_arrays(n, x_unaligned.data(), y_unaligned.data(), z_unaligned.data()); + set_elements_of_arrays(n, x_unaligned.data(), y_unaligned.data(), + z_unaligned.data()); auto mdspan_result = - benchmark_add_mdspan_1d(num_trials, n, x_unaligned.data(), - y_unaligned.data(), z_unaligned.data()); + benchmark_add_mdspan_1d(num_trials, n, x_unaligned.data(), + y_unaligned.data(), z_unaligned.data()); auto raw_result = - benchmark_add_raw_1d(num_trials, n, x_unaligned.data(), - y_unaligned.data(), z_unaligned.data()); + benchmark_add_raw_1d(num_trials, n, x_unaligned.data(), + y_unaligned.data(), z_unaligned.data()); #ifdef _OPENMP auto omp_simd_mdspan_result = - benchmark_add_omp_simd_mdspan_1d(num_trials, n, x_unaligned.data(), - y_unaligned.data(), z_unaligned.data()); + benchmark_add_omp_simd_mdspan_1d(num_trials, n, x_unaligned.data(), + y_unaligned.data(), z_unaligned.data()); auto omp_simd_raw_result = - benchmark_add_omp_simd_raw_1d(num_trials, n, x_unaligned.data(), - y_unaligned.data(), z_unaligned.data()); -#endif // _OPENMP + benchmark_add_omp_simd_raw_1d(num_trials, n, x_unaligned.data(), + y_unaligned.data(), z_unaligned.data()); +#endif // _OPENMP cout << "Number of trials: " << num_trials << endl << "Number of loop iterations per trial: " << n << endl @@ -722,7 +687,8 @@ int main(int argc, char* argv[]) #ifdef _OPENMP cout << "Total time in seconds for OpenMP (omp simd) loops:" << endl - << " omp_simd_aligned_mdspan: " << omp_simd_aligned_mdspan_result << endl + << " omp_simd_aligned_mdspan: " << omp_simd_aligned_mdspan_result + << endl << " omp_simd_mdspan: " << omp_simd_mdspan_result << endl << " omp_simd_raw: " << omp_simd_raw_result << endl << " omp_aligned_simd_raw (aligned clause): " @@ -731,6 +697,6 @@ int main(int argc, char* argv[]) << omp_simd_aligned_raw_result << endl << " omp_aligned_simd_aligned_raw (both): " << omp_aligned_simd_aligned_raw_result << endl; -#endif // _OPENMP +#endif // _OPENMP return 0; } diff --git a/examples/dot_product/dot_product.cpp b/examples/dot_product/dot_product.cpp index 7141177a..5aff3250 100644 --- a/examples/dot_product/dot_product.cpp +++ b/examples/dot_product/dot_product.cpp @@ -19,8 +19,8 @@ #include #include - -#if !(defined(__cpp_lib_make_unique) && __cpp_lib_make_unique >= 201304) && !MDSPAN_HAS_CXX_14 +#if !(defined(__cpp_lib_make_unique) && __cpp_lib_make_unique >= 201304) && \ + !MDSPAN_HAS_CXX_14 // Not actually conforming, but it works for the purposes of this file namespace std { template @@ -32,33 +32,28 @@ struct __unique_ptr_new_impl { }; template struct __unique_ptr_new_impl { - static T* __impl(size_t size) { - return new T[size]; - } + static T* __impl(size_t size) { return new T[size]; } }; template std::unique_ptr make_unique(Args&&... args) { return std::unique_ptr(__unique_ptr_new_impl::__impl((Args&&)args...)); } -} // end namespace std +} // end namespace std #endif //================================================================================ -template < - class T, - class ExtsA, class LayA, class AccA, - class ExtsB, class LayB, class AccB -> +template T dot_product( - Kokkos::mdspan a, - Kokkos::mdspan b -) //requires ExtsA::rank() == ExtsB::rank() && ExtsA::rank() == 2 + Kokkos::mdspan a, + Kokkos::mdspan + b) // requires ExtsA::rank() == ExtsB::rank() && ExtsA::rank() == 2 { using int_t = typename ExtsA::index_type; - T result = 0; - for(int_t i = 0; i < a.extent(0); ++i) { - for(int_t j = 0; j < a.extent(1); ++j) { + T result = 0; + for (int_t i = 0; i < a.extent(0); ++i) { + for (int_t j = 0; j < a.extent(1); ++j) { #if MDSPAN_USE_BRACKET_OPERATOR result += a[i, j] * b[i, j]; #else @@ -71,18 +66,14 @@ T dot_product( //================================================================================ -template < - class T, - class ExtsA, class LayA, class AccA -> +template void fill_in_order( - Kokkos::mdspan a -) // requires ExtsA::rank() == 2 + Kokkos::mdspan a) // requires ExtsA::rank() == 2 { using int_t = typename ExtsA::index_type; - T count = 0; - for(int_t i = 0; i < a.extent(0); ++i) { - for(int_t j = 0; j < a.extent(1); ++j) { + T count = 0; + for (int_t i = 0; i < a.extent(0); ++i) { + for (int_t j = 0; j < a.extent(1); ++j) { #if MDSPAN_USE_BRACKET_OPERATOR a[i, j] = count++; #else @@ -101,8 +92,10 @@ constexpr int cols = 3; int main() { { - using span_2d_dynamic = Kokkos::mdspan, Kokkos::layout_right>; - using span_2d_dynamic_left = Kokkos::mdspan, Kokkos::layout_left>; + using span_2d_dynamic = + Kokkos::mdspan, Kokkos::layout_right>; + using span_2d_dynamic_left = + Kokkos::mdspan, Kokkos::layout_left>; auto data_a = std::make_unique(rows * cols); auto data_b = std::make_unique(rows * cols); @@ -116,8 +109,12 @@ int main() { } { - using span_2d_10_10 = Kokkos::mdspan, Kokkos::layout_right>; - using span_2d_10_10_left = Kokkos::mdspan, Kokkos::layout_right>; + using span_2d_10_10 = + Kokkos::mdspan, + Kokkos::layout_right>; + using span_2d_10_10_left = + Kokkos::mdspan, + Kokkos::layout_right>; auto data_a = std::make_unique(100); auto data_b = std::make_unique(100); @@ -129,5 +126,4 @@ int main() { std::cout << dot_product(a, b) << std::endl; } - } diff --git a/examples/godbolt_starter/godbolt_starter.cpp b/examples/godbolt_starter/godbolt_starter.cpp index 8b5f29f5..08d1f742 100644 --- a/examples/godbolt_starter/godbolt_starter.cpp +++ b/examples/godbolt_starter/godbolt_starter.cpp @@ -19,12 +19,9 @@ #include #include - int main() { std::array d{ - 0, 5, 1, - 3, 8, 4, - 2, 7, 6, + 0, 5, 1, 3, 8, 4, 2, 7, 6, }; Kokkos::mdspan m{d.data(), Kokkos::extents{3, 3}}; diff --git a/examples/restrict_accessor/restrict_accessor.cpp b/examples/restrict_accessor/restrict_accessor.cpp index f4e7d409..c565ca3d 100644 --- a/examples/restrict_accessor/restrict_accessor.cpp +++ b/examples/restrict_accessor/restrict_accessor.cpp @@ -20,23 +20,23 @@ #include #include #include -#include // stoi +#include // stoi // mfh 2022/08/04: This is based on my comments on reference mdspan // implementation issue https://github.com/kokkos/mdspan/issues/169. namespace { - #if defined(MDSPAN_IMPL_COMPILER_MSVC) || defined(__INTEL_COMPILER) -# define MDSPAN_IMPL_RESTRICT_KEYWORD __restrict +#define MDSPAN_IMPL_RESTRICT_KEYWORD __restrict #elif defined(__GNUC__) || defined(__clang__) -# define MDSPAN_IMPL_RESTRICT_KEYWORD __restrict__ +#define MDSPAN_IMPL_RESTRICT_KEYWORD __restrict__ #else -# define MDSPAN_IMPL_RESTRICT_KEYWORD +#define MDSPAN_IMPL_RESTRICT_KEYWORD #endif -#define MDSPAN_IMPL_RESTRICT_POINTER( ELEMENT_TYPE ) ELEMENT_TYPE * MDSPAN_IMPL_RESTRICT_KEYWORD +#define MDSPAN_IMPL_RESTRICT_POINTER(ELEMENT_TYPE) \ + ELEMENT_TYPE* MDSPAN_IMPL_RESTRICT_KEYWORD // https://en.cppreference.com/w/c/language/restrict gives examples // of the kinds of optimizations that may apply to restrict. For instance, @@ -46,79 +46,88 @@ namespace { // // void f(int n, float * restrict r, float * restrict s) { // float * p = r, * q = s; // OK -// while(n-- > 0) *p++ = *q++; // almost certainly optimized just like *r++ = *s++ +// while(n-- > 0) *p++ = *q++; // almost certainly optimized just like *r++ = +// *s++ // } // -// This is relevant because restrict_accessor::reference is _not_ restrict. -// (It's not formally correct to apply C restrict wording to C++ references. -// However, GCC defines this extension: +// This is relevant because restrict_accessor::reference is _not_ +// restrict. (It's not formally correct to apply C restrict wording to C++ +// references. However, GCC defines this extension: // // https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html // // In what follows, I'll assume that this has a reasonable definition.) -// The idea is that even though p[i] has type ElementType& and not ElementType& restrict, -// the compiler can figure out that the reference comes from a pointer based on p, -// which is marked restrict. +// The idea is that even though p[i] has type ElementType& and not ElementType& +// restrict, the compiler can figure out that the reference comes from a pointer +// based on p, which is marked restrict. // // Note that any performance improvements can only be determined by experiment. // Compilers are not required to do anything with restrict. // Any use of this keyword is not Standard C++, // so you'll have to refer to the compiler's documentation, // look at the assembler output, and do performance experiments. -template +template struct restrict_accessor { - using offset_policy = Kokkos::default_accessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = MDSPAN_IMPL_RESTRICT_POINTER( ElementType ); + using offset_policy = Kokkos::default_accessor; + using element_type = ElementType; + using reference = ElementType&; + using data_handle_type = MDSPAN_IMPL_RESTRICT_POINTER(ElementType); constexpr restrict_accessor() noexcept = default; MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, - /* requires */ (std::is_convertible::value) - ) + class OtherElementType, + /* requires */ (std::is_convertible::value)) constexpr restrict_accessor(restrict_accessor) noexcept {} constexpr reference access(data_handle_type p, size_t i) const noexcept { return p[i]; } - constexpr typename offset_policy::data_handle_type - offset(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 { return p + i; } }; // Use int, not size_t, as the index_type. -// Some compilers have trouble optimizing loops with unsigned or 64-bit index types. +// Some compilers have trouble optimizing loops with unsigned or 64-bit index +// types. using index_type = int; -template +template using restrict_mdspan_1d = - Kokkos::mdspan, Kokkos::layout_right, restrict_accessor>; + Kokkos::mdspan, + Kokkos::layout_right, restrict_accessor>; -template +template using mdspan_1d = - Kokkos::mdspan, Kokkos::layout_right, Kokkos::default_accessor>; + Kokkos::mdspan, + Kokkos::layout_right, Kokkos::default_accessor>; #define TICK() const auto tick = std::chrono::steady_clock::now() using double_seconds = std::chrono::duration>; -#define TOCK() std::chrono::duration_cast(std::chrono::steady_clock::now() - tick).count() +#define TOCK() \ + std::chrono::duration_cast( \ + std::chrono::steady_clock::now() - tick) \ + .count() -template -void add_restrict_mdspan_1d(restrict_mdspan_1d x, restrict_mdspan_1d y, restrict_mdspan_1d z) -{ +template +void add_restrict_mdspan_1d(restrict_mdspan_1d x, + restrict_mdspan_1d y, + restrict_mdspan_1d z) { const index_type n = z.extent(0); for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_restrict_mdspan_1d(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto benchmark_add_restrict_mdspan_1d(const std::size_t num_trials, + const index_type n, const ElementType* x, + const ElementType* y, ElementType* z) { TICK(); restrict_mdspan_1d x2{x, n}; restrict_mdspan_1d y2{y, n}; @@ -129,18 +138,19 @@ auto benchmark_add_restrict_mdspan_1d(const std::size_t num_trials, const index_ return TOCK(); } -template -void add_mdspan_1d(mdspan_1d x, mdspan_1d y, mdspan_1d z) -{ +template +void add_mdspan_1d(mdspan_1d x, + mdspan_1d y, mdspan_1d z) { const index_type n = z.extent(0); for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_mdspan_1d(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto benchmark_add_mdspan_1d(const std::size_t num_trials, const index_type n, + const ElementType* x, const ElementType* y, + ElementType* z) { TICK(); mdspan_1d x2{x, n}; mdspan_1d y2{y, n}; @@ -151,17 +161,18 @@ auto benchmark_add_mdspan_1d(const std::size_t num_trials, const index_type n, c return TOCK(); } -template -void add_raw_1d(const index_type n, const ElementType x[], const ElementType y[], ElementType z[]) -{ +template +void add_raw_1d(const index_type n, const ElementType x[], + const ElementType y[], ElementType z[]) { for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_raw_1d(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto benchmark_add_raw_1d(const std::size_t num_trials, const index_type n, + const ElementType* x, const ElementType* y, + ElementType* z) { TICK(); for (std::size_t trial = 0; trial < num_trials; ++trial) { add_raw_1d(n, x, y, z); @@ -169,24 +180,24 @@ auto benchmark_add_raw_1d(const std::size_t num_trials, const index_type n, cons return TOCK(); } -template +template void add_restrict_raw_1d(const index_type n, - MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x, - MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y, - MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z) -{ + MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x, + MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y, + MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z) { for (index_type i = 0; i < n; ++i) { z[i] = x[i] + y[i]; } } -template -auto benchmark_add_restrict_raw_1d(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto benchmark_add_restrict_raw_1d(const std::size_t num_trials, + const index_type n, const ElementType* x, + const ElementType* y, ElementType* z) { TICK(); MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x2 = x; MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y2 = y; - MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z2 = z; + MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z2 = z; for (std::size_t trial = 0; trial < num_trials; ++trial) { add_restrict_raw_1d(n, x2, y2, z2); } @@ -195,65 +206,69 @@ auto benchmark_add_restrict_raw_1d(const std::size_t num_trials, const index_typ // Start with restrict pointers, then assign to nonrestrict pointers. // This checks whether the compiler's alias analysis suffices. -template +template void add_unrestrict_raw_1d(const index_type n, - MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x, - MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y, - MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z) -{ + MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x, + MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y, + MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z) { const ElementType* x2 = x; const ElementType* y2 = y; - ElementType* z2 = z; + ElementType* z2 = z; add_raw_1d(n, x2, y2, z2); } -template -auto benchmark_add_unrestrict_raw_1d(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto benchmark_add_unrestrict_raw_1d(const std::size_t num_trials, + const index_type n, const ElementType* x, + const ElementType* y, ElementType* z) { TICK(); MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) x2 = x; MDSPAN_IMPL_RESTRICT_POINTER(const ElementType) y2 = y; - MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z2 = z; + MDSPAN_IMPL_RESTRICT_POINTER(ElementType) z2 = z; for (std::size_t trial = 0; trial < num_trials; ++trial) { add_unrestrict_raw_1d(n, x2, y2, z2); } return TOCK(); } -template -auto warmup(const std::size_t num_trials, const index_type n, const ElementType* x, const ElementType* y, ElementType* z) -{ +template +auto warmup(const std::size_t num_trials, const index_type n, + const ElementType* x, const ElementType* y, ElementType* z) { return benchmark_add_raw_1d(num_trials, n, x, y, z); } -} // namespace (anonymous) +} // namespace -int main(int argc, char* argv[]) -{ - using std::cout; +int main(int argc, char* argv[]) { using std::cerr; + using std::cout; using std::endl; - if(argc != 3) { + if (argc != 3) { cerr << "Usage: main " << endl; return -1; } - int n = 10000; + int n = 10000; int num_trials = 100; - n = std::stoi(argv[1]); - num_trials = std::stoi(argv[2]); + n = std::stoi(argv[1]); + num_trials = std::stoi(argv[2]); std::vector x(n); std::vector y(n); std::vector z(n); auto warmup_result = warmup(num_trials, n, x.data(), y.data(), z.data()); - auto restrict_mdspan_result = benchmark_add_restrict_mdspan_1d(num_trials, n, x.data(), y.data(), z.data()); - auto mdspan_result = benchmark_add_mdspan_1d(num_trials, n, x.data(), y.data(), z.data()); - auto raw_result = benchmark_add_raw_1d(num_trials, n, x.data(), y.data(), z.data()); - auto restrict_raw_result = benchmark_add_restrict_raw_1d(num_trials, n, x.data(), y.data(), z.data()); - auto unrestrict_raw_result = benchmark_add_unrestrict_raw_1d(num_trials, n, x.data(), y.data(), z.data()); + auto restrict_mdspan_result = benchmark_add_restrict_mdspan_1d( + num_trials, n, x.data(), y.data(), z.data()); + auto mdspan_result = + benchmark_add_mdspan_1d(num_trials, n, x.data(), y.data(), z.data()); + auto raw_result = + benchmark_add_raw_1d(num_trials, n, x.data(), y.data(), z.data()); + auto restrict_raw_result = benchmark_add_restrict_raw_1d( + num_trials, n, x.data(), y.data(), z.data()); + auto unrestrict_raw_result = benchmark_add_unrestrict_raw_1d( + num_trials, n, x.data(), y.data(), z.data()); cout << "num_trials: " << num_trials << ", n: " << n << endl << "Total time (unit: second):" << endl diff --git a/examples/tiled_layout/simple_tiled_layout.cpp b/examples/tiled_layout/simple_tiled_layout.cpp index e707ae4b..e9cc0918 100644 --- a/examples/tiled_layout/simple_tiled_layout.cpp +++ b/examples/tiled_layout/simple_tiled_layout.cpp @@ -19,35 +19,28 @@ #include #include - // Simple tiled layout. // Hard-coded for 2D, column-major across tiles // and row-major within each tile struct SimpleTileLayout2D { template struct mapping { - // for simplicity - static_assert(Extents::rank() == 2, "SimpleTileLayout2D is hard-coded for 2D layout"); + static_assert(Extents::rank() == 2, + "SimpleTileLayout2D is hard-coded for 2D layout"); using extents_type = Extents; - using rank_type = typename Extents::rank_type; - using size_type = typename Extents::size_type; - using layout_type = SimpleTileLayout2D; + using rank_type = typename Extents::rank_type; + using size_type = typename Extents::size_type; + using layout_type = SimpleTileLayout2D; - mapping() noexcept = default; - mapping(const mapping&) noexcept = default; + mapping() noexcept = default; + mapping(const mapping&) noexcept = default; mapping& operator=(const mapping&) noexcept = default; - mapping( - Extents const& exts, - size_type row_tile, - size_type col_tile - ) noexcept - : extents_(exts), - row_tile_size_(row_tile), - col_tile_size_(col_tile) - { + mapping(Extents const& exts, size_type row_tile, + size_type col_tile) noexcept + : extents_(exts), row_tile_size_(row_tile), col_tile_size_(col_tile) { // For simplicity, don't worry about negatives/zeros/etc. assert(row_tile > 0); assert(col_tile > 0); @@ -56,38 +49,34 @@ struct SimpleTileLayout2D { } MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ (::std::is_constructible::value) - ) + class OtherExtents, + /* requires */ ( + ::std::is_constructible::value)) MDSPAN_CONDITIONAL_EXPLICIT( - (!::std::is_convertible::value) - ) - constexpr mapping(const mapping& input_mapping) noexcept : - extents_(input_mapping.extents()), - row_tile_size_(input_mapping.row_tile_size_), - col_tile_size_(input_mapping.col_tile_size_) - {} + (!::std::is_convertible::value)) + constexpr mapping(const mapping& input_mapping) noexcept + : extents_(input_mapping.extents()), + row_tile_size_(input_mapping.row_tile_size_), + col_tile_size_(input_mapping.col_tile_size_) {} //------------------------------------------------------------ // Helper members (not part of the layout concept) - constexpr size_type - n_row_tiles() const noexcept { - return extents_.extent(0) / row_tile_size_ + size_type((extents_.extent(0) % row_tile_size_) != 0); + constexpr size_type n_row_tiles() const noexcept { + return extents_.extent(0) / row_tile_size_ + + size_type((extents_.extent(0) % row_tile_size_) != 0); } - constexpr size_type - n_column_tiles() const noexcept { - return extents_.extent(1) / col_tile_size_ + size_type((extents_.extent(1) % col_tile_size_) != 0); + constexpr size_type n_column_tiles() const noexcept { + return extents_.extent(1) / col_tile_size_ + + size_type((extents_.extent(1) % col_tile_size_) != 0); } - constexpr size_type - tile_size() const noexcept { + constexpr size_type tile_size() const noexcept { return row_tile_size_ * col_tile_size_; } - size_type - tile_offset(size_type row, size_type col) const noexcept { + size_type tile_offset(size_type row, size_type col) const noexcept { // This could probably be more efficient, but for example purposes... auto col_tile = col / col_tile_size_; auto row_tile = row / row_tile_size_; @@ -95,8 +84,7 @@ struct SimpleTileLayout2D { return (col_tile * n_row_tiles() + row_tile) * tile_size(); } - size_type - offset_in_tile(size_type row, size_type col) const noexcept { + size_type offset_in_tile(size_type row, size_type col) const noexcept { auto t_row = row % row_tile_size_; auto t_col = col % col_tile_size_; // We're hard-coding this to *row-major* within tiles @@ -106,79 +94,81 @@ struct SimpleTileLayout2D { //------------------------------------------------------------ // Required members - constexpr const extents_type& extents() const { - return extents_; - } + constexpr const extents_type& extents() const { return extents_; } - constexpr size_type - required_span_size() const noexcept { + constexpr size_type required_span_size() const noexcept { return n_row_tiles() * n_column_tiles() * tile_size(); } - template + template // requires(is_convertible_v && // is_convertible_v && // is_nothrow_constructible_v && // is_nothrow_constructible_v) - constexpr size_type - operator()(RowIndex row, ColIndex col) const noexcept { + constexpr size_type operator()(RowIndex row, ColIndex col) const noexcept { // TODO (mfh 2022/08/04 check precondition that // extents_type::index-cast(row, col) // is a multidimensional index in extents_. return tile_offset(row, col) + offset_in_tile(row, col); } - // Mapping is always unique static constexpr bool is_always_unique() noexcept { return true; } - // Only exhaustive if extents_.extent(0) % column_tile_size == 0, so not always + // Only exhaustive if extents_.extent(0) % column_tile_size == 0, so not + // always static constexpr bool is_always_exhaustive() noexcept { return false; } - // There is not always a regular stride between elements in a given dimension + // There is not always a regular stride between elements in a given + // dimension static constexpr bool is_always_strided() noexcept { return false; } static constexpr bool is_unique() noexcept { return true; } constexpr bool is_exhaustive() const noexcept { // Only exhaustive if extents fit exactly into tile sizes... - return (extents_.extent(0) % row_tile_size_ == 0) && (extents_.extent(1) % col_tile_size_ == 0); + return (extents_.extent(0) % row_tile_size_ == 0) && + (extents_.extent(1) % col_tile_size_ == 0); } // There are some circumstances where this is strided, but we're not - // concerned about that optimization, so we're allowed to just return false here + // concerned about that optimization, so we're allowed to just return false + // here constexpr bool is_strided() const noexcept { return false; } - private: + private: Extents extents_; size_type row_tile_size_ = 1; size_type col_tile_size_ = 1; }; }; - - int main() { //---------------------------------------- // 5x2 example, tiled as 3x3 constexpr int n_rows = 2; constexpr int n_cols = 5; int data_row_major[] = { - 1, 2, 3, /*|*/ 4, 5, /* X | */ - 6, 7, 8, /*|*/ 9, 10 /* X | */ - /*X, X, X, | X X X | - *------------------------------------ */ + 1, 2, 3, + /*|*/ 4, 5, /* X | */ + 6, 7, 8, + /*|*/ 9, 10 /* X | */ + /*X, X, X, | X X X | + *------------------------------------ */ }; // manually tiling the above, using -1 as filler static constexpr int X = -1; - int data_tiled[] = { - /* tile 0, 0 */ 1, 2, 3, 6, 7, 8, X, X, X, - /* tile 0, 1 */ 4, 5, X, 9, 10, X, X, X, X, + int data_tiled[] = { + /* tile 0, 0 */ 1, 2, 3, 6, 7, 8, X, X, X, + /* tile 0, 1 */ 4, 5, X, 9, 10, X, X, X, X, }; //---------------------------------------- // Just use dynamic extents for the purposes of demonstration using extents_type = Kokkos::dextents; using tiled_mdspan = Kokkos::mdspan; - using tiled_layout_type = typename SimpleTileLayout2D::template mapping; - using row_major_mdspan = Kokkos::mdspan; + using tiled_layout_type = + typename SimpleTileLayout2D::template mapping; + using row_major_mdspan = + Kokkos::mdspan; //---------------------------------------- - auto tiled = tiled_mdspan(data_tiled, tiled_layout_type(extents_type(n_rows, n_cols), 3, 3)); + auto tiled = tiled_mdspan( + data_tiled, tiled_layout_type(extents_type(n_rows, n_cols), 3, 3)); auto row_major = row_major_mdspan(data_row_major, n_rows, n_cols); //---------------------------------------- // Check that we did things correctly @@ -186,27 +176,27 @@ int main() { for (int irow = 0; irow < n_rows; ++irow) { for (int icol = 0; icol < n_cols; ++icol) { #if MDSPAN_USE_BRACKET_OPERATOR - if(tiled[irow, icol] != row_major[irow, icol]) { - std::cout << "Mismatch for entry " << irow << ", " << icol << ":" << std::endl; - std::cout << " tiled(" << irow << ", " << icol << ") = " - << tiled[irow, icol] << std::endl; - std::cout << " row_major(" << irow << ", " << icol << ") = " - << row_major[irow, icol] << std::endl; + if (tiled[irow, icol] != row_major[irow, icol]) { + std::cout << "Mismatch for entry " << irow << ", " << icol << ":" + << std::endl; + std::cout << " tiled(" << irow << ", " << icol + << ") = " << tiled[irow, icol] << std::endl; + std::cout << " row_major(" << irow << ", " << icol + << ") = " << row_major[irow, icol] << std::endl; #else - if(tiled(irow, icol) != row_major(irow, icol)) { - std::cout << "Mismatch for entry " << irow << ", " << icol << ":" << std::endl; - std::cout << " tiled(" << irow << ", " << icol << ") = " - << tiled(irow, icol) << std::endl; - std::cout << " row_major(" << irow << ", " << icol << ") = " - << row_major(irow, icol) << std::endl; + if (tiled(irow, icol) != row_major(irow, icol)) { + std::cout << "Mismatch for entry " << irow << ", " << icol << ":" + << std::endl; + std::cout << " tiled(" << irow << ", " << icol + << ") = " << tiled(irow, icol) << std::endl; + std::cout << " row_major(" << irow << ", " << icol + << ") = " << row_major(irow, icol) << std::endl; #endif ++failures; - } - } } - if(failures == 0) { + if (failures == 0) { std::cout << "Success! SimpleTiledLayout2D works as expected." << std::endl; } } diff --git a/include/experimental/__p0009_bits/compressed_pair.hpp b/include/experimental/__p0009_bits/compressed_pair.hpp index 5a6e9451..56306abe 100644 --- a/include/experimental/__p0009_bits/compressed_pair.hpp +++ b/include/experimental/__p0009_bits/compressed_pair.hpp @@ -19,22 +19,27 @@ #include "trait_backports.hpp" #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# include "no_unique_address.hpp" +#include "no_unique_address.hpp" #endif namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace detail { -// For no unique address emulation, this is the case taken when neither are empty. -// For real `[[no_unique_address]]`, this case is always taken. -template struct impl_compressed_pair { +// For no unique address emulation, this is the case taken when neither are +// empty. For real `[[no_unique_address]]`, this case is always taken. +template +struct impl_compressed_pair { MDSPAN_IMPL_NO_UNIQUE_ADDRESS T1 m_t1_val{}; MDSPAN_IMPL_NO_UNIQUE_ADDRESS T2 m_t2_val{}; - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { return m_t1_val; } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { + return m_t1_val; + } MDSPAN_FORCE_INLINE_FUNCTION constexpr T1 const &first() const noexcept { return m_t1_val; } - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T2 &second() noexcept { return m_t2_val; } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T2 &second() noexcept { + return m_t2_val; + } MDSPAN_FORCE_INLINE_FUNCTION constexpr T2 const &second() const noexcept { return m_t2_val; } @@ -46,16 +51,17 @@ template struct impl_compressed_pair { MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr impl_compressed_pair(impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair const &) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair const &) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair &&) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~impl_compressed_pair() = default; template - MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, T2Like &&t2) - : m_t1_val((T1Like &&) t1), m_t2_val((T2Like &&) t2) {} + MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, + T2Like &&t2) + : m_t1_val((T1Like &&)t1), m_t2_val((T2Like &&)t2) {} }; #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) @@ -64,8 +70,8 @@ template struct impl_compressed_pair { template struct impl_compressed_pair< T1, T2, - std::enable_if_t> - : private T1 { + std::enable_if_t> : private T1 { T2 m_t2_val{}; MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { return *static_cast(this); @@ -73,7 +79,9 @@ struct impl_compressed_pair< MDSPAN_FORCE_INLINE_FUNCTION constexpr T1 const &first() const noexcept { return *static_cast(this); } - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T2 &second() noexcept { return m_t2_val; } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T2 &second() noexcept { + return m_t2_val; + } MDSPAN_FORCE_INLINE_FUNCTION constexpr T2 const &second() const noexcept { return m_t2_val; } @@ -85,26 +93,29 @@ struct impl_compressed_pair< MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr impl_compressed_pair(impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair const &) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair const &) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair &&) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~impl_compressed_pair() = default; template - MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, T2Like &&t2) - : T1((T1Like &&) t1), m_t2_val((T2Like &&) t2) {} + MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, + T2Like &&t2) + : T1((T1Like &&)t1), m_t2_val((T2Like &&)t2) {} }; // Second empty. template struct impl_compressed_pair< T1, T2, - std::enable_if_t> - : private T2 { + std::enable_if_t> : private T2 { T1 m_t1_val{}; - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { return m_t1_val; } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { + return m_t1_val; + } MDSPAN_FORCE_INLINE_FUNCTION constexpr T1 const &first() const noexcept { return m_t1_val; } @@ -122,29 +133,31 @@ struct impl_compressed_pair< MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr impl_compressed_pair(impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair const &) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair const &) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair &&) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~impl_compressed_pair() = default; template - MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, T2Like &&t2) - : T2((T2Like &&) t2), m_t1_val((T1Like &&) t1) {} + MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, + T2Like &&t2) + : T2((T2Like &&)t2), m_t1_val((T1Like &&)t1) {} }; // Both empty. template struct impl_compressed_pair< T1, T2, - std::enable_if_t> - // We need to use the no_unique_address_emulation wrapper here to avoid - // base class ambiguities. + std::enable_if_t> +// We need to use the no_unique_address_emulation wrapper here to avoid +// base class ambiguities. #ifdef MDSPAN_IMPL_COMPILER_MSVC -// MSVC doesn't allow you to access public static member functions of a type -// when you *happen* to privately inherit from that type. + // MSVC doesn't allow you to access public static member functions of a type + // when you *happen* to privately inherit from that type. : protected no_unique_address_emulation, protected no_unique_address_emulation #else @@ -152,7 +165,7 @@ struct impl_compressed_pair< private no_unique_address_emulation #endif { - using first_base_t = no_unique_address_emulation; + using first_base_t = no_unique_address_emulation; using second_base_t = no_unique_address_emulation; MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 T1 &first() noexcept { @@ -175,21 +188,20 @@ struct impl_compressed_pair< MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr impl_compressed_pair(impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair const &) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair const &) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair & - operator=(impl_compressed_pair &&) = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED impl_compressed_pair &operator=( + impl_compressed_pair &&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~impl_compressed_pair() = default; template - MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, T2Like &&t2) noexcept - : first_base_t(T1((T1Like &&) t1)), - second_base_t(T2((T2Like &&) t2)) - { } + MDSPAN_INLINE_FUNCTION constexpr impl_compressed_pair(T1Like &&t1, + T2Like &&t2) noexcept + : first_base_t(T1((T1Like &&)t1)), second_base_t(T2((T2Like &&)t2)) {} }; -#endif // !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) +#endif // !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -} // end namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace detail +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/config.hpp b/include/experimental/__p0009_bits/config.hpp index 73ea64e4..e9ded5d8 100644 --- a/include/experimental/__p0009_bits/config.hpp +++ b/include/experimental/__p0009_bits/config.hpp @@ -16,18 +16,18 @@ #pragma once #ifndef MDSPAN_IMPL_HAS_INCLUDE -# ifndef __has_include -# define MDSPAN_IMPL_HAS_INCLUDE(x) 0 -# else -# define MDSPAN_IMPL_HAS_INCLUDE(x) __has_include(x) -# endif +#ifndef __has_include +#define MDSPAN_IMPL_HAS_INCLUDE(x) 0 +#else +#define MDSPAN_IMPL_HAS_INCLUDE(x) __has_include(x) +#endif #endif #if MDSPAN_IMPL_HAS_INCLUDE() -# include +#include #else -# include -# include +#include +#include #endif #ifdef _MSVC_LANG @@ -51,255 +51,269 @@ #define MDSPAN_HAS_CXX_20 (MDSPAN_IMPL_CPLUSPLUS >= MDSPAN_CXX_STD_20) #define MDSPAN_HAS_CXX_23 (MDSPAN_IMPL_CPLUSPLUS >= MDSPAN_CXX_STD_23) -static_assert(MDSPAN_IMPL_CPLUSPLUS >= MDSPAN_CXX_STD_14, "mdspan requires C++14 or later."); +static_assert(MDSPAN_IMPL_CPLUSPLUS >= MDSPAN_CXX_STD_14, + "mdspan requires C++14 or later."); #ifndef MDSPAN_IMPL_COMPILER_CLANG -# if defined(__clang__) -# define MDSPAN_IMPL_COMPILER_CLANG __clang__ -# endif +#if defined(__clang__) +#define MDSPAN_IMPL_COMPILER_CLANG __clang__ +#endif #endif -#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && !defined(MDSPAN_IMPL_COMPILER_MSVC_CLANG) -# if defined(_MSC_VER) -# if !defined(MDSPAN_IMPL_COMPILER_CLANG) -# define MDSPAN_IMPL_COMPILER_MSVC _MSC_VER -# else -# define MDSPAN_IMPL_COMPILER_MSVC_CLANG _MSC_VER -# endif -# endif +#if !defined(MDSPAN_IMPL_COMPILER_MSVC) && \ + !defined(MDSPAN_IMPL_COMPILER_MSVC_CLANG) +#if defined(_MSC_VER) +#if !defined(MDSPAN_IMPL_COMPILER_CLANG) +#define MDSPAN_IMPL_COMPILER_MSVC _MSC_VER +#else +#define MDSPAN_IMPL_COMPILER_MSVC_CLANG _MSC_VER +#endif +#endif #endif #ifndef MDSPAN_IMPL_COMPILER_INTEL -# ifdef __INTEL_COMPILER -# define MDSPAN_IMPL_COMPILER_INTEL __INTEL_COMPILER -# endif +#ifdef __INTEL_COMPILER +#define MDSPAN_IMPL_COMPILER_INTEL __INTEL_COMPILER +#endif #endif #ifndef MDSPAN_IMPL_COMPILER_APPLECLANG -# ifdef __apple_build_version__ -# define MDSPAN_IMPL_COMPILER_APPLECLANG __apple_build_version__ -# endif +#ifdef __apple_build_version__ +#define MDSPAN_IMPL_COMPILER_APPLECLANG __apple_build_version__ +#endif #endif #ifndef MDSPAN_IMPL_HAS_CUDA -# if defined(__CUDACC__) -# define MDSPAN_IMPL_HAS_CUDA __CUDACC__ -# endif +#if defined(__CUDACC__) +#define MDSPAN_IMPL_HAS_CUDA __CUDACC__ +#endif #endif #ifndef MDSPAN_IMPL_HAS_HIP -# if defined(__HIPCC__) -# define MDSPAN_IMPL_HAS_HIP __HIPCC__ -# endif +#if defined(__HIPCC__) +#define MDSPAN_IMPL_HAS_HIP __HIPCC__ +#endif #endif #ifndef MDSPAN_IMPL_HAS_SYCL -# if defined(SYCL_LANGUAGE_VERSION) -# define MDSPAN_IMPL_HAS_SYCL SYCL_LANGUAGE_VERSION -# endif +#if defined(SYCL_LANGUAGE_VERSION) +#define MDSPAN_IMPL_HAS_SYCL SYCL_LANGUAGE_VERSION +#endif #endif #ifndef MDSPAN_IMPL_HAS_CPP_ATTRIBUTE -# ifndef __has_cpp_attribute -# define MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(x) 0 -# else -# define MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -# endif +#ifndef __has_cpp_attribute +#define MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(x) 0 +#else +#define MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#endif #endif #ifndef MDSPAN_IMPL_PRESERVE_STANDARD_LAYOUT // Preserve standard layout by default, but we're not removing the old version // that turns this off until we're sure this doesn't have an unreasonable cost // to the compiler or optimizer. -# define MDSPAN_IMPL_PRESERVE_STANDARD_LAYOUT 1 +#define MDSPAN_IMPL_PRESERVE_STANDARD_LAYOUT 1 #endif #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# if ((MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(no_unique_address) >= 201803L) && \ - (!defined(__NVCC__) || MDSPAN_HAS_CXX_20) && \ - (!defined(MDSPAN_IMPL_COMPILER_MSVC) || MDSPAN_HAS_CXX_20)) -# define MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 -# define MDSPAN_IMPL_NO_UNIQUE_ADDRESS [[no_unique_address]] -# else -# define MDSPAN_IMPL_NO_UNIQUE_ADDRESS -# endif +#if ((MDSPAN_IMPL_HAS_CPP_ATTRIBUTE(no_unique_address) >= 201803L) && \ + (!defined(__NVCC__) || MDSPAN_HAS_CXX_20) && \ + (!defined(MDSPAN_IMPL_COMPILER_MSVC) || MDSPAN_HAS_CXX_20)) +#define MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 +#define MDSPAN_IMPL_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else +#define MDSPAN_IMPL_NO_UNIQUE_ADDRESS +#endif #endif // NVCC older than 11.6 chokes on the no-unique-address-emulation // so just pretend to use it (to avoid the full blown EBO workaround // which NVCC also doesn't like ...), and leave the macro empty #ifndef MDSPAN_IMPL_NO_UNIQUE_ADDRESS -# if defined(__NVCC__) -# define MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 -# define MDSPAN_IMPL_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS -# endif -# define MDSPAN_IMPL_NO_UNIQUE_ADDRESS +#if defined(__NVCC__) +#define MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 +#define MDSPAN_IMPL_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS +#endif +#define MDSPAN_IMPL_NO_UNIQUE_ADDRESS #endif // AMDs HIP compiler seems to have issues with concepts // it pretends concepts exist, but doesn't ship #ifndef __HIPCC__ #ifndef MDSPAN_IMPL_USE_CONCEPTS -# if defined(__cpp_concepts) && __cpp_concepts >= 201507L -# define MDSPAN_IMPL_USE_CONCEPTS 1 -# endif +#if defined(__cpp_concepts) && __cpp_concepts >= 201507L +#define MDSPAN_IMPL_USE_CONCEPTS 1 +#endif #endif #endif #ifndef MDSPAN_IMPL_USE_FOLD_EXPRESSIONS -# if (defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603L) \ - || (!defined(__cpp_fold_expressions) && MDSPAN_HAS_CXX_17) -# define MDSPAN_IMPL_USE_FOLD_EXPRESSIONS 1 -# endif +#if (defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603L) || \ + (!defined(__cpp_fold_expressions) && MDSPAN_HAS_CXX_17) +#define MDSPAN_IMPL_USE_FOLD_EXPRESSIONS 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_INLINE_VARIABLES -# if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L \ - || (!defined(__cpp_inline_variables) && MDSPAN_HAS_CXX_17) -# define MDSPAN_IMPL_USE_INLINE_VARIABLES 1 -# endif +#if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L || \ + (!defined(__cpp_inline_variables) && MDSPAN_HAS_CXX_17) +#define MDSPAN_IMPL_USE_INLINE_VARIABLES 1 +#endif #endif #ifndef MDSPAN_IMPL_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS -# if (!(defined(__cpp_lib_type_trait_variable_templates) && __cpp_lib_type_trait_variable_templates >= 201510L) \ - || !MDSPAN_HAS_CXX_17) -# if !(defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_17) -# define MDSPAN_IMPL_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS 1 -# endif -# endif +#if (!(defined(__cpp_lib_type_trait_variable_templates) && \ + __cpp_lib_type_trait_variable_templates >= 201510L) || \ + !MDSPAN_HAS_CXX_17) +#if !(defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_17) +#define MDSPAN_IMPL_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS 1 +#endif +#endif #endif #ifndef MDSPAN_IMPL_USE_VARIABLE_TEMPLATES -# if (defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 && MDSPAN_HAS_CXX_17) \ - || (!defined(__cpp_variable_templates) && MDSPAN_HAS_CXX_17) -# define MDSPAN_IMPL_USE_VARIABLE_TEMPLATES 1 -# endif -#endif // MDSPAN_IMPL_USE_VARIABLE_TEMPLATES +#if (defined(__cpp_variable_templates) && \ + __cpp_variable_templates >= 201304 && MDSPAN_HAS_CXX_17) || \ + (!defined(__cpp_variable_templates) && MDSPAN_HAS_CXX_17) +#define MDSPAN_IMPL_USE_VARIABLE_TEMPLATES 1 +#endif +#endif // MDSPAN_IMPL_USE_VARIABLE_TEMPLATES #ifndef MDSPAN_IMPL_USE_CONSTEXPR_14 -# if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) \ - || (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_14) \ - && (!(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 1700)) -# define MDSPAN_IMPL_USE_CONSTEXPR_14 1 -# endif +#if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) || \ + (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_14) && \ + (!(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 1700)) +#define MDSPAN_IMPL_USE_CONSTEXPR_14 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_IF_CONSTEXPR_17 -# if (defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606) \ - || (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_17) -# define MDSPAN_IMPL_USE_IF_CONSTEXPR_17 1 -# endif +#if (defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606) || \ + (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_17) +#define MDSPAN_IMPL_USE_IF_CONSTEXPR_17 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 -# if defined(MDSPAN_IMPL_COMPILER_MSVC) -# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304) -# define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 -# endif -# endif +#if defined(MDSPAN_IMPL_COMPILER_MSVC) +#if (defined(__cpp_lib_integer_sequence) && \ + __cpp_lib_integer_sequence >= 201304) +#define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 +#endif +#endif #endif #ifndef MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 -# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304) \ - || (!defined(__cpp_lib_integer_sequence) && MDSPAN_HAS_CXX_14) \ - /* as far as I can tell, libc++ seems to think this is a C++11 feature... */ \ - || (defined(__GLIBCXX__) && __GLIBCXX__ > 20150422 && __GNUC__ < 5 && !defined(__INTEL_CXX11_MODE__)) - // several compilers lie about integer_sequence working properly unless the C++14 standard is used -# define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 -# elif defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 - // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14 making - // integer_sequence work -# define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 -# endif +#if (defined(__cpp_lib_integer_sequence) && \ + __cpp_lib_integer_sequence >= 201304) || \ + (!defined(__cpp_lib_integer_sequence) && \ + MDSPAN_HAS_CXX_14) /* as far as I can tell, libc++ seems to think this is \ + a C++11 feature... */ \ + || (defined(__GLIBCXX__) && __GLIBCXX__ > 20150422 && __GNUC__ < 5 && \ + !defined(__INTEL_CXX11_MODE__)) +// several compilers lie about integer_sequence working properly unless the +// C++14 standard is used +#define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 +#elif defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 +// appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to +// lie about C++14 making integer_sequence work +#define MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_RETURN_TYPE_DEDUCTION -# if (defined(__cpp_return_type_deduction) && __cpp_return_type_deduction >= 201304) \ - || (!defined(__cpp_return_type_deduction) && MDSPAN_HAS_CXX_14) -# define MDSPAN_IMPL_USE_RETURN_TYPE_DEDUCTION 1 -# endif +#if (defined(__cpp_return_type_deduction) && \ + __cpp_return_type_deduction >= 201304) || \ + (!defined(__cpp_return_type_deduction) && MDSPAN_HAS_CXX_14) +#define MDSPAN_IMPL_USE_RETURN_TYPE_DEDUCTION 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -# if (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10 >= 1170)) && \ - ((defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201703) || \ - (!defined(__cpp_deduction_guides) && MDSPAN_HAS_CXX_17)) -# define MDSPAN_IMPL_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 -# endif +#if (!defined(__NVCC__) || \ + (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10 >= 1170)) && \ + ((defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201703) || \ + (!defined(__cpp_deduction_guides) && MDSPAN_HAS_CXX_17)) +#define MDSPAN_IMPL_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 +#endif #endif #ifndef MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES -# if (defined(__cpp_lib_transformation_trait_aliases) && __cpp_lib_transformation_trait_aliases >= 201304) \ - || (!defined(__cpp_lib_transformation_trait_aliases) && MDSPAN_HAS_CXX_14) -# define MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES 1 -# elif defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 - // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14 -# define MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES 1 -# endif +#if (defined(__cpp_lib_transformation_trait_aliases) && \ + __cpp_lib_transformation_trait_aliases >= 201304) || \ + (!defined(__cpp_lib_transformation_trait_aliases) && MDSPAN_HAS_CXX_14) +#define MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES 1 +#elif defined(MDSPAN_IMPL_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 +// appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to +// lie about C++14 +#define MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES 1 +#endif #endif #ifndef MDSPAN_IMPL_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND -# ifdef __GNUC__ -# if __GNUC__ < 9 -# define MDSPAN_IMPL_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND 1 -# endif -# endif +#ifdef __GNUC__ +#if __GNUC__ < 9 +#define MDSPAN_IMPL_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND 1 +#endif +#endif #endif #ifndef MDSPAN_CONDITIONAL_EXPLICIT -# if MDSPAN_HAS_CXX_20 -# define MDSPAN_CONDITIONAL_EXPLICIT(COND) explicit(COND) -# else -# define MDSPAN_CONDITIONAL_EXPLICIT(COND) -# endif +#if MDSPAN_HAS_CXX_20 +#define MDSPAN_CONDITIONAL_EXPLICIT(COND) explicit(COND) +#else +#define MDSPAN_CONDITIONAL_EXPLICIT(COND) +#endif #endif #ifndef MDSPAN_USE_BRACKET_OPERATOR -# if defined(__cpp_multidimensional_subscript) +#if defined(__cpp_multidimensional_subscript) // The following if/else is necessary to workaround a clang issue -// relative to using a parameter pack inside a bracket operator in C++2b/C++23 mode -# if defined(MDSPAN_IMPL_COMPILER_CLANG) && \ - ((__clang_major__ < 17) || \ - (__clang_major__ == 17 && __clang_minor__ == 0 && \ - __clang_patchlevel__ == 0)) -# define MDSPAN_USE_BRACKET_OPERATOR 0 -# else -# define MDSPAN_USE_BRACKET_OPERATOR 1 -# endif -# else -# define MDSPAN_USE_BRACKET_OPERATOR 0 -# endif +// relative to using a parameter pack inside a bracket operator in C++2b/C++23 +// mode +#if defined(MDSPAN_IMPL_COMPILER_CLANG) && \ + ((__clang_major__ < 17) || \ + (__clang_major__ == 17 && __clang_minor__ == 0 && \ + __clang_patchlevel__ == 0)) +#define MDSPAN_USE_BRACKET_OPERATOR 0 +#else +#define MDSPAN_USE_BRACKET_OPERATOR 1 +#endif +#else +#define MDSPAN_USE_BRACKET_OPERATOR 0 +#endif #endif #ifndef MDSPAN_USE_PAREN_OPERATOR -# if !MDSPAN_USE_BRACKET_OPERATOR -# define MDSPAN_USE_PAREN_OPERATOR 1 -# else -# define MDSPAN_USE_PAREN_OPERATOR 0 -# endif +#if !MDSPAN_USE_BRACKET_OPERATOR +#define MDSPAN_USE_PAREN_OPERATOR 1 +#else +#define MDSPAN_USE_PAREN_OPERATOR 0 +#endif #endif #if MDSPAN_USE_BRACKET_OPERATOR -# define MDSPAN_IMPL_OP(mds,...) mds[__VA_ARGS__] +#define MDSPAN_IMPL_OP(mds, ...) mds[__VA_ARGS__] // Corentins demo compiler for subscript chokes on empty [] call, // though I believe the proposal supports it? #ifdef MDSPAN_NO_EMPTY_BRACKET_OPERATOR -# define MDSPAN_IMPL_OP0(mds) mds.accessor().access(mds.data_handle(),0) +#define MDSPAN_IMPL_OP0(mds) mds.accessor().access(mds.data_handle(), 0) #else -# define MDSPAN_IMPL_OP0(mds) mds[] -#endif -# define MDSPAN_IMPL_OP1(mds, a) mds[a] -# define MDSPAN_IMPL_OP2(mds, a, b) mds[a,b] -# define MDSPAN_IMPL_OP3(mds, a, b, c) mds[a,b,c] -# define MDSPAN_IMPL_OP4(mds, a, b, c, d) mds[a,b,c,d] -# define MDSPAN_IMPL_OP5(mds, a, b, c, d, e) mds[a,b,c,d,e] -# define MDSPAN_IMPL_OP6(mds, a, b, c, d, e, f) mds[a,b,c,d,e,f] +#define MDSPAN_IMPL_OP0(mds) mds[] +#endif +#define MDSPAN_IMPL_OP1(mds, a) mds[a] +#define MDSPAN_IMPL_OP2(mds, a, b) mds[a, b] +#define MDSPAN_IMPL_OP3(mds, a, b, c) mds[a, b, c] +#define MDSPAN_IMPL_OP4(mds, a, b, c, d) mds[a, b, c, d] +#define MDSPAN_IMPL_OP5(mds, a, b, c, d, e) mds[a, b, c, d, e] +#define MDSPAN_IMPL_OP6(mds, a, b, c, d, e, f) mds[a, b, c, d, e, f] #else -# define MDSPAN_IMPL_OP(mds,...) mds(__VA_ARGS__) -# define MDSPAN_IMPL_OP0(mds) mds() -# define MDSPAN_IMPL_OP1(mds, a) mds(a) -# define MDSPAN_IMPL_OP2(mds, a, b) mds(a,b) -# define MDSPAN_IMPL_OP3(mds, a, b, c) mds(a,b,c) -# define MDSPAN_IMPL_OP4(mds, a, b, c, d) mds(a,b,c,d) -# define MDSPAN_IMPL_OP5(mds, a, b, c, d, e) mds(a,b,c,d,e) -# define MDSPAN_IMPL_OP6(mds, a, b, c, d, e, f) mds(a,b,c,d,e,f) +#define MDSPAN_IMPL_OP(mds, ...) mds(__VA_ARGS__) +#define MDSPAN_IMPL_OP0(mds) mds() +#define MDSPAN_IMPL_OP1(mds, a) mds(a) +#define MDSPAN_IMPL_OP2(mds, a, b) mds(a, b) +#define MDSPAN_IMPL_OP3(mds, a, b, c) mds(a, b, c) +#define MDSPAN_IMPL_OP4(mds, a, b, c, d) mds(a, b, c, d) +#define MDSPAN_IMPL_OP5(mds, a, b, c, d, e) mds(a, b, c, d, e) +#define MDSPAN_IMPL_OP6(mds, a, b, c, d, e, f) mds(a, b, c, d, e, f) #endif diff --git a/include/experimental/__p0009_bits/default_accessor.hpp b/include/experimental/__p0009_bits/default_accessor.hpp index b858fba2..368f0315 100644 --- a/include/experimental/__p0009_bits/default_accessor.hpp +++ b/include/experimental/__p0009_bits/default_accessor.hpp @@ -17,32 +17,30 @@ #include "macros.hpp" -#include // size_t +#include // size_t namespace MDSPAN_IMPL_STANDARD_NAMESPACE { template struct default_accessor { - - using offset_policy = default_accessor; - using element_type = ElementType; - using reference = ElementType&; + using offset_policy = default_accessor; + using element_type = ElementType; + using reference = ElementType&; using data_handle_type = ElementType*; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr default_accessor() noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr default_accessor() noexcept = + default; - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, OtherElementType(*)[], element_type(*)[]) - ) - ) + MDSPAN_TEMPLATE_REQUIRES(class OtherElementType, + /* requires */ (MDSPAN_IMPL_TRAIT( + std::is_convertible, OtherElementType (*)[], + element_type (*)[]))) MDSPAN_INLINE_FUNCTION constexpr default_accessor(default_accessor) noexcept {} MDSPAN_INLINE_FUNCTION - constexpr data_handle_type - offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { return p + i; } @@ -50,7 +48,6 @@ struct default_accessor { constexpr reference access(data_handle_type p, size_t i) const noexcept { return p[i]; } - }; -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/dynamic_extent.hpp b/include/experimental/__p0009_bits/dynamic_extent.hpp index ffa4a6b1..fc0e93a7 100644 --- a/include/experimental/__p0009_bits/dynamic_extent.hpp +++ b/include/experimental/__p0009_bits/dynamic_extent.hpp @@ -28,8 +28,9 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { #if defined(__cpp_lib_span) using std::dynamic_extent; #else -MDSPAN_IMPL_INLINE_VARIABLE constexpr auto dynamic_extent = std::numeric_limits::max(); +MDSPAN_IMPL_INLINE_VARIABLE constexpr auto dynamic_extent = + std::numeric_limits::max(); #endif -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE //============================================================================================================== diff --git a/include/experimental/__p0009_bits/extents.hpp b/include/experimental/__p0009_bits/extents.hpp index ab10ba32..83866aad 100644 --- a/include/experimental/__p0009_bits/extents.hpp +++ b/include/experimental/__p0009_bits/extents.hpp @@ -33,8 +33,8 @@ namespace detail { // Function used to check compatibility of extents in converting constructor // can't be a private member function for some reason. template -MDSPAN_INLINE_FUNCTION -constexpr std::integral_constant impl_check_compatible_extents( +MDSPAN_INLINE_FUNCTION constexpr std::integral_constant +impl_check_compatible_extents( std::integral_constant, std::integer_sequence, std::integer_sequence) noexcept { @@ -43,16 +43,14 @@ constexpr std::integral_constant impl_check_compatible_extents( // This helper prevents ICE's on MSVC. template -struct impl_compare_extent_compatible : std::integral_constant -{}; +struct impl_compare_extent_compatible + : std::integral_constant {}; template -MDSPAN_INLINE_FUNCTION -constexpr std::integral_constant< - bool, MDSPAN_IMPL_FOLD_AND(impl_compare_extent_compatible::value)> +MDSPAN_INLINE_FUNCTION constexpr std::integral_constant< + bool, MDSPAN_IMPL_FOLD_AND( + impl_compare_extent_compatible::value)> impl_check_compatible_extents( std::integral_constant, std::integer_sequence, @@ -60,12 +58,12 @@ impl_check_compatible_extents( return {}; } -template -MDSPAN_INLINE_FUNCTION -constexpr bool are_valid_indices() { - return - MDSPAN_IMPL_FOLD_AND(std::is_convertible::value) && - MDSPAN_IMPL_FOLD_AND(std::is_nothrow_constructible::value); +template +MDSPAN_INLINE_FUNCTION constexpr bool are_valid_indices() { + return MDSPAN_IMPL_FOLD_AND( + std::is_convertible::value) && + MDSPAN_IMPL_FOLD_AND( + std::is_nothrow_constructible::value); } // ------------------------------------------------------------------ @@ -76,7 +74,8 @@ constexpr bool are_valid_indices() { // function and operator []. // Implementation of Static Array with recursive implementation of get. -template struct static_array_impl; +template +struct static_array_impl; template struct static_array_impl { @@ -87,7 +86,8 @@ struct static_array_impl { else return static_array_impl::get(r); } - template MDSPAN_INLINE_FUNCTION constexpr static T get() { + template + MDSPAN_INLINE_FUNCTION constexpr static T get() { #if MDSPAN_HAS_CXX_17 if constexpr (r == R) return FirstExt; @@ -104,32 +104,33 @@ template struct static_array_impl { MDSPAN_INLINE_FUNCTION constexpr static T get(size_t) { return FirstExt; } - template MDSPAN_INLINE_FUNCTION constexpr static T get() { + template + MDSPAN_INLINE_FUNCTION constexpr static T get() { return FirstExt; } }; // Don't start recursion if size 0 -template struct static_array_impl<0, T> { +template +struct static_array_impl<0, T> { MDSPAN_INLINE_FUNCTION constexpr static T get(size_t) { return T(); } - template MDSPAN_INLINE_FUNCTION constexpr static T get() { + template + MDSPAN_INLINE_FUNCTION constexpr static T get() { return T(); } }; // Static array, provides get(), get(r) and operator[r] -template struct static_array: - public static_array_impl<0, T, Values...> { - -public: +template +struct static_array : public static_array_impl<0, T, Values...> { + public: using value_type = T; MDSPAN_INLINE_FUNCTION constexpr static size_t size() { return sizeof...(Values); } }; - // ------------------------------------------------------------------ // ------------ index_sequence_scan --------------------------------- // ------------------------------------------------------------------ @@ -138,7 +139,8 @@ template struct static_array: // and get() which return the sum of the first r-1 values. // Recursive implementation for get -template struct index_sequence_scan_impl; +template +struct index_sequence_scan_impl; template struct index_sequence_scan_impl { @@ -153,7 +155,7 @@ struct index_sequence_scan_impl { template struct index_sequence_scan_impl { -#if defined(__NVCC__) || defined(__NVCOMPILER) || \ +#if defined(__NVCC__) || defined(__NVCOMPILER) || \ defined(MDSPAN_IMPL_COMPILER_INTEL) // NVCC warns about pointless comparison with 0 for R==0 and r being const // evaluatable and also 0. @@ -166,7 +168,8 @@ struct index_sequence_scan_impl { constexpr static size_t get(size_t r) { return R > r ? FirstVal : 0; } #endif }; -template <> struct index_sequence_scan_impl<0> { +template <> +struct index_sequence_scan_impl<0> { MDSPAN_INLINE_FUNCTION constexpr static size_t get(size_t) { return 0; } }; @@ -180,7 +183,8 @@ template <> struct index_sequence_scan_impl<0> { // This is needed to make the maybe_static_array be truly empty, for // all static values. -template struct possibly_empty_array { +template +struct possibly_empty_array { T vals[N]{}; MDSPAN_INLINE_FUNCTION constexpr T &operator[](size_t r) { return vals[r]; } @@ -188,7 +192,8 @@ template struct possibly_empty_array { constexpr const T &operator[](size_t r) const { return vals[r]; } }; -template struct possibly_empty_array { +template +struct possibly_empty_array { MDSPAN_INLINE_FUNCTION constexpr T operator[](size_t) { return T(); } MDSPAN_INLINE_FUNCTION @@ -205,13 +210,14 @@ template struct possibly_empty_array { // The position of a dynamic value is indicated through a tag value. template struct maybe_static_array { + static_assert(std::is_convertible::value, + "maybe_static_array: TStatic must be convertible to TDynamic"); + static_assert(std::is_convertible::value, + "maybe_static_array: TDynamic must be convertible to TStatic"); - static_assert(std::is_convertible::value, "maybe_static_array: TStatic must be convertible to TDynamic"); - static_assert(std::is_convertible::value, "maybe_static_array: TDynamic must be convertible to TStatic"); - -private: + private: // Static values member - using static_vals_t = static_array; + using static_vals_t = static_array; constexpr static size_t m_size = sizeof...(Values); constexpr static size_t m_size_dynamic = MDSPAN_IMPL_FOLD_PLUS_RIGHT((Values == dyn_tag), 0); @@ -221,11 +227,12 @@ struct maybe_static_array { m_dyn_vals; // static mapping of indices to the position in the dynamic values array - using dyn_map_t = index_sequence_scan_impl<0, static_cast(Values == dyn_tag)...>; -public: + using dyn_map_t = + index_sequence_scan_impl<0, static_cast(Values == dyn_tag)...>; + public: // two types for static and dynamic values - using value_type = TDynamic; + using value_type = TDynamic; using static_value_type = TStatic; // tag value indicating dynamic value constexpr static static_value_type tag_value = dyn_tag; @@ -249,7 +256,6 @@ struct maybe_static_array { constexpr maybe_static_array(DynVals... vals) : m_dyn_vals{static_cast(vals)...} {} - MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, /* requires */ (N == m_size_dynamic && N > 0)) MDSPAN_INLINE_FUNCTION @@ -284,8 +290,7 @@ struct maybe_static_array { m_size_dynamic && m_size_dynamic > 0)) MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(DynVals... vals) - : m_dyn_vals{} { + constexpr maybe_static_array(DynVals... vals) : m_dyn_vals{} { static_assert((sizeof...(DynVals) == m_size), "Invalid number of values."); TDynamic values[m_size]{static_cast(vals)...}; for (size_t r = 0; r < m_size; r++) { @@ -354,7 +359,9 @@ struct maybe_static_array { // access functions MDSPAN_INLINE_FUNCTION - constexpr static TStatic static_value(size_t r) { return static_vals_t::get(r); } + constexpr static TStatic static_value(size_t r) { + return static_vals_t::get(r); + } MDSPAN_INLINE_FUNCTION constexpr TDynamic value(size_t r) const { @@ -363,12 +370,11 @@ struct maybe_static_array { // FIXME: workaround for nvhpc OpenACC compiler bug TStatic dyn_tag_copy = dyn_tag; return static_val == dyn_tag_copy ? m_dyn_vals[dyn_map_t::get(r)] - : static_cast(static_val); + : static_cast(static_val); } MDSPAN_INLINE_FUNCTION constexpr TDynamic operator[](size_t r) const { return value(r); } - // observers MDSPAN_INLINE_FUNCTION constexpr static size_t size() { return m_size; } @@ -376,8 +382,8 @@ struct maybe_static_array { constexpr static size_t size_dynamic() { return m_size_dynamic; } }; -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace detail +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE namespace MDSPAN_IMPL_STANDARD_NAMESPACE { @@ -389,16 +395,21 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { // Used by mdspan, mdarray and layout mappings. // See ISO C++ standard [mdspan.extents] -template class extents { -public: +template +class extents { + public: // typedefs for integral types used using index_type = IndexType; - using size_type = std::make_unsigned_t; - using rank_type = size_t; + using size_type = std::make_unsigned_t; + using rank_type = size_t; + + static_assert( + std::is_integral::value && + !std::is_same::value, + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::extents::index_type must be a signed or unsigned integer type"); - static_assert(std::is_integral::value && !std::is_same::value, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents::index_type must be a signed or unsigned integer type"); -private: + private: constexpr static rank_type m_rank = sizeof...(Extents); constexpr static rank_type m_rank_dynamic = MDSPAN_IMPL_FOLD_PLUS_RIGHT((Extents == dynamic_extent), /* + ... + */ 0); @@ -408,7 +419,7 @@ template class extents { detail::maybe_static_array; MDSPAN_IMPL_NO_UNIQUE_ADDRESS vals_t m_vals; -public: + public: // [mdspan.extents.obs], observers of multidimensional index space MDSPAN_INLINE_FUNCTION constexpr static rank_type rank() noexcept { return m_rank; } @@ -416,7 +427,9 @@ template class extents { constexpr static rank_type rank_dynamic() noexcept { return m_rank_dynamic; } MDSPAN_INLINE_FUNCTION - constexpr index_type extent(rank_type r) const noexcept { return m_vals.value(r); } + constexpr index_type extent(rank_type r) const noexcept { + return m_vals.value(r); + } MDSPAN_INLINE_FUNCTION constexpr static size_t static_extent(rank_type r) noexcept { return vals_t::static_value(r); @@ -430,13 +443,14 @@ template class extents { // Precondition check is deferred to maybe_static_array constructor MDSPAN_TEMPLATE_REQUIRES( class... OtherIndexTypes, - /* requires */ ( - MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_convertible, OtherIndexTypes, - index_type) /* && ... */) && - MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, - OtherIndexTypes) /* && ... */) && - (sizeof...(OtherIndexTypes) == m_rank || - sizeof...(OtherIndexTypes) == m_rank_dynamic))) + /* requires */ (MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT( + std::is_convertible, OtherIndexTypes, + index_type) /* && ... */) && + MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT( + std::is_nothrow_constructible, index_type, + OtherIndexTypes) /* && ... */) && + (sizeof...(OtherIndexTypes) == m_rank || + sizeof...(OtherIndexTypes) == m_rank_dynamic))) MDSPAN_INLINE_FUNCTION constexpr explicit extents(OtherIndexTypes... dynvals) noexcept : m_vals(static_cast(dynvals)...) {} @@ -444,11 +458,11 @@ template class extents { MDSPAN_TEMPLATE_REQUIRES( class OtherIndexType, size_t N, /* requires */ - ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherIndexType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, - const OtherIndexType&) && - (N == m_rank || N == m_rank_dynamic))) + (MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherIndexType &, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, + const OtherIndexType &) && + (N == m_rank || N == m_rank_dynamic))) MDSPAN_INLINE_FUNCTION MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic) constexpr extents(const std::array &exts) noexcept @@ -458,8 +472,10 @@ template class extents { MDSPAN_TEMPLATE_REQUIRES( class OtherIndexType, size_t N, /* requires */ - (MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherIndexType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const OtherIndexType&) && + (MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherIndexType &, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, + const OtherIndexType &) && (N == m_rank || N == m_rank_dynamic))) MDSPAN_INLINE_FUNCTION MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic) @@ -467,7 +483,7 @@ template class extents { : m_vals(std::move(exts)) {} #endif -private: + private: // Function to construct extents storage from other extents. // With C++ 17 the first two variants could be collapsed using if constexpr // in which case you don't need all the requires clauses. @@ -476,11 +492,10 @@ template class extents { size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, /* requires */ ((R < m_rank) && (static_extent(R) == dynamic_extent))) MDSPAN_INLINE_FUNCTION - constexpr - vals_t impl_construct_vals_from_extents(std::integral_constant, - std::integral_constant, - const OtherExtents &exts, - DynamicValues... dynamic_values) noexcept { + constexpr vals_t impl_construct_vals_from_extents( + std::integral_constant, + std::integral_constant, const OtherExtents &exts, + DynamicValues... dynamic_values) noexcept { return impl_construct_vals_from_extents( std::integral_constant(), std::integral_constant(), exts, dynamic_values..., @@ -491,11 +506,10 @@ template class extents { size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, /* requires */ ((R < m_rank) && (static_extent(R) != dynamic_extent))) MDSPAN_INLINE_FUNCTION - constexpr - vals_t impl_construct_vals_from_extents(std::integral_constant, - std::integral_constant, - const OtherExtents &exts, - DynamicValues... dynamic_values) noexcept { + constexpr vals_t impl_construct_vals_from_extents( + std::integral_constant, + std::integral_constant, const OtherExtents &exts, + DynamicValues... dynamic_values) noexcept { return impl_construct_vals_from_extents( std::integral_constant(), std::integral_constant(), exts, dynamic_values...); @@ -505,57 +519,57 @@ template class extents { size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, /* requires */ ((R == m_rank) && (DynCount == m_rank_dynamic))) MDSPAN_INLINE_FUNCTION - constexpr - vals_t impl_construct_vals_from_extents(std::integral_constant, - std::integral_constant, - const OtherExtents &, - DynamicValues... dynamic_values) noexcept { + constexpr vals_t impl_construct_vals_from_extents( + std::integral_constant, + std::integral_constant, const OtherExtents &, + DynamicValues... dynamic_values) noexcept { return vals_t{static_cast(dynamic_values)...}; } -public: - + public: // Converting constructor from other extents specializations - MDSPAN_TEMPLATE_REQUIRES( - class OtherIndexType, size_t... OtherExtents, - /* requires */ - ( - /* multi-stage check to protect from invalid pack expansion when sizes - don't match? */ - decltype(detail::impl_check_compatible_extents( - // using: sizeof...(Extents) == sizeof...(OtherExtents) as the second argument fails with MSVC+NVCC with some obscure expansion error - // MSVC: 19.38.33133 NVCC: 12.0 - std::integral_constant::rank() == extents::rank()>{}, + MDSPAN_TEMPLATE_REQUIRES( + class OtherIndexType, size_t... OtherExtents, + /* requires */ + ( + /* multi-stage check to protect from invalid pack expansion when sizes + don't match? */ + decltype(detail::impl_check_compatible_extents( + // using: sizeof...(Extents) == sizeof...(OtherExtents) as the + // second argument fails with MSVC+NVCC with some obscure + // expansion error MSVC: 19.38.33133 NVCC: 12.0 + std::integral_constant< + bool, extents::rank() == + extents::rank()>{}, std::integer_sequence{}, - std::integer_sequence{}))::value - ) - ) + std::integer_sequence{}))::value)) MDSPAN_INLINE_FUNCTION MDSPAN_CONDITIONAL_EXPLICIT((((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ...) || (std::numeric_limits::max() < std::numeric_limits::max())) - constexpr extents(const extents &other) noexcept + constexpr extents( + const extents &other) noexcept : m_vals(impl_construct_vals_from_extents( std::integral_constant(), std::integral_constant(), other)) {} // Comparison operator template - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const extents &lhs, - const extents &rhs) noexcept { - return - rank() == extents::rank() && - detail::rankwise_equal(detail::with_rank{}, rhs, lhs, detail::extent); + MDSPAN_INLINE_FUNCTION friend constexpr bool operator==( + const extents &lhs, + const extents &rhs) noexcept { + return rank() == extents::rank() && + detail::rankwise_equal(detail::with_rank{}, rhs, lhs, + detail::extent); } #if !(MDSPAN_HAS_CXX_20) template - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(extents const &lhs, - extents const &rhs) noexcept { + MDSPAN_INLINE_FUNCTION friend constexpr bool operator!=( + extents const &lhs, + extents const &rhs) noexcept { return !(lhs == rhs); } #endif @@ -570,23 +584,24 @@ struct impl_make_dextents; template struct impl_make_dextents< - IndexType, Rank, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> -{ + IndexType, Rank, + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> { using type = typename impl_make_dextents< IndexType, Rank - 1, - ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents>::type; + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents< + IndexType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent, + ExtentsPack...>>::type; }; template struct impl_make_dextents< - IndexType, 0, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> -{ - using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents; + IndexType, 0, + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> { + using type = + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents; }; -} // end namespace detail +} // end namespace detail // [mdspan.extents.dextents], alias template template @@ -596,17 +611,19 @@ using dextents = typename detail::impl_make_dextents::type; #if defined(MDSPAN_IMPL_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) template extents(IndexTypes...) - -> extents; + -> extents; #endif // Helper type traits for identifying a class as extents. namespace detail { -template struct impl_is_extents : ::std::false_type {}; +template +struct impl_is_extents : ::std::false_type {}; template -struct impl_is_extents<::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> +struct impl_is_extents< + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents> : ::std::true_type {}; template @@ -615,37 +632,28 @@ inline #else static #endif -constexpr bool impl_is_extents_v = impl_is_extents::value; - -template -MDSPAN_INLINE_FUNCTION -constexpr void -check_lower_bound(InputIndexType user_index, - ExtentsIndexType /* current_extent */, - std::true_type /* is_signed */) -{ - (void) user_index; // prevent unused variable warning + constexpr bool impl_is_extents_v = impl_is_extents::value; + +template +MDSPAN_INLINE_FUNCTION constexpr void check_lower_bound( + InputIndexType user_index, ExtentsIndexType /* current_extent */, + std::true_type /* is_signed */) { + (void)user_index; // prevent unused variable warning #ifdef MDSPAN_DEBUG assert(static_cast(user_index) >= 0); #endif } -template -MDSPAN_INLINE_FUNCTION -constexpr void -check_lower_bound(InputIndexType /* user_index */, - ExtentsIndexType /* current_extent */, - std::false_type /* is_signed */) -{} - -template -MDSPAN_INLINE_FUNCTION -constexpr void -check_upper_bound(InputIndexType user_index, - ExtentsIndexType current_extent) -{ - (void) user_index; // prevent unused variable warnings - (void) current_extent; +template +MDSPAN_INLINE_FUNCTION constexpr void check_lower_bound( + InputIndexType /* user_index */, ExtentsIndexType /* current_extent */, + std::false_type /* is_signed */) {} + +template +MDSPAN_INLINE_FUNCTION constexpr void check_upper_bound( + InputIndexType user_index, ExtentsIndexType current_extent) { + (void)user_index; // prevent unused variable warnings + (void)current_extent; #ifdef MDSPAN_DEBUG assert(static_cast(user_index) < current_extent); #endif @@ -654,43 +662,32 @@ check_upper_bound(InputIndexType user_index, // Returning true to use AND fold instead of comma // CPP14 mode doesn't like the use of void expressions // with the way the MDSPAN_IMPL_FOLD_AND is set up -template -MDSPAN_INLINE_FUNCTION -constexpr bool -check_one_index(InputIndex user_index, - ExtentsIndexType current_extent) -{ - check_lower_bound(user_index, current_extent, - std::integral_constant::value>{}); +template +MDSPAN_INLINE_FUNCTION constexpr bool check_one_index( + InputIndex user_index, ExtentsIndexType current_extent) { + check_lower_bound( + user_index, current_extent, + std::integral_constant::value>{}); check_upper_bound(user_index, current_extent); return true; } -template -MDSPAN_INLINE_FUNCTION -constexpr void -check_all_indices_helper(std::index_sequence, - const extents& exts, - Indices... indices) -{ +template +MDSPAN_INLINE_FUNCTION constexpr void check_all_indices_helper( + std::index_sequence, + const extents &exts, Indices... indices) { // Suppress warning about statement has no effect - (void) MDSPAN_IMPL_FOLD_AND( - (check_one_index(indices, exts.extent(RankIndices))) - ); + (void)MDSPAN_IMPL_FOLD_AND( + (check_one_index(indices, exts.extent(RankIndices)))); } -template -MDSPAN_INLINE_FUNCTION -constexpr void -check_all_indices(const extents& exts, - Indices... indices) -{ - check_all_indices_helper(std::make_index_sequence(), - exts, indices...); +template +MDSPAN_INLINE_FUNCTION constexpr void check_all_indices( + const extents &exts, Indices... indices) { + check_all_indices_helper(std::make_index_sequence(), exts, + indices...); } -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace detail +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/full_extent_t.hpp b/include/experimental/__p0009_bits/full_extent_t.hpp index a1e296ac..1f29fb83 100644 --- a/include/experimental/__p0009_bits/full_extent_t.hpp +++ b/include/experimental/__p0009_bits/full_extent_t.hpp @@ -19,8 +19,10 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -struct full_extent_t { explicit full_extent_t() = default; }; +struct full_extent_t { + explicit full_extent_t() = default; +}; -MDSPAN_IMPL_INLINE_VARIABLE constexpr auto full_extent = full_extent_t{ }; +MDSPAN_IMPL_INLINE_VARIABLE constexpr auto full_extent = full_extent_t{}; -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/layout_left.hpp b/include/experimental/__p0009_bits/layout_left.hpp index e1198008..a6ec3ff0 100644 --- a/include/experimental/__p0009_bits/layout_left.hpp +++ b/include/experimental/__p0009_bits/layout_left.hpp @@ -31,239 +31,248 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { template class layout_left::mapping { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left; - private: - - static_assert(detail::impl_is_extents_v, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_left::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - template - friend class mapping; - - // i0+(i1 + E(1)*(i2 + E(2)*i3)) - template - struct rank_count {}; - - template - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset( - rank_count, const I& i, Indices... idx) const { - return compute_offset(rank_count(), idx...) * - m_extents.extent(r) + i; - } - - template - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset( - rank_count, const I& i) const { - return i; - } - - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset(rank_count<0,0>) const { return 0; } - - public: - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; - - MDSPAN_IMPL_HOST_DEVICE - constexpr mapping(extents_type const& exts) noexcept - :m_extents(exts) - { } - - MDSPAN_TEMPLATE_REQUIRES( + public: + using extents_type = Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_left; + + private: + static_assert(detail::impl_is_extents_v, + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::layout_left::mapping must be instantiated with a " + "specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::extents."); + + template + friend class mapping; + + // i0+(i1 + E(1)*(i2 + E(2)*i3)) + template + struct rank_count {}; + + template + MDSPAN_IMPL_HOST_DEVICE constexpr index_type compute_offset( + rank_count, const I& i, Indices... idx) const { + return compute_offset(rank_count(), idx...) * + m_extents.extent(r) + + i; + } + + template + MDSPAN_IMPL_HOST_DEVICE constexpr index_type compute_offset( + rank_count, + const I& i) const { + return i; + } + + MDSPAN_IMPL_HOST_DEVICE + constexpr index_type compute_offset(rank_count<0, 0>) const { return 0; } + + public: + //-------------------------------------------------------------------------------- + + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = + default; + + MDSPAN_IMPL_HOST_DEVICE + constexpr mapping(extents_type const& exts) noexcept : m_extents(exts) {} + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - MDSPAN_TEMPLATE_REQUIRES( + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + } + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) && - (extents_type::rank() <= 1) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(layout_right::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents) && + (extents_type::rank() <= 1))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(layout_right::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + } #if MDSPAN_HAS_CXX_17 - /** - * Converting constructor from `layout_left_padded::mapping`. - * - * This overload participates in overload resolution only if Mapping is a layout_left_padded mapping and - * extents_type is constructible from Mapping::extents_type. - * - * \note There is currently a difference from p2642r2, where this function is specified as taking - * `layout_left_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible. - */ - MDSPAN_TEMPLATE_REQUIRES( + /** + * Converting constructor from `layout_left_padded::mapping`. + * + * This overload participates in overload resolution only if Mapping is a + * layout_left_padded mapping and extents_type is constructible from + * Mapping::extents_type. + * + * \note There is currently a difference from p2642r2, where this function is + * specified as taking `layout_left_padded< padding_value >::mapping< + * Extents>`. However, this makes `padding_value` non-deducible. + */ + MDSPAN_TEMPLATE_REQUIRES( class Mapping, /* requires */ ( - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_left_padded_mapping::value - && std::is_constructible_v - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v)) - MDSPAN_INLINE_FUNCTION constexpr - mapping(const Mapping& other) noexcept - : m_extents(other.extents()) - { - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_mandates< - extents_type, Mapping>(detail::with_rank{}); - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_preconditions< - extents_type>(detail::with_rank{}, other); - } + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_left_padded_mapping< + Mapping>::value&& std:: + is_constructible_v)) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible_v)) + MDSPAN_INLINE_FUNCTION constexpr mapping(const Mapping& other) noexcept + : m_extents(other.extents()) { + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: + check_padded_layout_converting_constructor_mandates( + detail::with_rank{}); + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: + check_padded_layout_converting_constructor_preconditions( + detail::with_rank{}, other); + } #endif - MDSPAN_TEMPLATE_REQUIRES( + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(layout_stride::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - detail::validate_strides(detail::with_rank{}, layout_left{}, m_extents, other); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION - constexpr const extents_type& extents() const noexcept { - return m_extents; - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type value = 1; - for(rank_type r=0; r 0)) + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(layout_stride::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + detail::validate_strides(detail::with_rank{}, + layout_left{}, m_extents, other); + } + + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& + operator=(mapping const&) noexcept = default; + + MDSPAN_INLINE_FUNCTION + constexpr const extents_type& extents() const noexcept { return m_extents; } + + MDSPAN_INLINE_FUNCTION + constexpr index_type required_span_size() const noexcept { + index_type value = 1; + for (rank_type r = 0; r < extents_type::rank(); r++) + value *= m_extents.extent(r); + return value; + } + + //-------------------------------------------------------------------------------- + + MDSPAN_TEMPLATE_REQUIRES( class... Indices, - /* requires */ ( - (sizeof...(Indices) == extents_type::rank()) && - (detail::are_valid_indices()) - ) - ) - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) - detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return compute_offset(rank_count<0, extents_type::rank()>(), static_cast(idxs)...); - } - - - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type i) const noexcept + /* requires */ ((sizeof...(Indices) == extents_type::rank()) && + (detail::are_valid_indices()))) + MDSPAN_IMPL_HOST_DEVICE + constexpr index_type operator()(Indices... idxs) const noexcept { +#if !defined(NDEBUG) + detail::check_all_indices(this->extents(), idxs...); +#endif // ! NDEBUG + return compute_offset(rank_count<0, extents_type::rank()>(), + static_cast(idxs)...); + } + + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { + return true; + } + + MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { + return true; + } + + MDSPAN_INLINE_FUNCTION + constexpr index_type stride(rank_type i) const noexcept #if MDSPAN_HAS_CXX_20 - requires ( Extents::rank() > 0 ) + requires(Extents::rank() > 0) #endif - { - index_type value = 1; - for(rank_type r=0; r const& rhs) noexcept { - return lhs.extents() == rhs.extents(); - } - - // In C++ 20 the not equal exists if equal is found + { + index_type value = 1; + for (rank_type r = 0; r < i; r++) value *= m_extents.extent(r); + return value; + } + + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ (Extents::rank() == + OtherExtents::rank())) + MDSPAN_INLINE_FUNCTION + friend constexpr bool operator==(mapping const& lhs, + mapping const& rhs) noexcept { + return lhs.extents() == rhs.extents(); + } + + // In C++ 20 the not equal exists if equal is found #if !(MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping const& rhs) noexcept { - return lhs.extents() != rhs.extents(); - } + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ (Extents::rank() == + OtherExtents::rank())) + MDSPAN_INLINE_FUNCTION + friend constexpr bool operator!=(mapping const& lhs, + mapping const& rhs) noexcept { + return lhs.extents() != rhs.extents(); + } #endif - // Not really public, but currently needed to implement fully constexpr useable submdspan: - template - MDSPAN_INLINE_FUNCTION - constexpr index_type impl_get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents,std::integer_sequence) const { - return MDSPAN_IMPL_FOLD_TIMES_RIGHT((Idx():1),1); - } - template - MDSPAN_INLINE_FUNCTION - constexpr index_type impl_stide() const noexcept { - return impl_get_stride(m_extents, std::make_index_sequence()); - } - -private: - MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template - MDSPAN_INLINE_FUNCTION - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } + // Not really public, but currently needed to implement fully constexpr + // useable submdspan: + template + MDSPAN_INLINE_FUNCTION constexpr index_type impl_get_stride( + MDSPAN_IMPL_STANDARD_NAMESPACE::extents, + std::integer_sequence) const { + return MDSPAN_IMPL_FOLD_TIMES_RIGHT( + (Idx < N ? m_extents.template extent() : 1), 1); + } + template + MDSPAN_INLINE_FUNCTION constexpr index_type impl_stide() const noexcept { + return impl_get_stride(m_extents, + std::make_index_sequence()); + } + + private: + MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; + + // [mdspan.submdspan.mapping], submdspan mapping specialization + template + MDSPAN_INLINE_FUNCTION constexpr auto submdspan_mapping_impl( + SliceSpecifiers... slices) const; + + template + MDSPAN_INLINE_FUNCTION friend constexpr auto submdspan_mapping( + const mapping& src, SliceSpecifiers... slices) { + return src.submdspan_mapping_impl(slices...); + } }; - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/layout_right.hpp b/include/experimental/__p0009_bits/layout_right.hpp index d95c180e..1cba6556 100644 --- a/include/experimental/__p0009_bits/layout_right.hpp +++ b/include/experimental/__p0009_bits/layout_right.hpp @@ -29,237 +29,255 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { //============================================================================== template class layout_right::mapping { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right; - private: - - static_assert(detail::impl_is_extents_v, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_right::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - template - friend class mapping; - - // i0+(i1 + E(1)*(i2 + E(2)*i3)) - template - struct rank_count {}; - - template - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset( - index_type offset, rank_count, const I& i, Indices... idx) const { - return compute_offset(offset * m_extents.extent(r) + i,rank_count(), idx...); - } - - template - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset( - rank_count<0,extents_type::rank()>, const I& i, Indices... idx) const { - return compute_offset(i,rank_count<1,extents_type::rank()>(),idx...); - } - - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset(size_t offset, rank_count) const { - return static_cast(offset); - } - - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type compute_offset(rank_count<0,0>) const { return 0; } - - public: - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; - - MDSPAN_IMPL_HOST_DEVICE - constexpr mapping(extents_type const& exts) noexcept - :m_extents(exts) - { } - - MDSPAN_TEMPLATE_REQUIRES( + public: + using extents_type = Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_right; + + private: + static_assert(detail::impl_is_extents_v, + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::layout_right::mapping must be instantiated with a " + "specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::extents."); + + template + friend class mapping; + + // i0+(i1 + E(1)*(i2 + E(2)*i3)) + template + struct rank_count {}; + + template + MDSPAN_IMPL_HOST_DEVICE constexpr index_type compute_offset( + index_type offset, rank_count, const I& i, + Indices... idx) const { + return compute_offset(offset * m_extents.extent(r) + i, + rank_count(), idx...); + } + + template + MDSPAN_IMPL_HOST_DEVICE constexpr index_type compute_offset( + rank_count<0, extents_type::rank()>, const I& i, Indices... idx) const { + return compute_offset(i, rank_count<1, extents_type::rank()>(), idx...); + } + + MDSPAN_IMPL_HOST_DEVICE + constexpr index_type compute_offset( + size_t offset, + rank_count) const { + return static_cast(offset); + } + + MDSPAN_IMPL_HOST_DEVICE + constexpr index_type compute_offset(rank_count<0, 0>) const { return 0; } + + public: + //-------------------------------------------------------------------------------- + + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = + default; + + MDSPAN_IMPL_HOST_DEVICE + constexpr mapping(extents_type const& exts) noexcept : m_extents(exts) {} + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + } - MDSPAN_TEMPLATE_REQUIRES( + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) && - (extents_type::rank() <= 1) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(layout_left::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - /** - * Converting constructor from `layout_right_padded::mapping`. - * - * This overload participates in overload resolution only if Mapping is a layout_right_padded mapping and - * extents_type is constructible from Mapping::extents_type. - * - * \note There is currently a difference from p2642r2, where this function is specified as taking - * `layout_right_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible. + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents) && + (extents_type::rank() <= 1))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(layout_left::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type */ + } + + /** + * Converting constructor from `layout_right_padded::mapping`. + * + * This overload participates in overload resolution only if Mapping is a + * layout_right_padded mapping and extents_type is constructible from + * Mapping::extents_type. + * + * \note There is currently a difference from p2642r2, where this function is + * specified as taking `layout_right_padded< padding_value >::mapping< + * Extents>`. However, this makes `padding_value` non-deducible. + */ #if MDSPAN_HAS_CXX_17 - MDSPAN_TEMPLATE_REQUIRES( - class Mapping, - /* requires */ ( - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_right_padded_mapping::value - && std::is_constructible_v)) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v)) - MDSPAN_INLINE_FUNCTION constexpr - mapping(const Mapping &other) noexcept - : m_extents(other.extents()) - { - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_mandates< - extents_type, Mapping>(detail::with_rank{}); - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_preconditions< - extents_type>(detail::with_rank{}, other); - } + MDSPAN_TEMPLATE_REQUIRES( + class Mapping, + /* requires */ ( + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: + is_layout_right_padded_mapping::value&& + std::is_constructible_v)) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible_v)) + MDSPAN_INLINE_FUNCTION constexpr mapping(const Mapping& other) noexcept + : m_extents(other.extents()) { + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: + check_padded_layout_converting_constructor_mandates( + detail::with_rank{}); + MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: + check_padded_layout_converting_constructor_preconditions( + detail::with_rank{}, other); + } #endif - MDSPAN_TEMPLATE_REQUIRES( + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(layout_stride::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - detail::validate_strides(detail::with_rank{}, layout_right{}, m_extents, other); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION - constexpr const extents_type& extents() const noexcept { - return m_extents; - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type value = 1; - for(rank_type r=0; r != extents_type::rank(); ++r) value*=m_extents.extent(r); - return value; - } - - //-------------------------------------------------------------------------------- - - MDSPAN_TEMPLATE_REQUIRES( - class ... Indices, - /* requires */ ( - (sizeof...(Indices) == extents_type::rank()) && - (detail::are_valid_indices()) - ) - ) - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) - detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return compute_offset(rank_count<0, extents_type::rank()>(), static_cast(idxs)...); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type i) const noexcept + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(layout_stride::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + detail::validate_strides(detail::with_rank{}, + layout_right{}, m_extents, other); + } + + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& + operator=(mapping const&) noexcept = default; + + MDSPAN_INLINE_FUNCTION + constexpr const extents_type& extents() const noexcept { return m_extents; } + + MDSPAN_INLINE_FUNCTION + constexpr index_type required_span_size() const noexcept { + index_type value = 1; + for (rank_type r = 0; r != extents_type::rank(); ++r) + value *= m_extents.extent(r); + return value; + } + + //-------------------------------------------------------------------------------- + + MDSPAN_TEMPLATE_REQUIRES( + class... Indices, + /* requires */ ((sizeof...(Indices) == extents_type::rank()) && + (detail::are_valid_indices()))) + MDSPAN_IMPL_HOST_DEVICE + constexpr index_type operator()(Indices... idxs) const noexcept { +#if !defined(NDEBUG) + detail::check_all_indices(this->extents(), idxs...); +#endif // ! NDEBUG + return compute_offset(rank_count<0, extents_type::rank()>(), + static_cast(idxs)...); + } + + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { + return true; + } + + MDSPAN_INLINE_FUNCTION + constexpr index_type stride(rank_type i) const noexcept #if MDSPAN_HAS_CXX_20 - requires ( Extents::rank() > 0 ) + requires(Extents::rank() > 0) #endif - { - index_type value = 1; - for(rank_type r=extents_type::rank()-1; r>i; r--) value*=m_extents.extent(r); - return value; - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping const& rhs) noexcept { - return lhs.extents() == rhs.extents(); - } - - // In C++ 20 the not equal exists if equal is found + { + index_type value = 1; + for (rank_type r = extents_type::rank() - 1; r > i; r--) + value *= m_extents.extent(r); + return value; + } + + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ (Extents::rank() == + OtherExtents::rank())) + MDSPAN_INLINE_FUNCTION + friend constexpr bool operator==(mapping const& lhs, + mapping const& rhs) noexcept { + return lhs.extents() == rhs.extents(); + } + + // In C++ 20 the not equal exists if equal is found #if !(MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ (Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping const& rhs) noexcept { - return lhs.extents() != rhs.extents(); - } + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ (Extents::rank() == + OtherExtents::rank())) + MDSPAN_INLINE_FUNCTION + friend constexpr bool operator!=(mapping const& lhs, + mapping const& rhs) noexcept { + return lhs.extents() != rhs.extents(); + } #endif - // Not really public, but currently needed to implement fully constexpr useable submdspan: - template - MDSPAN_INLINE_FUNCTION - constexpr index_type impl_get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents,std::integer_sequence) const { - return MDSPAN_IMPL_FOLD_TIMES_RIGHT((Idx>N? m_extents.template extent():1),1); - } - template - MDSPAN_INLINE_FUNCTION - constexpr index_type impl_stide() const noexcept { - return impl_get_stride(m_extents, std::make_index_sequence()); - } - -private: - MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template - MDSPAN_INLINE_FUNCTION - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } + // Not really public, but currently needed to implement fully constexpr + // useable submdspan: + template + MDSPAN_INLINE_FUNCTION constexpr index_type impl_get_stride( + MDSPAN_IMPL_STANDARD_NAMESPACE::extents, + std::integer_sequence) const { + return MDSPAN_IMPL_FOLD_TIMES_RIGHT( + (Idx > N ? m_extents.template extent() : 1), 1); + } + template + MDSPAN_INLINE_FUNCTION constexpr index_type impl_stide() const noexcept { + return impl_get_stride(m_extents, + std::make_index_sequence()); + } + + private: + MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; + + // [mdspan.submdspan.mapping], submdspan mapping specialization + template + MDSPAN_INLINE_FUNCTION constexpr auto submdspan_mapping_impl( + SliceSpecifiers... slices) const; + + template + MDSPAN_INLINE_FUNCTION friend constexpr auto submdspan_mapping( + const mapping& src, SliceSpecifiers... slices) { + return src.submdspan_mapping_impl(slices...); + } }; -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/layout_stride.hpp b/include/experimental/__p0009_bits/layout_stride.hpp index 2b83f429..b83607c0 100644 --- a/include/experimental/__p0009_bits/layout_stride.hpp +++ b/include/experimental/__p0009_bits/layout_stride.hpp @@ -22,7 +22,7 @@ #include "utility.hpp" #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# include "no_unique_address.hpp" +#include "no_unique_address.hpp" #endif #include @@ -32,88 +32,92 @@ #ifdef __cpp_lib_span #include #endif -#if defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 && defined(__cpp_lib_concepts) -# include +#if defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 && \ + defined(__cpp_lib_concepts) +#include #endif namespace MDSPAN_IMPL_STANDARD_NAMESPACE { struct layout_left { - template + template class mapping; }; struct layout_right { - template + template class mapping; }; namespace detail { - template - constexpr bool is_mapping_of = - std::is_same, Mapping>::value; +template +constexpr bool is_mapping_of = std::is_same< + typename Layout::template mapping, + Mapping>::value; #if defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 -# if !defined(__cpp_lib_concepts) - namespace internal { - namespace detail { - template - concept same_as = std::is_same_v; - } // namespace detail - template - concept same_as = detail::same_as && detail::same_as; - } // namespace internal -# endif - - template - concept layout_mapping_alike = requires { - requires impl_is_extents::value; +#if !defined(__cpp_lib_concepts) +namespace internal { +namespace detail { +template +concept same_as = std::is_same_v; +} // namespace detail +template +concept same_as = detail::same_as && detail::same_as; +} // namespace internal +#endif + +template +concept layout_mapping_alike = requires { + requires impl_is_extents::value; #if defined(__cpp_lib_concepts) - { M::is_always_strided() } -> std::same_as; - { M::is_always_exhaustive() } -> std::same_as; - { M::is_always_unique() } -> std::same_as; + { M::is_always_strided() } -> std::same_as; + { M::is_always_exhaustive() } -> std::same_as; + { M::is_always_unique() } -> std::same_as; #else - { M::is_always_strided() } -> internal::same_as; - { M::is_always_exhaustive() } -> internal::_ame_as; - { M::is_always_unique() } -> internal::same_as; + { M::is_always_strided() } -> internal::same_as; + { M::is_always_exhaustive() } -> internal::_ame_as; + { M::is_always_unique() } -> internal::same_as; #endif - std::bool_constant::value; - std::bool_constant::value; - std::bool_constant::value; - }; + std::bool_constant::value; + std::bool_constant::value; + std::bool_constant::value; +}; #endif -} // namespace detail +} // namespace detail struct layout_stride { template class mapping #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : private detail::no_unique_address_emulation< - detail::impl_compressed_pair< - Extents, - detail::possibly_empty_array - > - > + : private detail::no_unique_address_emulation< + detail::impl_compressed_pair< + Extents, detail::possibly_empty_array< + typename Extents::index_type, Extents::rank()>>> #endif { - public: + public: using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_stride; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_stride; - // This could be a `requires`, but I think it's better and clearer as a `static_assert`. + // This could be a `requires`, but I think it's better and clearer as a + // `static_assert`. static_assert(detail::impl_is_extents_v, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_stride::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - - private: + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::layout_stride::mapping must be instantiated with a " + "specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::extents."); + private: //---------------------------------------------------------------------------- - using strides_storage_t = detail::possibly_empty_array; - using member_pair_t = detail::impl_compressed_pair; + using strides_storage_t = + detail::possibly_empty_array; + using member_pair_t = + detail::impl_compressed_pair; #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) MDSPAN_IMPL_NO_UNIQUE_ADDRESS member_pair_t m_members; @@ -138,10 +142,12 @@ struct layout_stride { #endif } - template - MDSPAN_IMPL_HOST_DEVICE - constexpr index_type get_size(::MDSPAN_IMPL_STANDARD_NAMESPACE::extents,std::integer_sequence) const { - return MDSPAN_IMPL_FOLD_TIMES_RIGHT( static_cast(extents().extent(Idx)), 1 ); + template + MDSPAN_IMPL_HOST_DEVICE constexpr index_type get_size( + ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents, + std::integer_sequence) const { + return MDSPAN_IMPL_FOLD_TIMES_RIGHT( + static_cast(extents().extent(Idx)), 1); } //---------------------------------------------------------------------------- @@ -151,90 +157,118 @@ struct layout_stride { //---------------------------------------------------------------------------- - // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level + // Workaround for non-deducibility of the index sequence template parameter + // if it's given at the top level template struct deduction_workaround; template - struct deduction_workaround> - { + struct deduction_workaround> { template - MDSPAN_INLINE_FUNCTION - static constexpr bool _eq_impl(mapping const& self, mapping const& other) noexcept { - using common_t = std::common_type_t; - return MDSPAN_IMPL_FOLD_AND((static_cast(self.stride(Idxs)) == static_cast(other.stride(Idxs))) /* && ... */) - && MDSPAN_IMPL_FOLD_AND((static_cast(self.extents().extent(Idxs)) == static_cast(other.extents().extent(Idxs))) /* || ... */); + MDSPAN_INLINE_FUNCTION static constexpr bool _eq_impl( + mapping const& self, mapping const& other) noexcept { + using common_t = + std::common_type_t; + return MDSPAN_IMPL_FOLD_AND( + (static_cast(self.stride(Idxs)) == + static_cast(other.stride(Idxs))) /* && ... */) && + MDSPAN_IMPL_FOLD_AND( + (static_cast(self.extents().extent(Idxs)) == + static_cast( + other.extents().extent(Idxs))) /* || ... */); } template - MDSPAN_INLINE_FUNCTION - static constexpr bool _not_eq_impl(mapping const& self, mapping const& other) noexcept { - using common_t = std::common_type_t; - return MDSPAN_IMPL_FOLD_OR((static_cast(self.stride(Idxs)) != static_cast(other.stride(Idxs))) /* || ... */) - || MDSPAN_IMPL_FOLD_OR((static_cast(self.extents().extent(Idxs)) != static_cast(other.extents().extent(Idxs))) /* || ... */); + MDSPAN_INLINE_FUNCTION static constexpr bool _not_eq_impl( + mapping const& self, mapping const& other) noexcept { + using common_t = + std::common_type_t; + return MDSPAN_IMPL_FOLD_OR( + (static_cast(self.stride(Idxs)) != + static_cast(other.stride(Idxs))) /* || ... */) || + MDSPAN_IMPL_FOLD_OR( + (static_cast(self.extents().extent(Idxs)) != + static_cast( + other.extents().extent(Idxs))) /* || ... */); } template - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr size_t _call_op_impl(mapping const& self, Integral... idxs) noexcept { - return MDSPAN_IMPL_FOLD_PLUS_RIGHT((idxs * self.stride(Idxs)), /* + ... + */ 0); + MDSPAN_FORCE_INLINE_FUNCTION static constexpr size_t _call_op_impl( + mapping const& self, Integral... idxs) noexcept { + return MDSPAN_IMPL_FOLD_PLUS_RIGHT((idxs * self.stride(Idxs)), + /* + ... + */ 0); } MDSPAN_INLINE_FUNCTION - static constexpr size_t _req_span_size_impl(mapping const& self) noexcept { - // assumes no negative strides; not sure if I'm allowed to assume that or not - return deduction_workaround_impl::_call_op_impl(self, (self.extents().template extent() - 1)...) + 1; + static constexpr size_t _req_span_size_impl( + mapping const& self) noexcept { + // assumes no negative strides; not sure if I'm allowed to assume that + // or not + return deduction_workaround_impl::_call_op_impl( + self, (self.extents().template extent() - 1)...) + + 1; } - template - MDSPAN_INLINE_FUNCTION - static constexpr const strides_storage_t fill_strides(const OtherMapping& map) { + template + MDSPAN_INLINE_FUNCTION static constexpr const strides_storage_t + fill_strides(const OtherMapping& map) { return strides_storage_t{static_cast(map.stride(Idxs))...}; } MDSPAN_INLINE_FUNCTION - static constexpr const strides_storage_t& fill_strides(const strides_storage_t& s) { + static constexpr const strides_storage_t& fill_strides( + const strides_storage_t& s) { return s; } - template - static constexpr const strides_storage_t fill_strides(const std::array& s) { + template + static constexpr const strides_storage_t fill_strides( + const std::array& s) { return strides_storage_t{static_cast(s[Idxs])...}; } MDSPAN_TEMPLATE_REQUIRES( - class IntegralType, - (std::is_convertible::value) - ) + class IntegralType, + (std::is_convertible::value)) MDSPAN_INLINE_FUNCTION // Need to avoid zero length c-array - static constexpr const strides_storage_t fill_strides(mdspan_non_standard_tag, const IntegralType (&s)[extents_type::rank()>0?extents_type::rank():1]) { + static constexpr const strides_storage_t fill_strides( + mdspan_non_standard_tag, + const IntegralType ( + &s)[extents_type::rank() > 0 ? extents_type::rank() : 1]) { return strides_storage_t{static_cast(s[Idxs])...}; } #ifdef __cpp_lib_span - template - static constexpr const strides_storage_t fill_strides(const std::span& s) { + template + static constexpr const strides_storage_t fill_strides( + const std::span& s) { return strides_storage_t{static_cast(s[Idxs])...}; } #endif MDSPAN_INLINE_FUNCTION - static constexpr std::array return_strides(const strides_storage_t& s) { + static constexpr std::array + return_strides(const strides_storage_t& s) { return std::array{s[Idxs]...}; } - template - MDSPAN_INLINE_FUNCTION - static constexpr size_t return_zero() { return 0; } + template + MDSPAN_INLINE_FUNCTION static constexpr size_t return_zero() { + return 0; + } - template - MDSPAN_INLINE_FUNCTION - static constexpr typename Mapping::index_type - offset(const Mapping& m) { return m(return_zero()...); } + template + MDSPAN_INLINE_FUNCTION static constexpr typename Mapping::index_type + offset(const Mapping& m) { + return m(return_zero()...); + } }; - // Can't use defaulted parameter in the deduction_workaround template because of a bug in MSVC warning C4348. - using deduction_workaround_impl = deduction_workaround>; + // Can't use defaulted parameter in the deduction_workaround template + // because of a bug in MSVC warning C4348. + using deduction_workaround_impl = + deduction_workaround>; MDSPAN_FUNCTION static constexpr strides_storage_t strides_storage(detail::with_rank<0>) { @@ -242,13 +276,13 @@ struct layout_stride { } template - MDSPAN_FUNCTION - static constexpr strides_storage_t strides_storage(detail::with_rank) { + MDSPAN_FUNCTION static constexpr strides_storage_t strides_storage( + detail::with_rank) { strides_storage_t s{}; extents_type e; index_type stride = 1; - for(int r = static_cast(extents_type::rank() - 1); r >= 0; r--) { + for (int r = static_cast(extents_type::rank() - 1); r >= 0; r--) { s[r] = stride; stride *= e.extent(r); } @@ -259,43 +293,50 @@ struct layout_stride { //---------------------------------------------------------------------------- #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - MDSPAN_INLINE_FUNCTION constexpr explicit - mapping(member_pair_t&& m) : m_members(::std::move(m)) {} + MDSPAN_INLINE_FUNCTION constexpr explicit mapping(member_pair_t&& m) + : m_members(::std::move(m)) {} #else - MDSPAN_INLINE_FUNCTION constexpr explicit - mapping(base_t&& __b) : base_t(::std::move(__b)) {} + MDSPAN_INLINE_FUNCTION constexpr explicit mapping(base_t&& __b) + : base_t(::std::move(__b)) {} #endif - public: - + public: //-------------------------------------------------------------------------------- MDSPAN_INLINE_FUNCTION constexpr mapping() noexcept #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : m_members{ #else - : base_t(base_t{member_pair_t( + : base_t(base_t { + member_pair_t( #endif extents_type(), strides_storage_t(strides_storage(detail::with_rank{})) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) } #else - )}) + ) + }) #endif - {} + { + } - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping( + mapping const&) noexcept = default; MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - MDSPAN_IMPL_TRAIT(std::is_convertible, const std::remove_const_t&, typename Extents::index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t&) - ) - ) + class IntegralTypes, + /* requires */ ( + // MSVC 19.32 does not like using index_type here, requires the + // typename Extents::index_type error C2641: cannot deduce template + // arguments for + // 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' + MDSPAN_IMPL_TRAIT(std::is_convertible, + const std::remove_const_t&, + typename Extents::index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + typename Extents::index_type, + const std::remove_const_t&))) constexpr mapping( extents_type const& e, @@ -304,34 +345,42 @@ struct layout_stride { #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : m_members{ #else - : base_t(base_t{member_pair_t( + : base_t(base_t { + member_pair_t( #endif e, strides_storage_t(deduction_workaround_impl::fill_strides(s)) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) } #else - )}) + ) + }) #endif { /* * TODO: check preconditions * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. + * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type + * ([basic.fundamental]). + * - If rank_ is greater than 0, then there exists a permutation P of the + * integers in the range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * + * e.extent( pi − 1 ) is true for all i in the range [1, rank_ ), where pi + * is the ith element of P. */ } MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - MDSPAN_IMPL_TRAIT(std::is_convertible, const std::remove_const_t&, typename Extents::index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t&) - ) - ) + class IntegralTypes, + /* requires */ ( + // MSVC 19.32 does not like using index_type here, requires the + // typename Extents::index_type error C2641: cannot deduce template + // arguments for + // 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' + MDSPAN_IMPL_TRAIT(std::is_convertible, + const std::remove_const_t&, + typename Extents::index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + typename Extents::index_type, + const std::remove_const_t&))) MDSPAN_INLINE_FUNCTION constexpr mapping( @@ -343,35 +392,43 @@ struct layout_stride { #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : m_members{ #else - : base_t(base_t{member_pair_t( + : base_t(base_t { + member_pair_t( #endif e, strides_storage_t(deduction_workaround_impl::fill_strides(mdspan_non_standard, s)) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) } #else - )}) + ) + }) #endif { /* * TODO: check preconditions * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. + * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type + * ([basic.fundamental]). + * - If rank_ is greater than 0, then there exists a permutation P of the + * integers in the range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * + * e.extent( pi − 1 ) is true for all i in the range [1, rank_ ), where pi + * is the ith element of P. */ } #ifdef __cpp_lib_span MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - MDSPAN_IMPL_TRAIT(std::is_convertible, const std::remove_const_t&, typename Extents::index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t&) - ) - ) + class IntegralTypes, + /* requires */ ( + // MSVC 19.32 does not like using index_type here, requires the + // typename Extents::index_type error C2641: cannot deduce template + // arguments for + // 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' + MDSPAN_IMPL_TRAIT(std::is_convertible, + const std::remove_const_t&, + typename Extents::index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + typename Extents::index_type, + const std::remove_const_t&))) constexpr mapping( extents_type const& e, @@ -380,79 +437,88 @@ struct layout_stride { #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : m_members{ #else - : base_t(base_t{member_pair_t( + : base_t(base_t { + member_pair_t( #endif e, strides_storage_t(deduction_workaround_impl::fill_strides(s)) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) } #else - )}) + ) + }) #endif { /* * TODO: check preconditions * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. + * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type + * ([basic.fundamental]). + * - If rank_ is greater than 0, then there exists a permutation P of the + * integers in the range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * + * e.extent( pi − 1 ) is true for all i in the range [1, rank_ ), where pi + * is the ith element of P. */ } -#endif // __cpp_lib_span +#endif // __cpp_lib_span #if !(defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20) MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) && - detail::is_mapping_of && - StridedLayoutMapping::is_always_unique() && - StridedLayoutMapping::is_always_strided() - ) - ) + class StridedLayoutMapping, + /* requires */ ( + MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + typename StridedLayoutMapping::extents_type) && + detail::is_mapping_of && + StridedLayoutMapping::is_always_unique() && + StridedLayoutMapping::is_always_strided())) #else - template - requires( - detail::layout_mapping_alike && - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) && - StridedLayoutMapping::is_always_unique() && - StridedLayoutMapping::is_always_strided() - ) + template + requires(detail::layout_mapping_alike && + MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + typename StridedLayoutMapping::extents_type) && + StridedLayoutMapping::is_always_unique() && + StridedLayoutMapping::is_always_strided()) #endif MDSPAN_CONDITIONAL_EXPLICIT( - !(std::is_convertible::value && - (detail::is_mapping_of || - detail::is_mapping_of || - detail::is_mapping_of)) - ) // needs two () due to comma + !(std::is_convertible::value && + (detail::is_mapping_of || + detail::is_mapping_of || + detail::is_mapping_of))) // needs two () due + // to comma MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 mapping(StridedLayoutMapping const& other) noexcept // NOLINT(google-explicit-constructor) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) : m_members{ #else - : base_t(base_t{member_pair_t( + : base_t(base_t { + member_pair_t( #endif other.extents(), strides_storage_t(deduction_workaround_impl::fill_strides(other)) #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) } #else - )}) + ) + }) #endif { /* * TODO: check preconditions * - other.stride(i) > 0 is true for all i in the range [0, rank_ ). - * - other.required_span_size() is a representable value of type index_type ([basic.fundamental]). + * - other.required_span_size() is a representable value of type + * index_type ([basic.fundamental]). * - OFFSET(other) == 0 */ } //-------------------------------------------------------------------------------- - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED - mapping& operator=(mapping const&) noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& + operator=(mapping const&) noexcept = default; - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { + MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() + const noexcept { #if defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) return m_members.first(); #else @@ -461,7 +527,8 @@ struct layout_stride { } MDSPAN_INLINE_FUNCTION - constexpr std::array< index_type, extents_type::rank() > strides() const noexcept { + constexpr std::array strides() + const noexcept { return deduction_workaround_impl::return_strides(strides_storage()); } @@ -469,62 +536,65 @@ struct layout_stride { constexpr index_type required_span_size() const noexcept { index_type span_size = 1; // using int here to avoid warning about pointless comparison to 0 - for(int r = 0; r < static_cast(extents_type::rank()); r++) { + for (int r = 0; r < static_cast(extents_type::rank()); r++) { // Return early if any of the extents are zero - if(extents().extent(r)==0) return 0; - span_size += ( static_cast(extents().extent(r) - 1 ) * strides_storage()[r]); + if (extents().extent(r) == 0) return 0; + span_size += (static_cast(extents().extent(r) - 1) * + strides_storage()[r]); } return span_size; } - MDSPAN_TEMPLATE_REQUIRES( - class... Indices, - /* requires */ ( - sizeof...(Indices) == Extents::rank() && - (detail::are_valid_indices()) - ) - ) + class... Indices, + /* requires */ (sizeof...(Indices) == Extents::rank() && + (detail::are_valid_indices()))) MDSPAN_FORCE_INLINE_FUNCTION constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) +#if !defined(NDEBUG) detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return static_cast(deduction_workaround_impl::_call_op_impl(*this, static_cast(idxs)...)); +#endif // ! NDEBUG + return static_cast(deduction_workaround_impl::_call_op_impl( + *this, static_cast(idxs)...)); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool + is_always_exhaustive() noexcept { return false; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { + return true; + } - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } + MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { + return true; + } - private: + private: MDSPAN_INLINE_FUNCTION - constexpr bool exhaustive_for_nonzero_span_size() const - { - return required_span_size() == get_size(extents(), std::make_index_sequence()); + constexpr bool exhaustive_for_nonzero_span_size() const { + return required_span_size() == + get_size(extents(), + std::make_index_sequence()); } MDSPAN_INLINE_FUNCTION - constexpr bool is_exhaustive_impl(detail::with_rank<0>) const - { + constexpr bool is_exhaustive_impl(detail::with_rank<0>) const { return true; } MDSPAN_INLINE_FUNCTION - constexpr bool is_exhaustive_impl(detail::with_rank<1>) const - { + constexpr bool is_exhaustive_impl(detail::with_rank<1>) const { if (required_span_size() != static_cast(0)) { return exhaustive_for_nonzero_span_size(); } return stride(0) == 1; } template - MDSPAN_INLINE_FUNCTION - constexpr bool is_exhaustive_impl(detail::with_rank) const - { + MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive_impl( + detail::with_rank) const { if (required_span_size() != static_cast(0)) { return exhaustive_for_nonzero_span_size(); } @@ -543,12 +613,14 @@ struct layout_stride { return true; } - public: - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 bool is_exhaustive() const noexcept { + public: + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 bool is_exhaustive() + const noexcept { return is_exhaustive_impl(detail::with_rank{}); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - + MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { + return true; + } MDSPAN_INLINE_FUNCTION constexpr index_type stride(rank_type r) const noexcept { @@ -557,13 +629,13 @@ struct layout_stride { #if !(defined(MDSPAN_IMPL_USE_CONCEPTS) && MDSPAN_HAS_CXX_20) MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - detail::is_mapping_of && - (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) && - StridedLayoutMapping::is_always_strided() - ) - ) + class StridedLayoutMapping, + /* requires */ ( + detail::is_mapping_of && + (extents_type::rank() == + StridedLayoutMapping::extents_type::rank()) && + StridedLayoutMapping::is_always_strided())) #else template requires( @@ -573,60 +645,59 @@ struct layout_stride { ) #endif MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(const mapping& x, const StridedLayoutMapping& y) noexcept { + friend constexpr bool operator==(const mapping& x, + const StridedLayoutMapping& y) noexcept { return (x.extents() == y.extents()) && - (deduction_workaround_impl::offset(y) == static_cast(0)) && - detail::rankwise_equal(detail::with_rank{}, x, y, detail::stride); + (deduction_workaround_impl::offset(y) == + static_cast(0)) && + detail::rankwise_equal(detail::with_rank{}, + x, y, detail::stride); } - // This one is not technically part of the proposal. Just here to make implementation a bit more optimal hopefully - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - (extents_type::rank() == OtherExtents::rank()) - ) - ) + // This one is not technically part of the proposal. Just here to make + // implementation a bit more optimal hopefully + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ ((extents_type::rank() == + OtherExtents::rank()))) MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping const& rhs) noexcept { + friend constexpr bool operator==( + mapping const& lhs, mapping const& rhs) noexcept { return deduction_workaround_impl::_eq_impl(lhs, rhs); } #if !MDSPAN_HAS_CXX_20 MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - detail::is_mapping_of && - (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) && - StridedLayoutMapping::is_always_strided() - ) - ) + class StridedLayoutMapping, + /* requires */ ( + detail::is_mapping_of && + (extents_type::rank() == + StridedLayoutMapping::extents_type::rank()) && + StridedLayoutMapping::is_always_strided())) MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(const mapping& x, const StridedLayoutMapping& y) noexcept { + friend constexpr bool operator!=(const mapping& x, + const StridedLayoutMapping& y) noexcept { return !(x == y); } - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - (extents_type::rank() == OtherExtents::rank()) - ) - ) + MDSPAN_TEMPLATE_REQUIRES(class OtherExtents, + /* requires */ ((extents_type::rank() == + OtherExtents::rank()))) MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping const& rhs) noexcept { + friend constexpr bool operator!=( + mapping const& lhs, mapping const& rhs) noexcept { return deduction_workaround_impl::_not_eq_impl(lhs, rhs); } #endif - // [mdspan.submdspan.mapping], submdspan mapping specialization - template - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; + // [mdspan.submdspan.mapping], submdspan mapping specialization + template + MDSPAN_INLINE_FUNCTION constexpr auto submdspan_mapping_impl( + SliceSpecifiers... slices) const; - template - MDSPAN_INLINE_FUNCTION - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { + template + MDSPAN_INLINE_FUNCTION friend constexpr auto submdspan_mapping( + const mapping& src, SliceSpecifiers... slices) { return src.submdspan_mapping_impl(slices...); } }; @@ -635,19 +706,20 @@ struct layout_stride { namespace detail { template -MDSPAN_INLINE_FUNCTION -constexpr void validate_strides(with_rank<0>, Layout, const Extents&, const Mapping&) -{} +MDSPAN_INLINE_FUNCTION constexpr void validate_strides(with_rank<0>, Layout, + const Extents&, + const Mapping&) {} template -MDSPAN_INLINE_FUNCTION -constexpr void validate_strides(with_rank, Layout, const Extents& ext, const Mapping& other) -{ - static_assert(std::is_same::value && - (std::is_same::value || - std::is_same::value) - , "This function is only intended to validate construction of " - "a layout_left or layout_right mapping from a layout_stride mapping."); +MDSPAN_INLINE_FUNCTION constexpr void validate_strides(with_rank, Layout, + const Extents& ext, + const Mapping& other) { + static_assert( + std::is_same::value && + (std::is_same::value || + std::is_same::value), + "This function is only intended to validate construction of " + "a layout_left or layout_right mapping from a layout_stride mapping."); constexpr auto is_left = std::is_same::value; @@ -656,12 +728,13 @@ constexpr void validate_strides(with_rank, Layout, const Extents& ext, const for (std::size_t r = 0; r < N; r++) { const std::size_t s = is_left ? r : N - 1 - r; - MDSPAN_IMPL_PRECONDITION(common_integral_compare(expected_stride, other.stride(s)) - && "invalid strides for layout_{left,right}"); + MDSPAN_IMPL_PRECONDITION( + common_integral_compare(expected_stride, other.stride(s)) && + "invalid strides for layout_{left,right}"); expected_stride *= ext.extent(s); } } -} // namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace detail +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/macros.hpp b/include/experimental/__p0009_bits/macros.hpp index 233ff0e8..d127173a 100644 --- a/include/experimental/__p0009_bits/macros.hpp +++ b/include/experimental/__p0009_bits/macros.hpp @@ -20,82 +20,75 @@ #include #include -#include // std::is_void -#if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_SYCL) +#include // std::is_void +#if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) || \ + defined(MDSPAN_IMPL_HAS_SYCL) #include "assert.h" #endif #ifndef MDSPAN_IMPL_HOST_DEVICE -# if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) -# define MDSPAN_IMPL_HOST_DEVICE __host__ __device__ -# else -# define MDSPAN_IMPL_HOST_DEVICE -# endif +#if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) +#define MDSPAN_IMPL_HOST_DEVICE __host__ __device__ +#else +#define MDSPAN_IMPL_HOST_DEVICE +#endif #endif #ifndef MDSPAN_FORCE_INLINE_FUNCTION -# ifdef MDSPAN_IMPL_COMPILER_MSVC // Microsoft compilers -# define MDSPAN_FORCE_INLINE_FUNCTION __forceinline MDSPAN_IMPL_HOST_DEVICE -# else -# define MDSPAN_FORCE_INLINE_FUNCTION __attribute__((always_inline)) MDSPAN_IMPL_HOST_DEVICE -# endif +#ifdef MDSPAN_IMPL_COMPILER_MSVC // Microsoft compilers +#define MDSPAN_FORCE_INLINE_FUNCTION __forceinline MDSPAN_IMPL_HOST_DEVICE +#else +#define MDSPAN_FORCE_INLINE_FUNCTION \ + __attribute__((always_inline)) MDSPAN_IMPL_HOST_DEVICE +#endif #endif #ifndef MDSPAN_INLINE_FUNCTION -# define MDSPAN_INLINE_FUNCTION inline MDSPAN_IMPL_HOST_DEVICE +#define MDSPAN_INLINE_FUNCTION inline MDSPAN_IMPL_HOST_DEVICE #endif #ifndef MDSPAN_FUNCTION -# define MDSPAN_FUNCTION MDSPAN_IMPL_HOST_DEVICE +#define MDSPAN_FUNCTION MDSPAN_IMPL_HOST_DEVICE #endif #ifdef MDSPAN_IMPL_HAS_HIP -# define MDSPAN_DEDUCTION_GUIDE MDSPAN_IMPL_HOST_DEVICE +#define MDSPAN_DEDUCTION_GUIDE MDSPAN_IMPL_HOST_DEVICE #else -# define MDSPAN_DEDUCTION_GUIDE +#define MDSPAN_DEDUCTION_GUIDE #endif // In CUDA defaulted functions do not need host device markup #ifndef MDSPAN_INLINE_FUNCTION_DEFAULTED -# define MDSPAN_INLINE_FUNCTION_DEFAULTED +#define MDSPAN_INLINE_FUNCTION_DEFAULTED #endif //============================================================================== // {{{1 -#define MDSPAN_PP_COUNT(...) \ +#define MDSPAN_PP_COUNT(...) \ MDSPAN_IMPL_PP_INTERNAL_EXPAND_ARGS( \ - MDSPAN_IMPL_PP_INTERNAL_ARGS_AUGMENTER(__VA_ARGS__) \ - ) + MDSPAN_IMPL_PP_INTERNAL_ARGS_AUGMENTER(__VA_ARGS__)) #define MDSPAN_IMPL_PP_INTERNAL_ARGS_AUGMENTER(...) unused, __VA_ARGS__ #define MDSPAN_IMPL_PP_INTERNAL_EXPAND(x) x -#define MDSPAN_IMPL_PP_INTERNAL_EXPAND_ARGS(...) \ - MDSPAN_IMPL_PP_INTERNAL_EXPAND( \ - MDSPAN_IMPL_PP_INTERNAL_COUNT( \ - __VA_ARGS__, 69, 68, 67, 66, 65, 64, 63, 62, 61, \ - 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \ - 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, \ - 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, \ - 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \ - 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 \ - ) \ - ) -# define MDSPAN_IMPL_PP_INTERNAL_COUNT( \ - _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, \ - _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ - _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \ - _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \ - _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \ - _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, \ - _70, count, ...) count \ - /**/ +#define MDSPAN_IMPL_PP_INTERNAL_EXPAND_ARGS(...) \ + MDSPAN_IMPL_PP_INTERNAL_EXPAND(MDSPAN_IMPL_PP_INTERNAL_COUNT( \ + __VA_ARGS__, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, \ + 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, \ + 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \ + 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#define MDSPAN_IMPL_PP_INTERNAL_COUNT( \ + _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10, _11, _12, _13, _14, _15, \ + _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, \ + _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, count, ...) \ + count /**/ #define MDSPAN_PP_STRINGIFY_IMPL(x) #x #define MDSPAN_PP_STRINGIFY(x) MDSPAN_PP_STRINGIFY_IMPL(x) -#define MDSPAN_PP_CAT_IMPL(x, y) x ## y +#define MDSPAN_PP_CAT_IMPL(x, y) x##y #define MDSPAN_PP_CAT(x, y) MDSPAN_PP_CAT_IMPL(x, y) #define MDSPAN_PP_EVAL(X, ...) X(__VA_ARGS__) @@ -103,76 +96,84 @@ #define MDSPAN_PP_REMOVE_PARENS_IMPL(...) __VA_ARGS__ #define MDSPAN_PP_REMOVE_PARENS(...) MDSPAN_PP_REMOVE_PARENS_IMPL __VA_ARGS__ -#define MDSPAN_IMPL_STANDARD_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) -#define MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) "::" MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_PROPOSED_NAMESPACE) +#define MDSPAN_IMPL_STANDARD_NAMESPACE_STRING \ + MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) +#define MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING \ + MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) \ + "::" MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_PROPOSED_NAMESPACE) namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace detail { #if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ +MDSPAN_FUNCTION inline void default_precondition_violation_handler( + const char* cond, const char* file, unsigned line) { ::printf("%s:%u: precondition failure: `%s`\n", file, line, cond); assert(0); } #elif defined(MDSPAN_IMPL_HAS_SYCL) -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ +MDSPAN_FUNCTION inline void default_precondition_violation_handler( + const char* cond, const char* file, unsigned line) { #ifdef __INTEL_LLVM_COMPILER - sycl::ext::oneapi::experimental::printf("%s:%u: precondition failure: `%s`\n", file, line, cond); + sycl::ext::oneapi::experimental::printf("%s:%u: precondition failure: `%s`\n", + file, line, cond); #else - (void) cond; - (void) file; - (void) line; + (void)cond; + (void)file; + (void)line; #endif assert(0); } #else -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ +MDSPAN_FUNCTION inline void default_precondition_violation_handler( + const char* cond, const char* file, unsigned line) { std::fprintf(stderr, "%s:%u: precondition failure: `%s`\n", file, line, cond); std::abort(); } #endif -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace detail +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE #ifndef MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER #define MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line) \ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::default_precondition_violation_handler(cond, file, line) + MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: \ + default_precondition_violation_handler(cond, file, line) #endif #ifndef MDSPAN_IMPL_CHECK_PRECONDITION - #ifndef NDEBUG - #define MDSPAN_IMPL_CHECK_PRECONDITION 0 - #else - #define MDSPAN_IMPL_CHECK_PRECONDITION 1 - #endif +#ifndef NDEBUG +#define MDSPAN_IMPL_CHECK_PRECONDITION 0 +#else +#define MDSPAN_IMPL_CHECK_PRECONDITION 1 +#endif #endif namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace detail { template -MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, unsigned line) -{ - if (!check) { return; } +MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, + unsigned line) { + if (!check) { + return; + } // in case the macro doesn't use the arguments for custom macros - (void) cond; - (void) file; - (void) line; + (void)cond; + (void)file; + (void)line; MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line); } -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace detail +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE -#define MDSPAN_IMPL_PRECONDITION(...) \ - do { \ - if (!(__VA_ARGS__)) { \ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::precondition(#__VA_ARGS__, __FILE__, __LINE__); \ - } \ +#define MDSPAN_IMPL_PRECONDITION(...) \ + do { \ + if (!(__VA_ARGS__)) { \ + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::precondition( \ + #__VA_ARGS__, __FILE__, __LINE__); \ + } \ } while (0) // end Preprocessor helpers }}}1 @@ -181,121 +182,117 @@ MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, //============================================================================== // {{{1 -// These compatibility macros don't help with partial ordering, but they should do the trick -// for what we need to do with concepts in mdspan +// These compatibility macros don't help with partial ordering, but they should +// do the trick for what we need to do with concepts in mdspan #ifdef MDSPAN_IMPL_USE_CONCEPTS -# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) > requires REQ -# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \ - MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS requires REQ \ - /**/ +#define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ + > \ + requires REQ +#define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, \ + REQ) \ + MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) \ + FNAME PAREN_PARAMS QUALS \ + requires REQ /**/ #else -# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) , typename ::std::enable_if<(REQ), int>::type = 0> -# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \ - MDSPAN_TEMPLATE_REQUIRES( \ - class function_requires_ignored=void, \ - (std::is_void::value && REQ) \ - ) MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS \ - /**/ +#define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ + , typename ::std::enable_if<(REQ), int>::type = 0 > +#define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, \ + REQ) \ + MDSPAN_TEMPLATE_REQUIRES( \ + class function_requires_ignored = void, \ + (std::is_void::value && REQ)) \ + MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS /**/ #endif -#if defined(MDSPAN_IMPL_COMPILER_MSVC) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) -# define MDSPAN_TEMPLATE_REQUIRES(...) \ - MDSPAN_PP_CAT( \ - MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__))\ - (__VA_ARGS__), \ - ) \ - /**/ +#if defined(MDSPAN_IMPL_COMPILER_MSVC) && \ + (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) +#define MDSPAN_TEMPLATE_REQUIRES(...) \ + MDSPAN_PP_CAT(MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, \ + MDSPAN_PP_COUNT(__VA_ARGS__))(__VA_ARGS__), ) \ + /**/ #else -# define MDSPAN_TEMPLATE_REQUIRES(...) \ - MDSPAN_PP_EVAL( \ - MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__)), \ - __VA_ARGS__ \ - ) \ - /**/ +#define MDSPAN_TEMPLATE_REQUIRES(...) \ + MDSPAN_PP_EVAL( \ + MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__)), \ + __VA_ARGS__) \ + /**/ #endif #define MDSPAN_TEMPLATE_REQUIRES_2(TP1, REQ) \ - template end Concept emulation }}}1 @@ -305,9 +302,9 @@ MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, // {{{1 #ifdef MDSPAN_IMPL_USE_INLINE_VARIABLES -# define MDSPAN_IMPL_INLINE_VARIABLE inline +#define MDSPAN_IMPL_INLINE_VARIABLE inline #else -# define MDSPAN_IMPL_INLINE_VARIABLE +#define MDSPAN_IMPL_INLINE_VARIABLE #endif // end inline variables }}}1 @@ -317,19 +314,26 @@ MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, // {{{1 #if MDSPAN_IMPL_USE_RETURN_TYPE_DEDUCTION -# define MDSPAN_IMPL_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); } -# define MDSPAN_IMPL_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - decltype(auto) MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); } +#define MDSPAN_IMPL_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ + auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { \ + return MDSPAN_PP_REMOVE_PARENS(BODY); \ + } +#define MDSPAN_IMPL_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, \ + BODY) \ + decltype(auto) MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { \ + return MDSPAN_PP_REMOVE_PARENS(BODY); \ + } #else -# define MDSPAN_IMPL_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \ - -> std::remove_cv_t> \ - { return MDSPAN_PP_REMOVE_PARENS(BODY); } -# define MDSPAN_IMPL_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \ - -> decltype(BODY) \ - { return MDSPAN_PP_REMOVE_PARENS(BODY); } +#define MDSPAN_IMPL_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ + auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \ + ->std::remove_cv_t> { \ + return MDSPAN_PP_REMOVE_PARENS(BODY); \ + } +#define MDSPAN_IMPL_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, \ + BODY) \ + auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE)->decltype(BODY) { \ + return MDSPAN_PP_REMOVE_PARENS(BODY); \ + } #endif @@ -339,96 +343,96 @@ MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, //============================================================================== // {{{1 -struct enable_fold_comma { }; +struct enable_fold_comma {}; #ifdef MDSPAN_IMPL_USE_FOLD_EXPRESSIONS -# define MDSPAN_IMPL_FOLD_AND(...) ((__VA_ARGS__) && ...) -# define MDSPAN_IMPL_FOLD_AND_TEMPLATE(...) ((__VA_ARGS__) && ...) -# define MDSPAN_IMPL_FOLD_OR(...) ((__VA_ARGS__) || ...) -# define MDSPAN_IMPL_FOLD_ASSIGN_LEFT(INIT, ...) (INIT = ... = (__VA_ARGS__)) -# define MDSPAN_IMPL_FOLD_ASSIGN_RIGHT(PACK, ...) (PACK = ... = (__VA_ARGS__)) -# define MDSPAN_IMPL_FOLD_TIMES_RIGHT(PACK, ...) (PACK * ... * (__VA_ARGS__)) -# define MDSPAN_IMPL_FOLD_PLUS_RIGHT(PACK, ...) (PACK + ... + (__VA_ARGS__)) -# define MDSPAN_IMPL_FOLD_COMMA(...) ((__VA_ARGS__), ...) +#define MDSPAN_IMPL_FOLD_AND(...) ((__VA_ARGS__) && ...) +#define MDSPAN_IMPL_FOLD_AND_TEMPLATE(...) ((__VA_ARGS__) && ...) +#define MDSPAN_IMPL_FOLD_OR(...) ((__VA_ARGS__) || ...) +#define MDSPAN_IMPL_FOLD_ASSIGN_LEFT(INIT, ...) (INIT = ... = (__VA_ARGS__)) +#define MDSPAN_IMPL_FOLD_ASSIGN_RIGHT(PACK, ...) (PACK = ... = (__VA_ARGS__)) +#define MDSPAN_IMPL_FOLD_TIMES_RIGHT(PACK, ...) (PACK * ... * (__VA_ARGS__)) +#define MDSPAN_IMPL_FOLD_PLUS_RIGHT(PACK, ...) (PACK + ... + (__VA_ARGS__)) +#define MDSPAN_IMPL_FOLD_COMMA(...) ((__VA_ARGS__), ...) #else namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace fold_compatibility_impl { -// We could probably be more clever here, but at the (small) risk of losing some compiler understanding. For the -// few operations we need, it's not worth generalizing over the operation +// We could probably be more clever here, but at the (small) risk of losing some +// compiler understanding. For the few operations we need, it's not worth +// generalizing over the operation #if MDSPAN_IMPL_USE_RETURN_TYPE_DEDUCTION MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) fold_right_and_impl() { - return true; -} +constexpr decltype(auto) fold_right_and_impl() { return true; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) fold_right_and_impl(Arg&& arg, Args&&... args) { - return ((Arg&&)arg) && fold_compatibility_impl::fold_right_and_impl((Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr decltype(auto) fold_right_and_impl( + Arg&& arg, Args&&... args) { + return ((Arg&&)arg) && + fold_compatibility_impl::fold_right_and_impl((Args&&)args...); } MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) fold_right_or_impl() { - return false; -} +constexpr decltype(auto) fold_right_or_impl() { return false; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_or_impl(Arg&& arg, Args&&... args) { - return ((Arg&&)arg) || fold_compatibility_impl::fold_right_or_impl((Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_or_impl(Arg&& arg, + Args&&... args) { + return ((Arg&&)arg) || + fold_compatibility_impl::fold_right_or_impl((Args&&)args...); } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_left_assign_impl(Arg1&& arg1) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_left_assign_impl(Arg1&& arg1) { return (Arg1&&)arg1; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_left_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return fold_compatibility_impl::fold_left_assign_impl((((Arg1&&)arg1) = ((Arg2&&)arg2)), (Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_left_assign_impl( + Arg1&& arg1, Arg2&& arg2, Args&&... args) { + return fold_compatibility_impl::fold_left_assign_impl( + (((Arg1&&)arg1) = ((Arg2&&)arg2)), (Args&&)args...); } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_assign_impl(Arg1&& arg1) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_assign_impl( + Arg1&& arg1) { return (Arg1&&)arg1; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) = fold_compatibility_impl::fold_right_assign_impl((Arg2&&)arg2, (Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_assign_impl( + Arg1&& arg1, Arg2&& arg2, Args&&... args) { + return ((Arg1&&)arg1) = fold_compatibility_impl::fold_right_assign_impl( + (Arg2&&)arg2, (Args&&)args...); } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_plus_impl(Arg1&& arg1) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_plus_impl(Arg1&& arg1) { return (Arg1&&)arg1; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_plus_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) + fold_compatibility_impl::fold_right_plus_impl((Arg2&&)arg2, (Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_plus_impl( + Arg1&& arg1, Arg2&& arg2, Args&&... args) { + return ((Arg1&&)arg1) + fold_compatibility_impl::fold_right_plus_impl( + (Arg2&&)arg2, (Args&&)args...); } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_times_impl(Arg1&& arg1) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_times_impl(Arg1&& arg1) { return (Arg1&&)arg1; } template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto fold_right_times_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) * fold_compatibility_impl::fold_right_times_impl((Arg2&&)arg2, (Args&&)args...); +MDSPAN_FORCE_INLINE_FUNCTION constexpr auto fold_right_times_impl( + Arg1&& arg1, Arg2&& arg2, Args&&... args) { + return ((Arg1&&)arg1) * fold_compatibility_impl::fold_right_times_impl( + (Arg2&&)arg2, (Args&&)args...); } #else @@ -442,26 +446,23 @@ template <> struct fold_right_and_impl_<> { using rv = bool; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl() noexcept { - return true; - } + static constexpr rv impl() noexcept { return true; } }; template struct fold_right_and_impl_ { using next_t = fold_right_and_impl_; - using rv = decltype(std::declval() && std::declval()); + using rv = + decltype(std::declval() && std::declval()); MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg, Args&&... args) noexcept { + static constexpr rv impl(Arg&& arg, Args&&... args) noexcept { return ((Arg&&)arg) && next_t::impl((Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_right_and_impl_::rv -fold_right_and_impl(Args&&... args) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr + typename fold_right_and_impl_::rv + fold_right_and_impl(Args&&... args) { return fold_right_and_impl_::impl((Args&&)args...); } @@ -477,25 +478,21 @@ template <> struct fold_right_or_impl_<> { using rv = bool; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl() noexcept { - return false; - } + static constexpr rv impl() noexcept { return false; } }; template struct fold_right_or_impl_ { using next_t = fold_right_or_impl_; - using rv = decltype(std::declval() || std::declval()); + using rv = + decltype(std::declval() || std::declval()); MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg, Args&&... args) noexcept { + static constexpr rv impl(Arg&& arg, Args&&... args) noexcept { return ((Arg&&)arg) || next_t::impl((Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_right_or_impl_::rv +MDSPAN_FORCE_INLINE_FUNCTION constexpr typename fold_right_or_impl_::rv fold_right_or_impl(Args&&... args) { return fold_right_or_impl_::impl((Args&&)args...); } @@ -512,26 +509,23 @@ template struct fold_right_plus_impl_ { using rv = Arg&&; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } + static constexpr rv impl(Arg&& arg) noexcept { return (Arg&&)arg; } }; template struct fold_right_plus_impl_ { using next_t = fold_right_plus_impl_; - using rv = decltype(std::declval() + std::declval()); + using rv = + decltype(std::declval() + std::declval()); MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { + static constexpr rv impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { return ((Arg1&&)arg) + next_t::impl((Arg2&&)arg2, (Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_right_plus_impl_::rv -fold_right_plus_impl(Args&&... args) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr + typename fold_right_plus_impl_::rv + fold_right_plus_impl(Args&&... args) { return fold_right_plus_impl_::impl((Args&&)args...); } @@ -547,26 +541,23 @@ template struct fold_right_times_impl_ { using rv = Arg&&; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } + static constexpr rv impl(Arg&& arg) noexcept { return (Arg&&)arg; } }; template struct fold_right_times_impl_ { using next_t = fold_right_times_impl_; - using rv = decltype(std::declval() * std::declval()); + using rv = + decltype(std::declval() * std::declval()); MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { + static constexpr rv impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { return ((Arg1&&)arg) * next_t::impl((Arg2&&)arg2, (Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_right_times_impl_::rv -fold_right_times_impl(Args&&... args) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr + typename fold_right_times_impl_::rv + fold_right_times_impl(Args&&... args) { return fold_right_times_impl_::impl((Args&&)args...); } @@ -582,26 +573,23 @@ template struct fold_right_assign_impl_ { using rv = Arg&&; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } + static constexpr rv impl(Arg&& arg) noexcept { return (Arg&&)arg; } }; template struct fold_right_assign_impl_ { using next_t = fold_right_assign_impl_; - using rv = decltype(std::declval() = std::declval()); + using rv = + decltype(std::declval() = std::declval()); MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { + static constexpr rv impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { return ((Arg1&&)arg) = next_t::impl((Arg2&&)arg2, (Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_right_assign_impl_::rv -fold_right_assign_impl(Args&&... args) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr + typename fold_right_assign_impl_::rv + fold_right_assign_impl(Args&&... args) { return fold_right_assign_impl_::impl((Args&&)args...); } @@ -617,27 +605,23 @@ template struct fold_left_assign_impl_ { using rv = Arg&&; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } + static constexpr rv impl(Arg&& arg) noexcept { return (Arg&&)arg; } }; template struct fold_left_assign_impl_ { using assign_result_t = decltype(std::declval() = std::declval()); - using next_t = fold_left_assign_impl_; - using rv = typename next_t::rv; + using next_t = fold_left_assign_impl_; + using rv = typename next_t::rv; MDSPAN_FORCE_INLINE_FUNCTION - static constexpr rv - impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { + static constexpr rv impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { return next_t::impl(((Arg1&&)arg) = (Arg2&&)arg2, (Args&&)args...); } }; template -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename fold_left_assign_impl_::rv -fold_left_assign_impl(Args&&... args) { +MDSPAN_FORCE_INLINE_FUNCTION constexpr + typename fold_left_assign_impl_::rv + fold_left_assign_impl(Args&&... args) { return fold_left_assign_impl_::impl((Args&&)args...); } @@ -646,27 +630,45 @@ fold_left_assign_impl(Args&&... args) { #endif - template -constexpr enable_fold_comma fold_comma_impl(Args&&...) noexcept { return { }; } +constexpr enable_fold_comma fold_comma_impl(Args&&...) noexcept { + return {}; +} template struct fold_bools; -} // fold_compatibility_impl - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -# define MDSPAN_IMPL_FOLD_AND(...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_and_impl((__VA_ARGS__)...) -# define MDSPAN_IMPL_FOLD_OR(...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_or_impl((__VA_ARGS__)...) -# define MDSPAN_IMPL_FOLD_ASSIGN_LEFT(INIT, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_left_assign_impl(INIT, (__VA_ARGS__)...) -# define MDSPAN_IMPL_FOLD_ASSIGN_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_assign_impl((PACK)..., __VA_ARGS__) -# define MDSPAN_IMPL_FOLD_TIMES_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_times_impl((PACK)..., __VA_ARGS__) -# define MDSPAN_IMPL_FOLD_PLUS_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_plus_impl((PACK)..., __VA_ARGS__) -# define MDSPAN_IMPL_FOLD_COMMA(...) MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_comma_impl((__VA_ARGS__)...) - -# define MDSPAN_IMPL_FOLD_AND_TEMPLATE(...) \ - MDSPAN_IMPL_TRAIT(std::is_same, fold_compatibility_impl::fold_bools<(__VA_ARGS__)..., true>, fold_compatibility_impl::fold_bools) +} // namespace fold_compatibility_impl + +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE + +#define MDSPAN_IMPL_FOLD_AND(...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl:: \ + fold_right_and_impl((__VA_ARGS__)...) +#define MDSPAN_IMPL_FOLD_OR(...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_right_or_impl( \ + (__VA_ARGS__)...) +#define MDSPAN_IMPL_FOLD_ASSIGN_LEFT(INIT, ...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl:: \ + fold_left_assign_impl(INIT, (__VA_ARGS__)...) +#define MDSPAN_IMPL_FOLD_ASSIGN_RIGHT(PACK, ...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl:: \ + fold_right_assign_impl((PACK)..., __VA_ARGS__) +#define MDSPAN_IMPL_FOLD_TIMES_RIGHT(PACK, ...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl:: \ + fold_right_times_impl((PACK)..., __VA_ARGS__) +#define MDSPAN_IMPL_FOLD_PLUS_RIGHT(PACK, ...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl:: \ + fold_right_plus_impl((PACK)..., __VA_ARGS__) +#define MDSPAN_IMPL_FOLD_COMMA(...) \ + MDSPAN_IMPL_STANDARD_NAMESPACE::fold_compatibility_impl::fold_comma_impl( \ + (__VA_ARGS__)...) + +#define MDSPAN_IMPL_FOLD_AND_TEMPLATE(...) \ + MDSPAN_IMPL_TRAIT( \ + std::is_same, \ + fold_compatibility_impl::fold_bools<(__VA_ARGS__)..., true>, \ + fold_compatibility_impl::fold_bools) #endif @@ -677,9 +679,9 @@ struct fold_bools; // {{{1 #if MDSPAN_IMPL_USE_VARIABLE_TEMPLATES -# define MDSPAN_IMPL_TRAIT(TRAIT, ...) TRAIT##_v<__VA_ARGS__> +#define MDSPAN_IMPL_TRAIT(TRAIT, ...) TRAIT##_v<__VA_ARGS__> #else -# define MDSPAN_IMPL_TRAIT(TRAIT, ...) TRAIT<__VA_ARGS__>::value +#define MDSPAN_IMPL_TRAIT(TRAIT, ...) TRAIT<__VA_ARGS__>::value #endif // end Variable template compatibility }}}1 @@ -689,23 +691,23 @@ struct fold_bools; // {{{1 #if MDSPAN_IMPL_USE_CONSTEXPR_14 -# define MDSPAN_IMPL_CONSTEXPR_14 constexpr +#define MDSPAN_IMPL_CONSTEXPR_14 constexpr // Workaround for a bug (I think?) in EDG frontends -# ifdef __EDG__ -# define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED -# else -# define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED constexpr -# endif +#ifdef __EDG__ +#define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED +#else +#define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED constexpr +#endif #else -# define MDSPAN_IMPL_CONSTEXPR_14 -# define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED +#define MDSPAN_IMPL_CONSTEXPR_14 +#define MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED #endif // end Pre-C++14 constexpr }}}1 //============================================================================== #if MDSPAN_IMPL_USE_IF_CONSTEXPR_17 -# define MDSPAN_IMPL_IF_CONSTEXPR_17 constexpr +#define MDSPAN_IMPL_IF_CONSTEXPR_17 constexpr #else -# define MDSPAN_IMPL_IF_CONSTEXPR_17 +#define MDSPAN_IMPL_IF_CONSTEXPR_17 #endif diff --git a/include/experimental/__p0009_bits/mdspan.hpp b/include/experimental/__p0009_bits/mdspan.hpp index bc473246..6a80d300 100644 --- a/include/experimental/__p0009_bits/mdspan.hpp +++ b/include/experimental/__p0009_bits/mdspan.hpp @@ -28,80 +28,95 @@ #include namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -template < - class ElementType, - class Extents, - class LayoutPolicy = layout_right, - class AccessorPolicy = default_accessor -> -class mdspan -{ -private: +template > +class mdspan { + private: static_assert(detail::impl_is_extents_v, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's Extents template parameter must be a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - static_assert(std::is_same::value, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's ElementType template parameter must be the same as its AccessorPolicy::element_type."); - - // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::mdspan's Extents template parameter must be a " + "specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::extents."); + static_assert( + std::is_same::value, + MDSPAN_IMPL_STANDARD_NAMESPACE_STRING + "::mdspan's ElementType template parameter must be the same as its " + "AccessorPolicy::element_type."); + + // Workaround for non-deducibility of the index sequence template parameter if + // it's given at the top level template struct deduction_workaround; template - struct deduction_workaround> - { - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - size_t size(mdspan const& self) noexcept { - return MDSPAN_IMPL_FOLD_TIMES_RIGHT((self.mapping_ref().extents().extent(Idxs)), /* * ... * */ size_t(1)); + struct deduction_workaround> { + MDSPAN_FORCE_INLINE_FUNCTION static constexpr size_t size( + mdspan const& self) noexcept { + return MDSPAN_IMPL_FOLD_TIMES_RIGHT( + (self.mapping_ref().extents().extent(Idxs)), /* * ... * */ size_t(1)); } - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - bool empty(mdspan const& self) noexcept { - return (self.rank()>0) && MDSPAN_IMPL_FOLD_OR((self.mapping_ref().extents().extent(Idxs)==index_type(0))); + MDSPAN_FORCE_INLINE_FUNCTION static constexpr bool empty( + mdspan const& self) noexcept { + return (self.rank() > 0) && + MDSPAN_IMPL_FOLD_OR( + (self.mapping_ref().extents().extent(Idxs) == index_type(0))); } template - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - ReferenceType callop(mdspan const& self, const std::array& indices) noexcept { - return self.accessor_ref().access(self.ptr_ref(), self.mapping_ref()(indices[Idxs]...)); + MDSPAN_FORCE_INLINE_FUNCTION static constexpr ReferenceType callop( + mdspan const& self, const std::array& indices) noexcept { + return self.accessor_ref().access(self.ptr_ref(), + self.mapping_ref()(indices[Idxs]...)); } #ifdef __cpp_lib_span template - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - ReferenceType callop(mdspan const& self, const std::span& indices) noexcept { - return self.accessor_ref().access(self.ptr_ref(), self.mapping_ref()(indices[Idxs]...)); + MDSPAN_FORCE_INLINE_FUNCTION static constexpr ReferenceType callop( + mdspan const& self, const std::span& indices) noexcept { + return self.accessor_ref().access(self.ptr_ref(), + self.mapping_ref()(indices[Idxs]...)); } #endif }; -public: - + public: //-------------------------------------------------------------------------------- // Domain and codomain types - using extents_type = Extents; - using layout_type = LayoutPolicy; - using accessor_type = AccessorPolicy; - using mapping_type = typename layout_type::template mapping; - using element_type = ElementType; - using value_type = std::remove_cv_t; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; + using extents_type = Extents; + using layout_type = LayoutPolicy; + using accessor_type = AccessorPolicy; + using mapping_type = typename layout_type::template mapping; + using element_type = ElementType; + using value_type = std::remove_cv_t; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; using data_handle_type = typename accessor_type::data_handle_type; - using reference = typename accessor_type::reference; - - MDSPAN_INLINE_FUNCTION static constexpr size_t rank() noexcept { return extents_type::rank(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent(size_t r) noexcept { return extents_type::static_extent(r); } - MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return mapping_ref().extents().extent(r); } + using reference = typename accessor_type::reference; -private: - - // Can't use defaulted parameter in the deduction_workaround template because of a bug in MSVC warning C4348. - using deduction_workaround_impl = deduction_workaround>; + MDSPAN_INLINE_FUNCTION static constexpr size_t rank() noexcept { + return extents_type::rank(); + } + MDSPAN_INLINE_FUNCTION static constexpr size_t rank_dynamic() noexcept { + return extents_type::rank_dynamic(); + } + MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent( + size_t r) noexcept { + return extents_type::static_extent(r); + } + MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { + return mapping_ref().extents().extent(r); + } - using map_acc_pair_t = detail::impl_compressed_pair; + private: + // Can't use defaulted parameter in the deduction_workaround template because + // of a bug in MSVC warning C4348. + using deduction_workaround_impl = + deduction_workaround>; -public: + using map_acc_pair_t = + detail::impl_compressed_pair; + public: //-------------------------------------------------------------------------------- // [mdspan.basic.cons], mdspan constructors, assignment, and destructor @@ -110,106 +125,127 @@ class mdspan #else MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan() requires( - // nvhpc has a bug where using just rank_dynamic() here doesn't work ... - (extents_type::rank_dynamic() > 0) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, data_handle_type) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, mapping_type) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) - ) = default; + // nvhpc has a bug where using just rank_dynamic() here doesn't + // work ... + (extents_type::rank_dynamic() > 0) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, + data_handle_type) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, + mapping_type) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type)) + = default; #endif MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(const mdspan&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(mdspan&&) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(mdspan&&) = default; MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - ((sizeof...(SizeTypes) == rank()) || (sizeof...(SizeTypes) == rank_dynamic())) && - (detail::are_valid_indices()) && - MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) - ) - ) + class... SizeTypes, + /* requires */ (((sizeof...(SizeTypes) == rank()) || + (sizeof...(SizeTypes) == rank_dynamic())) && + (detail::are_valid_indices()) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + extents_type) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, + accessor_type))) MDSPAN_INLINE_FUNCTION explicit constexpr mdspan(data_handle_type p, SizeTypes... dynamic_extents) - // TODO @proposal-bug shouldn't I be allowed to do `move(p)` here? - : m_members(std::move(p), map_acc_pair_t(mapping_type(extents_type(static_cast(std::move(dynamic_extents))...)), accessor_type())) - { } + // TODO @proposal-bug shouldn't I be allowed to do `move(p)` here? + : m_members( + std::move(p), + map_acc_pair_t(mapping_type(extents_type(static_cast( + std::move(dynamic_extents))...)), + accessor_type())) {} MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) && - ((N == rank()) || (N == rank_dynamic())) && - MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) - ) - ) + class SizeType, size_t N, + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, + const SizeType&) && + ((N == rank()) || (N == rank_dynamic())) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type))) MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic()) MDSPAN_INLINE_FUNCTION - constexpr mdspan(data_handle_type p, const std::array& dynamic_extents) - : m_members(std::move(p), map_acc_pair_t(mapping_type(extents_type(dynamic_extents)), accessor_type())) - { } + constexpr mdspan(data_handle_type p, + const std::array& dynamic_extents) + : m_members(std::move(p), + map_acc_pair_t(mapping_type(extents_type(dynamic_extents)), + accessor_type())) {} #ifdef __cpp_lib_span MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) && - ((N == rank()) || (N == rank_dynamic())) && - MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type) && - MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) - ) - ) + class SizeType, size_t N, + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, + const SizeType&) && + ((N == rank()) || (N == rank_dynamic())) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type) && + MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type))) MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic()) MDSPAN_INLINE_FUNCTION constexpr mdspan(data_handle_type p, std::span dynamic_extents) - : m_members(std::move(p), map_acc_pair_t(mapping_type(extents_type(as_const(dynamic_extents))), accessor_type())) - { } + : m_members(std::move(p), + map_acc_pair_t( + mapping_type(extents_type(as_const(dynamic_extents))), + accessor_type())) {} #endif MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdspan, (data_handle_type p, const extents_type& exts), , - /* requires */ (MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) && - MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, const extents_type&)) - ) : m_members(std::move(p), map_acc_pair_t(mapping_type(exts), accessor_type())) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdspan, (data_handle_type p, const mapping_type& m), , - /* requires */ (MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type)) - ) : m_members(std::move(p), map_acc_pair_t(m, accessor_type())) - { } + (MDSPAN_INLINE_FUNCTION constexpr), mdspan, + (data_handle_type p, const extents_type& exts), , + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_default_constructible, accessor_type) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + const extents_type&))) + : m_members(std::move(p), + map_acc_pair_t(mapping_type(exts), accessor_type())) {} + + MDSPAN_FUNCTION_REQUIRES((MDSPAN_INLINE_FUNCTION constexpr), mdspan, + (data_handle_type p, const mapping_type& m), , + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_default_constructible, + accessor_type))) + : m_members(std::move(p), map_acc_pair_t(m, accessor_type())) {} MDSPAN_INLINE_FUNCTION - constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a) - : m_members(std::move(p), map_acc_pair_t(m, a)) - { } + constexpr mdspan(data_handle_type p, const mapping_type& m, + const accessor_type& a) + : m_members(std::move(p), map_acc_pair_t(m, a)) {} MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessor, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, const typename OtherLayoutPolicy::template mapping&) && - MDSPAN_IMPL_TRAIT(std::is_constructible, accessor_type, const OtherAccessor&) - ) - ) + class OtherElementType, class OtherExtents, class OtherLayoutPolicy, + class OtherAccessor, + /* requires */ + (MDSPAN_IMPL_TRAIT( + std::is_constructible, mapping_type, + const typename OtherLayoutPolicy::template mapping&) && + MDSPAN_IMPL_TRAIT(std::is_constructible, accessor_type, + const OtherAccessor&))) MDSPAN_CONDITIONAL_EXPLICIT( - !MDSPAN_IMPL_TRAIT(std::is_convertible, const typename OtherLayoutPolicy::template mapping&, mapping_type) || - !MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherAccessor&, accessor_type) - ) + !MDSPAN_IMPL_TRAIT( + std::is_convertible, + const typename OtherLayoutPolicy::template mapping&, + mapping_type) || + !MDSPAN_IMPL_TRAIT(std::is_convertible, const OtherAccessor&, + accessor_type)) MDSPAN_INLINE_FUNCTION - constexpr mdspan(const mdspan& other) - : m_members(other.ptr_ref(), map_acc_pair_t(other.mapping_ref(), other.accessor_ref())) - { - static_assert(MDSPAN_IMPL_TRAIT(std::is_constructible, data_handle_type, typename OtherAccessor::data_handle_type),"Incompatible data_handle_type for mdspan construction"); - static_assert(MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents),"Incompatible extents for mdspan construction"); - /* - * TODO: Check precondition - * For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true. - */ + constexpr mdspan(const mdspan& other) + : m_members(other.ptr_ref(), + map_acc_pair_t(other.mapping_ref(), other.accessor_ref())) { + static_assert(MDSPAN_IMPL_TRAIT(std::is_constructible, data_handle_type, + typename OtherAccessor::data_handle_type), + "Incompatible data_handle_type for mdspan construction"); + static_assert( + MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents), + "Incompatible extents for mdspan construction"); + /* + * TODO: Check precondition + * For each rank index r of extents_type, static_extent(r) == dynamic_extent + * || static_extent(r) == other.extent(r) is true. + */ } /* Might need this on NVIDIA? @@ -217,175 +253,171 @@ class mdspan ~mdspan() = default; */ - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mdspan& operator=(const mdspan&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mdspan& operator=(mdspan&&) = default; - + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mdspan& + operator=(const mdspan&) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mdspan& + operator=(mdspan&&) = default; //-------------------------------------------------------------------------------- - // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to access codomain element + // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to + // access codomain element MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - extents_type::rank() == sizeof...(SizeTypes) && - (detail::are_valid_indices()) - ) - ) - constexpr reference at(SizeTypes... indices) const - { + class... SizeTypes, + /* requires */ (extents_type::rank() == sizeof...(SizeTypes) && + (detail::are_valid_indices()))) + constexpr reference at(SizeTypes... indices) const { size_t r = 0; for (const auto& index : {indices...}) { if (is_index_oor(index, mapping_ref().extents().extent(r))) { throw std::out_of_range( - "mdspan::at(...," + std::to_string(index) + ",...) out-of-range at rank index " + std::to_string(r) + - " for mdspan with extent {...," + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); + "mdspan::at(...," + std::to_string(index) + + ",...) out-of-range at rank index " + std::to_string(r) + + " for mdspan with extent {...," + + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); } ++r; } - return accessor_ref().access(ptr_ref(), mapping_ref()(static_cast(std::move(indices))...)); + return accessor_ref().access( + ptr_ref(), + mapping_ref()(static_cast(std::move(indices))...)); } MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - constexpr reference at(const std::array& indices) const - { + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) + constexpr reference at(const std::array& indices) const { for (size_t r = 0; r < indices.size(); ++r) { if (is_index_oor(indices[r], mapping_ref().extents().extent(r))) { throw std::out_of_range( - "mdspan::at({...," + std::to_string(indices[r]) + ",...}) out-of-range at rank index " + std::to_string(r) + - " for mdspan with extent {...," + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); + "mdspan::at({...," + std::to_string(indices[r]) + + ",...}) out-of-range at rank index " + std::to_string(r) + + " for mdspan with extent {...," + + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); } } - return deduction_workaround_impl::template callop(*this, indices); + return deduction_workaround_impl::template callop(*this, + indices); } - #ifdef __cpp_lib_span +#ifdef __cpp_lib_span MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - constexpr reference at(std::span indices) const - { + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) + constexpr reference at(std::span indices) const { for (size_t r = 0; r < indices.size(); ++r) { if (is_index_oor(indices[r], mapping_ref().extents().extent(r))) { throw std::out_of_range( - "mdspan::at({...," + std::to_string(indices[r]) + ",...}) out-of-range at rank index " + std::to_string(r) + - " for mdspan with extent {...," + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); + "mdspan::at({...," + std::to_string(indices[r]) + + ",...}) out-of-range at rank index " + std::to_string(r) + + " for mdspan with extent {...," + + std::to_string(mapping_ref().extents().extent(r)) + ",...}"); } } - return deduction_workaround_impl::template callop(*this, indices); + return deduction_workaround_impl::template callop(*this, + indices); } - #endif // __cpp_lib_span +#endif // __cpp_lib_span - #if MDSPAN_USE_BRACKET_OPERATOR +#if MDSPAN_USE_BRACKET_OPERATOR MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - extents_type::rank() == sizeof...(SizeTypes) && - (detail::are_valid_indices()) - ) - ) + class... SizeTypes, + /* requires */ (extents_type::rank() == sizeof...(SizeTypes) && + (detail::are_valid_indices()))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](SizeTypes... indices) const - { - return accessor_ref().access(ptr_ref(), mapping_ref()(static_cast(std::move(indices))...)); + constexpr reference operator[](SizeTypes... indices) const { + return accessor_ref().access( + ptr_ref(), + mapping_ref()(static_cast(std::move(indices))...)); } - #endif +#endif MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](const std::array& indices) const - { - return deduction_workaround_impl::template callop(*this, indices); + constexpr reference operator[]( + const std::array& indices) const { + return deduction_workaround_impl::template callop(*this, + indices); } - #ifdef __cpp_lib_span +#ifdef __cpp_lib_span MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](std::span indices) const - { - return deduction_workaround_impl::template callop(*this, indices); + constexpr reference operator[](std::span indices) const { + return deduction_workaround_impl::template callop(*this, + indices); } - #endif // __cpp_lib_span +#endif // __cpp_lib_span - #if !MDSPAN_USE_BRACKET_OPERATOR +#if !MDSPAN_USE_BRACKET_OPERATOR MDSPAN_TEMPLATE_REQUIRES( - class Index, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, Index, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, Index) && - extents_type::rank() == 1 - ) - ) + class Index, + /* requires */ ( + MDSPAN_IMPL_TRAIT(std::is_convertible, Index, index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, Index) && + extents_type::rank() == 1)) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](Index idx) const - { - return accessor_ref().access(ptr_ref(), mapping_ref()(static_cast(std::move(idx)))); + constexpr reference operator[](Index idx) const { + return accessor_ref().access( + ptr_ref(), mapping_ref()(static_cast(std::move(idx)))); } - #endif +#endif - #if MDSPAN_USE_PAREN_OPERATOR +#if MDSPAN_USE_PAREN_OPERATOR MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - extents_type::rank() == sizeof...(SizeTypes) && - (detail::are_valid_indices()) - ) - ) + class... SizeTypes, + /* requires */ (extents_type::rank() == sizeof...(SizeTypes) && + (detail::are_valid_indices()))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(SizeTypes... indices) const - { - return accessor_ref().access(ptr_ref(), mapping_ref()(static_cast(std::move(indices))...)); + constexpr reference operator()(SizeTypes... indices) const { + return accessor_ref().access( + ptr_ref(), + mapping_ref()(static_cast(std::move(indices))...)); } MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(const std::array& indices) const - { - return deduction_workaround_impl::template callop(*this, indices); + constexpr reference operator()( + const std::array& indices) const { + return deduction_workaround_impl::template callop(*this, + indices); } - #ifdef __cpp_lib_span +#ifdef __cpp_lib_span MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(std::span indices) const - { - return deduction_workaround_impl::template callop(*this, indices); + constexpr reference operator()(std::span indices) const { + return deduction_workaround_impl::template callop(*this, + indices); } - #endif // __cpp_lib_span - #endif // MDSPAN_USE_PAREN_OPERATOR +#endif // __cpp_lib_span +#endif // MDSPAN_USE_PAREN_OPERATOR MDSPAN_INLINE_FUNCTION constexpr size_type size() const noexcept { return static_cast(deduction_workaround_impl::size(*this)); @@ -397,62 +429,106 @@ class mdspan MDSPAN_INLINE_FUNCTION friend constexpr void swap(mdspan& x, mdspan& y) noexcept { - // can't call the std::swap inside on HIP - #if !defined(MDSPAN_IMPL_HAS_HIP) && !defined(MDSPAN_IMPL_HAS_CUDA) +// can't call the std::swap inside on HIP +#if !defined(MDSPAN_IMPL_HAS_HIP) && !defined(MDSPAN_IMPL_HAS_CUDA) using std::swap; swap(x.ptr_ref(), y.ptr_ref()); swap(x.mapping_ref(), y.mapping_ref()); swap(x.accessor_ref(), y.accessor_ref()); - #else +#else mdspan tmp = y; - y = x; - x = tmp; - #endif + y = x; + x = tmp; +#endif } //-------------------------------------------------------------------------------- - // [mdspan.basic.domobs], mdspan observers of the domain multidimensional index space - + // [mdspan.basic.domobs], mdspan observers of the domain multidimensional + // index space - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return mapping_ref().extents(); } - MDSPAN_INLINE_FUNCTION constexpr const data_handle_type& data_handle() const noexcept { return ptr_ref(); } - MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() const noexcept { return mapping_ref(); } - MDSPAN_INLINE_FUNCTION constexpr const accessor_type& accessor() const noexcept { return accessor_ref(); } + MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() + const noexcept { + return mapping_ref().extents(); + } + MDSPAN_INLINE_FUNCTION constexpr const data_handle_type& data_handle() + const noexcept { + return ptr_ref(); + } + MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() + const noexcept { + return mapping_ref(); + } + MDSPAN_INLINE_FUNCTION constexpr const accessor_type& accessor() + const noexcept { + return accessor_ref(); + } //-------------------------------------------------------------------------------- // [mdspan.basic.obs], mdspan observers of the mapping - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); } - - MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const { return mapping_ref().is_unique(); } - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const { return mapping_ref().is_exhaustive(); } - MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const { return mapping_ref().is_strided(); } - MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return mapping_ref().stride(r); } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() { + return mapping_type::is_always_unique(); + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() { + return mapping_type::is_always_exhaustive(); + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() { + return mapping_type::is_always_strided(); + } -private: + MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const { + return mapping_ref().is_unique(); + } + MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const { + return mapping_ref().is_exhaustive(); + } + MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const { + return mapping_ref().is_strided(); + } + MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { + return mapping_ref().stride(r); + } + private: detail::impl_compressed_pair m_members{}; - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 data_handle_type& ptr_ref() noexcept { return m_members.first(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr data_handle_type const& ptr_ref() const noexcept { return m_members.first(); } - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 mapping_type& mapping_ref() noexcept { return m_members.second().first(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const& mapping_ref() const noexcept { return m_members.second().first(); } - MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 accessor_type& accessor_ref() noexcept { return m_members.second().second(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type const& accessor_ref() const noexcept { return m_members.second().second(); } - + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 data_handle_type& + ptr_ref() noexcept { + return m_members.first(); + } + MDSPAN_FORCE_INLINE_FUNCTION constexpr data_handle_type const& ptr_ref() + const noexcept { + return m_members.first(); + } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 mapping_type& + mapping_ref() noexcept { + return m_members.second().first(); + } + MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const& mapping_ref() + const noexcept { + return m_members.second().first(); + } + MDSPAN_FORCE_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 accessor_type& + accessor_ref() noexcept { + return m_members.second().second(); + } + MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type const& accessor_ref() + const noexcept { + return m_members.second().second(); + } + MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, index_type) && - MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION constexpr bool is_index_oor(SizeType index, index_type extent) const noexcept { + class SizeType, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_convertible, const SizeType&, + index_type) && + MDSPAN_IMPL_TRAIT(std::is_nothrow_constructible, + index_type, const SizeType&))) + MDSPAN_FORCE_INLINE_FUNCTION constexpr bool is_index_oor( + SizeType index, index_type extent) const noexcept { // Check for negative indices - if MDSPAN_IMPL_IF_CONSTEXPR_17 (MDSPAN_IMPL_TRAIT(std::is_signed, SizeType)) { - if(index < 0) { + if MDSPAN_IMPL_IF_CONSTEXPR_17 (MDSPAN_IMPL_TRAIT(std::is_signed, + SizeType)) { + if (index < 0) { return true; } } @@ -461,54 +537,66 @@ class mdspan template friend class mdspan; - }; #if defined(MDSPAN_IMPL_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) MDSPAN_TEMPLATE_REQUIRES( - class ElementType, class... SizeTypes, - /* requires */ MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_convertible, SizeTypes, size_t) /* && ... */) && - (sizeof...(SizeTypes) > 0) -) -MDSPAN_DEDUCTION_GUIDE explicit mdspan(ElementType*, SizeTypes...) - -> mdspan>; - -MDSPAN_TEMPLATE_REQUIRES( - class Pointer, - (MDSPAN_IMPL_TRAIT(std::is_pointer, std::remove_reference_t)) -) -MDSPAN_DEDUCTION_GUIDE mdspan(Pointer&&) -> mdspan>, extents>; - -MDSPAN_TEMPLATE_REQUIRES( - class CArray, - (MDSPAN_IMPL_TRAIT(std::is_array, CArray) && (std::rank_v == 1)) -) -MDSPAN_DEDUCTION_GUIDE mdspan(CArray&) -> mdspan, extents>>; + class ElementType, class... SizeTypes, + /* requires */ + MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_convertible, SizeTypes, + size_t) /* && ... */) && + (sizeof...(SizeTypes) > 0)) +MDSPAN_DEDUCTION_GUIDE explicit mdspan(ElementType*, SizeTypes...) -> mdspan< + ElementType, + ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents>; + +MDSPAN_TEMPLATE_REQUIRES(class Pointer, + (MDSPAN_IMPL_TRAIT(std::is_pointer, + std::remove_reference_t))) +MDSPAN_DEDUCTION_GUIDE mdspan(Pointer&&) + -> mdspan>, + extents>; + +MDSPAN_TEMPLATE_REQUIRES(class CArray, + (MDSPAN_IMPL_TRAIT(std::is_array, CArray) && + (std::rank_v == 1))) +MDSPAN_DEDUCTION_GUIDE mdspan(CArray&) + -> mdspan, + extents>>; template MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const ::std::array&) - -> mdspan>; + -> mdspan>; #ifdef __cpp_lib_span template MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, ::std::span) - -> mdspan>; + -> mdspan>; #endif -// This one is necessary because all the constructors take `data_handle_type`s, not -// `ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which -// seems to throw off automatic deduction guides. +// This one is necessary because all the constructors take `data_handle_type`s, +// not `ElementType*`s, and `data_handle_type` is taken from +// `accessor_type::data_handle_type`, which seems to throw off automatic +// deduction guides. template -MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const extents&) - -> mdspan>; +MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, + const extents&) + -> mdspan>; template MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const MappingType&) - -> mdspan; + -> mdspan; template -MDSPAN_DEDUCTION_GUIDE mdspan(const typename AccessorType::data_handle_type, const MappingType&, const AccessorType&) - -> mdspan; +MDSPAN_DEDUCTION_GUIDE mdspan(const typename AccessorType::data_handle_type, + const MappingType&, const AccessorType&) + -> mdspan; #endif -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/no_unique_address.hpp b/include/experimental/__p0009_bits/no_unique_address.hpp index b7b07c60..8ddb1d54 100644 --- a/include/experimental/__p0009_bits/no_unique_address.hpp +++ b/include/experimental/__p0009_bits/no_unique_address.hpp @@ -42,19 +42,19 @@ template struct no_unique_address_emulation< T, Disambiguator, std::enable_if_t> : + // If the type isn't trivially destructible, its destructor + // won't be called at the right time, so don't use this + // specialization + MDSPAN_IMPL_TRAIT(std::is_trivially_destructible, T)>> : #ifdef MDSPAN_IMPL_COMPILER_MSVC // MSVC doesn't allow you to access public static member functions of a type // when you *happen* to privately inherit from that type. protected #else - // But we still want this to be private if possible so that we don't accidentally - // access members of T directly rather than calling ref() first, which wouldn't - // work if T happens to be stateful and thus we're using the unspecialized definition - // of no_unique_address_emulation above. + // But we still want this to be private if possible so that we don't + // accidentally access members of T directly rather than calling ref() + // first, which wouldn't work if T happens to be stateful and thus we're + // using the unspecialized definition of no_unique_address_emulation above. private #endif T { @@ -75,23 +75,24 @@ struct no_unique_address_emulation< constexpr no_unique_address_emulation( no_unique_address_emulation &&) noexcept = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED no_unique_address_emulation & - operator=(no_unique_address_emulation const &) noexcept = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED no_unique_address_emulation &operator=( + no_unique_address_emulation const &) noexcept = default; MDSPAN_INLINE_FUNCTION_DEFAULTED - MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED no_unique_address_emulation & - operator=(no_unique_address_emulation &&) noexcept = default; + MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED no_unique_address_emulation &operator=( + no_unique_address_emulation &&) noexcept = default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~no_unique_address_emulation() noexcept = default; // Explicitly make this not a reference so that the copy or move // constructor still gets called. MDSPAN_INLINE_FUNCTION - explicit constexpr no_unique_address_emulation(T const& v) noexcept : T(v) {} + explicit constexpr no_unique_address_emulation(T const &v) noexcept : T(v) {} MDSPAN_INLINE_FUNCTION - explicit constexpr no_unique_address_emulation(T&& v) noexcept : T(::std::move(v)) {} + explicit constexpr no_unique_address_emulation(T &&v) noexcept + : T(::std::move(v)) {} }; //============================================================================== -} // end namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace detail +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/trait_backports.hpp b/include/experimental/__p0009_bits/trait_backports.hpp index 70651a7c..5f3dc5fd 100644 --- a/include/experimental/__p0009_bits/trait_backports.hpp +++ b/include/experimental/__p0009_bits/trait_backports.hpp @@ -20,7 +20,7 @@ #include "config.hpp" #include -#include // integer_sequence +#include // integer_sequence //============================================================================== // {{{1 @@ -30,8 +30,10 @@ #if MDSPAN_IMPL_USE_VARIABLE_TEMPLATES namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -#define MDSPAN_IMPL_BACKPORT_TRAIT(TRAIT) \ - template MDSPAN_IMPL_INLINE_VARIABLE constexpr auto TRAIT##_v = TRAIT::value; +#define MDSPAN_IMPL_BACKPORT_TRAIT(TRAIT) \ + template \ + MDSPAN_IMPL_INLINE_VARIABLE constexpr auto TRAIT##_v = \ + TRAIT::value; MDSPAN_IMPL_BACKPORT_TRAIT(is_assignable) MDSPAN_IMPL_BACKPORT_TRAIT(is_constructible) @@ -44,11 +46,11 @@ MDSPAN_IMPL_BACKPORT_TRAIT(is_void) #undef MDSPAN_IMPL_BACKPORT_TRAIT -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE -#endif // MDSPAN_IMPL_USE_VARIABLE_TEMPLATES +#endif // MDSPAN_IMPL_USE_VARIABLE_TEMPLATES -#endif // MDSPAN_IMPL_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS +#endif // MDSPAN_IMPL_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS // end Variable template trait backports (e.g., is_void_v) }}}1 //============================================================================== @@ -56,7 +58,8 @@ MDSPAN_IMPL_BACKPORT_TRAIT(is_void) //============================================================================== // {{{1 -#if !defined(MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14) || !MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 +#if !defined(MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14) || \ + !MDSPAN_IMPL_USE_INTEGER_SEQUENCE_14 namespace MDSPAN_IMPL_STANDARD_NAMESPACE { @@ -75,29 +78,29 @@ template struct __make_int_seq_impl; template -struct __make_int_seq_impl> -{ +struct __make_int_seq_impl> { using type = integer_sequence; }; template -struct __make_int_seq_impl< - T, N, I, integer_sequence -> : __make_int_seq_impl> -{ }; +struct __make_int_seq_impl> + : __make_int_seq_impl> {}; -} // end namespace __detail +} // end namespace __detail template -using make_integer_sequence = typename __detail::__make_int_seq_impl>::type; +using make_integer_sequence = + typename __detail::__make_int_seq_impl>::type; template -using make_index_sequence = typename __detail::__make_int_seq_impl>::type; +using make_index_sequence = + typename __detail::__make_int_seq_impl>::type; template using index_sequence_for = make_index_sequence; -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE #endif @@ -107,26 +110,28 @@ using index_sequence_for = make_index_sequence; //============================================================================== // {{{1 -#if !defined(MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES) || !MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES +#if !defined(MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES) || \ + !MDSPAN_IMPL_USE_STANDARD_TRAIT_ALIASES namespace MDSPAN_IMPL_STANDARD_NAMESPACE { #define MDSPAN_IMPL_BACKPORT_TRAIT_ALIAS(TRAIT) \ - template using TRAIT##_t = typename TRAIT::type; + template \ + using TRAIT##_t = typename TRAIT::type; MDSPAN_IMPL_BACKPORT_TRAIT_ALIAS(remove_cv) MDSPAN_IMPL_BACKPORT_TRAIT_ALIAS(remove_reference) -template +template using enable_if_t = typename enable_if<_B, T>::type; #undef MDSPAN_IMPL_BACKPORT_TRAIT_ALIAS -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE #endif // end standard trait aliases }}}1 //============================================================================== -#endif //MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_ +#endif // MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_ diff --git a/include/experimental/__p0009_bits/type_list.hpp b/include/experimental/__p0009_bits/type_list.hpp index 23d58562..39d68af9 100644 --- a/include/experimental/__p0009_bits/type_list.hpp +++ b/include/experimental/__p0009_bits/type_list.hpp @@ -15,7 +15,7 @@ //@HEADER #include "macros.hpp" -#include "trait_backports.hpp" // make_index_sequence +#include "trait_backports.hpp" // make_index_sequence namespace MDSPAN_IMPL_STANDARD_NAMESPACE { @@ -23,14 +23,19 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace detail { -template struct type_list { static constexpr auto size = sizeof...(Ts); }; +template +struct type_list { + static constexpr auto size = sizeof...(Ts); +}; // Implementation of type_list at() that's heavily optimized for small typelists -template struct type_at; -template > struct type_at_large_impl; +template +struct type_at; +template > +struct type_at_large_impl; template -struct type_at_entry { }; +struct type_at_entry {}; template struct type_at_assign_op_ignore_rest { @@ -47,16 +52,15 @@ struct type_at_assign_op_impl { }; template -struct type_at_large_impl, std::integer_sequence> - : decltype( - MDSPAN_IMPL_FOLD_ASSIGN_LEFT(type_at_assign_op_impl{}, /* = ... = */ type_at_entry{}) - ) -{ }; +struct type_at_large_impl, + std::integer_sequence> + : decltype(MDSPAN_IMPL_FOLD_ASSIGN_LEFT( + type_at_assign_op_impl{}, + /* = ... = */ type_at_entry{})) {}; template -struct type_at> - : type_at_large_impl> -{ }; +struct type_at> : type_at_large_impl> { +}; template struct type_at<0, type_list> { @@ -78,9 +82,8 @@ struct type_at<3, type_list> { using type = T3; }; - -} // namespace detail +} // namespace detail //============================================================================== -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p0009_bits/utility.hpp b/include/experimental/__p0009_bits/utility.hpp index 2ded4363..e1e5ffee 100644 --- a/include/experimental/__p0009_bits/utility.hpp +++ b/include/experimental/__p0009_bits/utility.hpp @@ -17,27 +17,22 @@ template using with_rank = std::integral_constant; template -MDSPAN_INLINE_FUNCTION -constexpr bool common_integral_compare(I1 x, I2 y) -{ - static_assert(std::is_integral::value && - std::is_integral::value, ""); +MDSPAN_INLINE_FUNCTION constexpr bool common_integral_compare(I1 x, I2 y) { + static_assert(std::is_integral::value && std::is_integral::value, ""); using I = std::common_type_t; return static_cast(x) == static_cast(y); } template -MDSPAN_INLINE_FUNCTION -constexpr bool rankwise_equal(with_rank<0>, const T1&, const T2&, F) -{ +MDSPAN_INLINE_FUNCTION constexpr bool rankwise_equal(with_rank<0>, const T1&, + const T2&, F) { return true; } template -MDSPAN_INLINE_FUNCTION -constexpr bool rankwise_equal(with_rank, const T1& x, const T2& y, F func) -{ +MDSPAN_INLINE_FUNCTION constexpr bool rankwise_equal(with_rank, const T1& x, + const T2& y, F func) { bool match = true; for (std::size_t r = 0; r < N; r++) { @@ -50,12 +45,9 @@ constexpr bool rankwise_equal(with_rank, const T1& x, const T2& y, F func) #if MDSPAN_HAS_CXX_17 inline #endif -constexpr struct -{ + constexpr struct { template - MDSPAN_INLINE_FUNCTION - constexpr auto operator()(const T& x, I i) const - { + MDSPAN_INLINE_FUNCTION constexpr auto operator()(const T& x, I i) const { return x.extent(i); } } extent; @@ -63,12 +55,9 @@ constexpr struct #if MDSPAN_HAS_CXX_17 inline #endif -constexpr struct -{ + constexpr struct { template - MDSPAN_INLINE_FUNCTION - constexpr auto operator()(const T& x, I i) const - { + MDSPAN_INLINE_FUNCTION constexpr auto operator()(const T& x, I i) const { return x.stride(i); } } stride; @@ -77,8 +66,8 @@ constexpr struct // the implicit conversion function and the call operator template struct integral_constant { - using value_type = T; - using type = integral_constant; + using value_type = T; + using type = integral_constant; static constexpr T value = v; @@ -88,10 +77,11 @@ struct integral_constant { // These interop functions work, because other than the value_type operator // everything of std::integral_constant works on device (defaulted functions) MDSPAN_FUNCTION - constexpr integral_constant(std::integral_constant) {} + constexpr integral_constant(std::integral_constant) {} - MDSPAN_FUNCTION constexpr operator std::integral_constant() const noexcept { - return std::integral_constant{}; + MDSPAN_FUNCTION constexpr operator std::integral_constant() + const noexcept { + return std::integral_constant{}; } MDSPAN_FUNCTION constexpr operator value_type() const noexcept { @@ -106,9 +96,9 @@ struct integral_constant { // The tuple implementation only comes in play when using capabilities // such as submdspan which require C++17 anyway #if MDSPAN_HAS_CXX_17 -template +template struct tuple_member { - using type = T; + using type = T; static constexpr size_t idx = Idx; T val; MDSPAN_FUNCTION constexpr T& get() { return val; } @@ -117,59 +107,66 @@ struct tuple_member { // A helper class which will be used via a fold expression to // select the type with the correct Idx in a pack of tuple_member -template +template struct tuple_idx_matcher { using type = tuple_member; - template - MDSPAN_FUNCTION - constexpr auto operator | ([[maybe_unused]] Other v) const { - if constexpr (Idx == SearchIdx) { return *this; } - else { return v; } + template + MDSPAN_FUNCTION constexpr auto operator|([[maybe_unused]] Other v) const { + if constexpr (Idx == SearchIdx) { + return *this; + } else { + return v; + } } }; -template +template struct tuple_impl; -template -struct tuple_impl, Elements...>: public tuple_member ... { - +template +struct tuple_impl, Elements...> + : public tuple_member... { MDSPAN_FUNCTION - constexpr tuple_impl(Elements ... vals):tuple_member{vals}... {} + constexpr tuple_impl(Elements... vals) + : tuple_member{vals}... {} - template - MDSPAN_FUNCTION - constexpr auto& get() { - using base_t = decltype((tuple_idx_matcher() | ...) ); + template + MDSPAN_FUNCTION constexpr auto& get() { + using base_t = decltype((tuple_idx_matcher() | ...)); return base_t::type::get(); } - template - MDSPAN_FUNCTION - constexpr const auto& get() const { - using base_t = decltype((tuple_idx_matcher() | ...) ); + template + MDSPAN_FUNCTION constexpr const auto& get() const { + using base_t = decltype((tuple_idx_matcher() | ...)); return base_t::type::get(); } }; -// A simple tuple-like class for representing slices internally and is compatible with device code -// This doesn't support type access since we don't need it -// This is not meant as an external API -template -struct tuple: public tuple_impl()), Elements...> { +// A simple tuple-like class for representing slices internally and is +// compatible with device code This doesn't support type access since we don't +// need it This is not meant as an external API +template +struct tuple : public tuple_impl< + decltype(std::make_index_sequence()), + Elements...> { MDSPAN_FUNCTION - constexpr tuple(Elements ... vals):tuple_impl()), Elements ...>(vals ...) {} + constexpr tuple(Elements... vals) + : tuple_impl()), + Elements...>(vals...) {} }; -template -MDSPAN_FUNCTION -constexpr auto& get(tuple& vals) { return vals.template get(); } +template +MDSPAN_FUNCTION constexpr auto& get(tuple& vals) { + return vals.template get(); +} -template -MDSPAN_FUNCTION -constexpr const auto& get(const tuple& vals) { return vals.template get(); } +template +MDSPAN_FUNCTION constexpr const auto& get(const tuple& vals) { + return vals.template get(); +} -template -tuple(Elements ...) -> tuple; +template +tuple(Elements...) -> tuple; #endif #if MDSPAN_HAS_CXX_17 @@ -199,28 +196,27 @@ MDSPAN_INLINE_FUNCTION constexpr bool cmp_greater_equal(T t, U u) noexcept { template MDSPAN_INLINE_FUNCTION constexpr bool in_range(T t) noexcept { return cmp_greater_equal(t, std::numeric_limits::min()) && - cmp_less_equal(t, std::numeric_limits::max()); + cmp_less_equal(t, std::numeric_limits::max()); } -template +template MDSPAN_INLINE_FUNCTION constexpr bool check_mul_result_is_nonnegative_and_representable(T a, T b) { - if (b == 0 || a == 0) - return true; + if (b == 0 || a == 0) return true; if constexpr (std::is_signed_v) { - if ( a < 0 || b < 0 ) return false; + if (a < 0 || b < 0) return false; } return a <= std::numeric_limits::max() / b; return true; } #endif -} // namespace detail +} // namespace detail #if MDSPAN_HAS_CXX_17 inline #endif -constexpr struct mdspan_non_standard_tag { + constexpr struct mdspan_non_standard_tag { } mdspan_non_standard; -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p1684_bits/mdarray.hpp b/include/experimental/__p1684_bits/mdarray.hpp index 6f643a32..5fba0410 100644 --- a/include/experimental/__p1684_bits/mdarray.hpp +++ b/include/experimental/__p1684_bits/mdarray.hpp @@ -24,260 +24,283 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { namespace { - template - struct size_of_extents; - - template - struct size_of_extents> { - constexpr static size_t value() { - size_t size = 1; - for(size_t r=0; r::rank(); r++) - size *= extents::static_extent(r); - return size; - } - }; -} +template +struct size_of_extents; + +template +struct size_of_extents> { + constexpr static size_t value() { + size_t size = 1; + for (size_t r = 0; r < extents::rank(); r++) + size *= extents::static_extent(r); + return size; + } +}; +} // namespace namespace { - template - struct container_is_array : std::false_type { - template - static constexpr C construct(const M& m) { return C(m.required_span_size()); } - }; - template - struct container_is_array> : std::true_type { - template - static constexpr std::array construct(const M&) { return std::array(); } - }; -} - -template < - class ElementType, - class Extents, - class LayoutPolicy = layout_right, - class Container = std::vector -> -class mdarray { -private: - static_assert(::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::impl_is_extents_v, - MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING "::mdspan's Extents template parameter must be a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - -public: +template +struct container_is_array : std::false_type { + template + static constexpr C construct(const M& m) { + return C(m.required_span_size()); + } +}; +template +struct container_is_array> : std::true_type { + template + static constexpr std::array construct(const M&) { + return std::array(); + } +}; +} // namespace +template > +class mdarray { + private: + static_assert( + ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::impl_is_extents_v, + MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING + "::mdspan's Extents template parameter must be a specialization " + "of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); + + public: //-------------------------------------------------------------------------------- // Domain and codomain types - using extents_type = Extents; - using layout_type = LayoutPolicy; + using extents_type = Extents; + using layout_type = LayoutPolicy; using container_type = Container; - using mapping_type = typename layout_type::template mapping; - using element_type = ElementType; - using mdspan_type = mdspan; - using const_mdspan_type = mdspan; - using value_type = std::remove_cv_t; - using index_type = typename Extents::index_type; - using size_type = typename Extents::size_type; - using rank_type = typename Extents::rank_type; - using pointer = typename container_type::pointer; - using reference = typename container_type::reference; - using const_pointer = typename container_type::const_pointer; + using mapping_type = typename layout_type::template mapping; + using element_type = ElementType; + using mdspan_type = mdspan; + using const_mdspan_type = + mdspan; + using value_type = std::remove_cv_t; + using index_type = typename Extents::index_type; + using size_type = typename Extents::size_type; + using rank_type = typename Extents::rank_type; + using pointer = typename container_type::pointer; + using reference = typename container_type::reference; + using const_pointer = typename container_type::const_pointer; using const_reference = typename container_type::const_reference; -public: - + public: //-------------------------------------------------------------------------------- // [mdspan.basic.cons], mdspan constructors, assignment, and destructor #if !(MDSPAN_HAS_CXX_20) - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr), - mdarray, (), , - /* requires */ (extents_type::rank_dynamic()!=0)) {} + MDSPAN_FUNCTION_REQUIRES((MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr), + mdarray, (), , + /* requires */ (extents_type::rank_dynamic() != 0)) { + } #else - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray() requires(extents_type::rank_dynamic()!=0) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray() + requires(extents_type::rank_dynamic() != 0) + = default; #endif MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray(const mdarray&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray(mdarray&&) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray(mdarray&&) = default; // Constructors for container types constructible from a size MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices()) && - MDSPAN_IMPL_TRAIT( std::is_constructible, extents_type, SizeTypes...) && - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type) && - (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array::value) && - (extents_type::rank()>0 || extents_type::rank_dynamic()==0) - ) - ) + class... SizeTypes, + /* requires */ ( + (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices< + index_type, SizeTypes...>()) && + MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + SizeTypes...) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + extents_type) && + (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, size_t) || + container_is_array::value) && + (extents_type::rank() > 0 || extents_type::rank_dynamic() == 0))) MDSPAN_INLINE_FUNCTION explicit constexpr mdarray(SizeTypes... dynamic_extents) - : map_(extents_type(dynamic_extents...)), ctr_(container_is_array::construct(map_)) - { } + : map_(extents_type(dynamic_extents...)), + ctr_(container_is_array::construct(map_)) {} MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts), , - /* requires */ ((MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array::value) && - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(container_is_array::construct(map_)) - { } + (MDSPAN_INLINE_FUNCTION constexpr), mdarray, (const extents_type& exts), , + /* requires */ + ((MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, size_t) || + container_is_array::value) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type))) + : map_(exts), ctr_(container_is_array::construct(map_)) {} + + MDSPAN_FUNCTION_REQUIRES((MDSPAN_INLINE_FUNCTION constexpr), mdarray, + (const mapping_type& m), , + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_constructible, + container_type, size_t) || + container_is_array::value)) + : map_(m), ctr_(container_is_array::construct(map_)) {} MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const mapping_type& m), , - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array::value) - ) : map_(m), ctr_(container_is_array::construct(map_)) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts, const container_type& ctr), , - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(ctr) - { assert(ctr.size() >= static_cast(map_.required_span_size())); } + (MDSPAN_INLINE_FUNCTION constexpr), mdarray, + (const extents_type& exts, const container_type& ctr), , + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, extents_type))) + : map_(exts), ctr_(ctr) { + assert(ctr.size() >= static_cast(map_.required_span_size())); + } constexpr mdarray(const mapping_type& m, const container_type& ctr) - : map_(m), ctr_(ctr) - { assert(ctr.size() >= static_cast(map_.required_span_size())); } + : map_(m), ctr_(ctr) { + assert(ctr.size() >= static_cast(map_.required_span_size())); + } - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts, container_type&& ctr), , - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(std::move(ctr)) - { assert(ctr_.size() >= static_cast(map_.required_span_size())); } + MDSPAN_FUNCTION_REQUIRES((MDSPAN_INLINE_FUNCTION constexpr), mdarray, + (const extents_type& exts, container_type&& ctr), , + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_constructible, + mapping_type, extents_type))) + : map_(exts), ctr_(std::move(ctr)) { + assert(ctr_.size() >= static_cast(map_.required_span_size())); + } constexpr mdarray(const mapping_type& m, container_type&& ctr) - : map_(m), ctr_(std::move(ctr)) - { assert(ctr_.size() >= static_cast(map_.required_span_size())); } - + : map_(m), ctr_(std::move(ctr)) { + assert(ctr_.size() >= static_cast(map_.required_span_size())); + } MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherContainer, - /* requires */ ( - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, typename OtherLayoutPolicy::template mapping) && - MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, OtherContainer) - ) - ) + class OtherElementType, class OtherExtents, class OtherLayoutPolicy, + class OtherContainer, + /* requires */ + (MDSPAN_IMPL_TRAIT( + std::is_constructible, mapping_type, + typename OtherLayoutPolicy::template mapping) && + MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + OtherContainer))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mdarray& other) - : map_(other.mapping()), ctr_(other.container()) - { - static_assert( std::is_constructible::value, ""); + constexpr mdarray(const mdarray& other) + : map_(other.mapping()), ctr_(other.container()) { + static_assert(std::is_constructible::value, ""); } // Constructors for container types constructible from a size and allocator MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t, Alloc) && - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + size_t, Alloc) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + extents_type))) MDSPAN_INLINE_FUNCTION constexpr mdarray(const extents_type& exts, const Alloc& a) - : map_(exts), ctr_(map_.required_span_size(), a) - { } + : map_(exts), ctr_(map_.required_span_size(), a) {} MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + size_t, Alloc))) MDSPAN_INLINE_FUNCTION constexpr mdarray(const mapping_type& map, const Alloc& a) - : map_(map), ctr_(map_.required_span_size(), a) - { } + : map_(map), ctr_(map_.required_span_size(), a) {} - // Constructors for container types constructible from a container and allocator + // Constructors for container types constructible from a container and + // allocator MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, container_type, Alloc) && - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + container_type, Alloc) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + extents_type))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const extents_type& exts, const container_type& ctr, const Alloc& a) - : map_(exts), ctr_(ctr, a) - { assert(ctr_.size() >= static_cast(map_.required_span_size())); } + constexpr mdarray(const extents_type& exts, const container_type& ctr, + const Alloc& a) + : map_(exts), ctr_(ctr, a) { + assert(ctr_.size() >= static_cast(map_.required_span_size())); + } MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + size_t, Alloc))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mapping_type& map, const container_type& ctr, const Alloc& a) - : map_(map), ctr_(ctr, a) - { assert(ctr_.size() >= static_cast(map_.required_span_size())); } + constexpr mdarray(const mapping_type& map, const container_type& ctr, + const Alloc& a) + : map_(map), ctr_(ctr, a) { + assert(ctr_.size() >= static_cast(map_.required_span_size())); + } MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, container_type, Alloc) && - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + container_type, Alloc) && + MDSPAN_IMPL_TRAIT(std::is_constructible, mapping_type, + extents_type))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const extents_type& exts, container_type&& ctr, const Alloc& a) - : map_(exts), ctr_(std::move(ctr), a) - { assert(ctr_.size() >= static_cast(map_.required_span_size())); } + constexpr mdarray(const extents_type& exts, container_type&& ctr, + const Alloc& a) + : map_(exts), ctr_(std::move(ctr), a) { + assert(ctr_.size() >= static_cast(map_.required_span_size())); + } MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) + class Alloc, + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, + size_t, Alloc))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mapping_type& map, container_type&& ctr, const Alloc& a) - : map_(map), ctr_(std::move(ctr), a) - { assert(ctr_.size() >= map_.required_span_size()); } + constexpr mdarray(const mapping_type& map, container_type&& ctr, + const Alloc& a) + : map_(map), ctr_(std::move(ctr), a) { + assert(ctr_.size() >= map_.required_span_size()); + } MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherContainer, class Alloc, - /* requires */ ( - MDSPAN_IMPL_TRAIT( std::is_constructible, mapping_type, typename OtherLayoutPolicy::template mapping) && - MDSPAN_IMPL_TRAIT( std::is_constructible, container_type, OtherContainer, Alloc) - ) - ) + class OtherElementType, class OtherExtents, class OtherLayoutPolicy, + class OtherContainer, class Alloc, + /* requires */ + (MDSPAN_IMPL_TRAIT( + std::is_constructible, mapping_type, + typename OtherLayoutPolicy::template mapping) && + MDSPAN_IMPL_TRAIT(std::is_constructible, container_type, OtherContainer, + Alloc))) MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mdarray& other, const Alloc& a) - : map_(other.mapping()), ctr_(other.container(), a) - { - static_assert( std::is_constructible::value, ""); + constexpr mdarray(const mdarray& other, + const Alloc& a) + : map_(other.mapping()), ctr_(other.container(), a) { + static_assert(std::is_constructible::value, ""); } - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (const mdarray&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (mdarray&&) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator=( + const mdarray&) = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator=(mdarray&&) = + default; MDSPAN_INLINE_FUNCTION_DEFAULTED ~mdarray() = default; //-------------------------------------------------------------------------------- - // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to access codomain element + // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to + // access codomain element - #if MDSPAN_USE_BRACKET_OPERATOR +#if MDSPAN_USE_BRACKET_OPERATOR MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT( std::is_convertible, SizeTypes, index_type) /* && ... */) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) + class... SizeTypes, + /* requires */ ( + MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_convertible, SizeTypes, + index_type) /* && ... */) && + extents_type::rank() == sizeof...(SizeTypes))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator[](SizeTypes... indices) const noexcept - { + constexpr const_reference operator[](SizeTypes... indices) const noexcept { return ctr_[map_(static_cast(std::move(indices))...)]; } MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT( std::is_convertible, SizeTypes, index_type) /* && ... */) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) + class... SizeTypes, + /* requires */ ( + MDSPAN_IMPL_FOLD_AND(MDSPAN_IMPL_TRAIT(std::is_convertible, SizeTypes, + index_type) /* && ... */) && + extents_type::rank() == sizeof...(SizeTypes))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](SizeTypes... indices) noexcept - { + constexpr reference operator[](SizeTypes... indices) noexcept { return ctr_[map_(static_cast(std::move(indices))...)]; } - #endif +#endif #if 0 MDSPAN_TEMPLATE_REQUIRES( @@ -307,30 +330,23 @@ class mdarray { } #endif - - #if MDSPAN_USE_PAREN_OPERATOR +#if MDSPAN_USE_PAREN_OPERATOR MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices()) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) + class... SizeTypes, + /* requires */ ((::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + are_valid_indices()) && + extents_type::rank() == sizeof...(SizeTypes))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator()(SizeTypes... indices) const noexcept - { + constexpr const_reference operator()(SizeTypes... indices) const noexcept { return ctr_[map_(static_cast(std::move(indices))...)]; } MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices()) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) + class... SizeTypes, + /* requires */ ((::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + are_valid_indices()) && + extents_type::rank() == sizeof...(SizeTypes))) MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(SizeTypes... indices) noexcept - { + constexpr reference operator()(SizeTypes... indices) noexcept { return ctr_[map_(static_cast(std::move(indices))...)]; } @@ -361,93 +377,132 @@ class mdarray { return impl::template callop(*this, indices); } #endif - #endif +#endif - MDSPAN_INLINE_FUNCTION constexpr pointer data() noexcept { return ctr_.data(); } - MDSPAN_INLINE_FUNCTION constexpr const_pointer data() const noexcept { return ctr_.data(); } - MDSPAN_INLINE_FUNCTION constexpr container_type& container() noexcept { return ctr_; } - MDSPAN_INLINE_FUNCTION constexpr const container_type& container() const noexcept { return ctr_; } + MDSPAN_INLINE_FUNCTION constexpr pointer data() noexcept { + return ctr_.data(); + } + MDSPAN_INLINE_FUNCTION constexpr const_pointer data() const noexcept { + return ctr_.data(); + } + MDSPAN_INLINE_FUNCTION constexpr container_type& container() noexcept { + return ctr_; + } + MDSPAN_INLINE_FUNCTION constexpr const container_type& container() + const noexcept { + return ctr_; + } //-------------------------------------------------------------------------------- - // [mdspan.basic.domobs], mdspan observers of the domain multidimensional index space + // [mdspan.basic.domobs], mdspan observers of the domain multidimensional + // index space - MDSPAN_INLINE_FUNCTION static constexpr rank_type rank() noexcept { return extents_type::rank(); } - MDSPAN_INLINE_FUNCTION static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent(size_t r) noexcept { return extents_type::static_extent(r); } + MDSPAN_INLINE_FUNCTION static constexpr rank_type rank() noexcept { + return extents_type::rank(); + } + MDSPAN_INLINE_FUNCTION static constexpr rank_type rank_dynamic() noexcept { + return extents_type::rank_dynamic(); + } + MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent( + size_t r) noexcept { + return extents_type::static_extent(r); + } - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return map_.extents(); } - MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return map_.extents().extent(r); } + MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() + const noexcept { + return map_.extents(); + } + MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { + return map_.extents().extent(r); + } MDSPAN_INLINE_FUNCTION constexpr index_type size() const noexcept { -// return impl::size(*this); + // return impl::size(*this); return ctr_.size(); } - //-------------------------------------------------------------------------------- // [mdspan.basic.obs], mdspan observers of the mapping - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return mapping_type::is_always_exhaustive(); } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { + return mapping_type::is_always_unique(); + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { + return mapping_type::is_always_exhaustive(); + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { + return mapping_type::is_always_strided(); + } - MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() const noexcept { return map_; } - MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { return map_.is_unique(); } - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { return map_.is_exhaustive(); } - MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return map_.is_strided(); } - MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return map_.stride(r); } + MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() + const noexcept { + return map_; + } + MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { + return map_.is_unique(); + } + MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { + return map_.is_exhaustive(); + } + MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { + return map_.is_strided(); + } + MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { + return map_.stride(r); + } // Converstion to mdspan MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, - class OtherLayoutType, class OtherAccessorType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_assignable, - mdspan, - mdspan_type) - ) - ) - constexpr operator mdspan () { + class OtherElementType, class OtherExtents, class OtherLayoutType, + class OtherAccessorType, + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_assignable, + mdspan, + mdspan_type))) + constexpr operator mdspan() { return mdspan_type(data(), map_); } MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, - class OtherLayoutType, class OtherAccessorType, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_assignable, - mdspan, - const_mdspan_type) - ) - ) - constexpr operator mdspan () const { + class OtherElementType, class OtherExtents, class OtherLayoutType, + class OtherAccessorType, + /* requires */ + (MDSPAN_IMPL_TRAIT(std::is_assignable, + mdspan, + const_mdspan_type))) + constexpr operator mdspan() const { return const_mdspan_type(data(), map_); } MDSPAN_TEMPLATE_REQUIRES( - class OtherAccessorType = default_accessor, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_assignable, mdspan_type, - mdspan) - ) - ) + class OtherAccessorType = default_accessor, + /* requires */ (MDSPAN_IMPL_TRAIT( + std::is_assignable, mdspan_type, + mdspan))) constexpr mdspan - to_mdspan(const OtherAccessorType& a = default_accessor()) { - return mdspan(data(), map_, a); + to_mdspan(const OtherAccessorType& a = default_accessor()) { + return mdspan( + data(), map_, a); } MDSPAN_TEMPLATE_REQUIRES( - class OtherAccessorType = default_accessor, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_assignable, const_mdspan_type, - mdspan) - ) - ) - constexpr mdspan - to_mdspan(const OtherAccessorType& a = default_accessor()) const { - return mdspan(data(), map_, a); + class OtherAccessorType = default_accessor, + /* requires */ ( + MDSPAN_IMPL_TRAIT(std::is_assignable, const_mdspan_type, + mdspan))) + constexpr mdspan + to_mdspan(const OtherAccessorType& a = + default_accessor()) const { + return mdspan(data(), map_, a); } -private: + private: mapping_type map_; container_type ctr_; @@ -455,6 +510,5 @@ class mdarray { friend class mdarray; }; - -} // end namespace MDSPAN_IMPL_PROPOSED_NAMESPACE -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // end namespace MDSPAN_IMPL_PROPOSED_NAMESPACE +} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2389_bits/dims.hpp b/include/experimental/__p2389_bits/dims.hpp index 00045215..39c85dd5 100644 --- a/include/experimental/__p2389_bits/dims.hpp +++ b/include/experimental/__p2389_bits/dims.hpp @@ -20,9 +20,8 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { -template< ::std::size_t Rank, class IndexType = std::size_t> -using dims = - :: MDSPAN_IMPL_STANDARD_NAMESPACE :: dextents; +template < ::std::size_t Rank, class IndexType = std::size_t> +using dims = ::MDSPAN_IMPL_STANDARD_NAMESPACE ::dextents; -} // namespace MDSPAN_IMPL_PROPOSED_NAMESPACE -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_PROPOSED_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2630_bits/strided_slice.hpp b/include/experimental/__p2630_bits/strided_slice.hpp index 23f3dde9..aa5ad03f 100644 --- a/include/experimental/__p2630_bits/strided_slice.hpp +++ b/include/experimental/__p2630_bits/strided_slice.hpp @@ -22,12 +22,13 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace { - template - struct mdspan_is_integral_constant: std::false_type {}; +template +struct mdspan_is_integral_constant : std::false_type {}; - template - struct mdspan_is_integral_constant>: std::true_type {}; -} +template +struct mdspan_is_integral_constant> + : std::true_type {}; +} // namespace // Slice Specifier allowing for strides and compile time extent template @@ -40,9 +41,12 @@ struct strided_slice { MDSPAN_IMPL_NO_UNIQUE_ADDRESS ExtentType extent{}; MDSPAN_IMPL_NO_UNIQUE_ADDRESS StrideType stride{}; - static_assert(std::is_integral_v || mdspan_is_integral_constant::value); - static_assert(std::is_integral_v || mdspan_is_integral_constant::value); - static_assert(std::is_integral_v || mdspan_is_integral_constant::value); + static_assert(std::is_integral_v || + mdspan_is_integral_constant::value); + static_assert(std::is_integral_v || + mdspan_is_integral_constant::value); + static_assert(std::is_integral_v || + mdspan_is_integral_constant::value); }; -} // MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2630_bits/submdspan.hpp b/include/experimental/__p2630_bits/submdspan.hpp index abddd0b5..a156016f 100644 --- a/include/experimental/__p2630_bits/submdspan.hpp +++ b/include/experimental/__p2630_bits/submdspan.hpp @@ -22,19 +22,20 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { template -MDSPAN_INLINE_FUNCTION -constexpr auto -submdspan(const mdspan &src, - SliceSpecifiers... slices) { - const auto sub_submdspan_mapping_result = submdspan_mapping(src.mapping(), slices...); +MDSPAN_INLINE_FUNCTION constexpr auto submdspan( + const mdspan &src, + SliceSpecifiers... slices) { + const auto sub_submdspan_mapping_result = + submdspan_mapping(src.mapping(), slices...); // NVCC has a problem with the deduction so lets figure out the type - using sub_mapping_t = std::remove_cv_t; - using sub_extents_t = typename sub_mapping_t::extents_type; - using sub_layout_t = typename sub_mapping_t::layout_type; + using sub_mapping_t = + std::remove_cv_t; + using sub_extents_t = typename sub_mapping_t::extents_type; + using sub_layout_t = typename sub_mapping_t::layout_type; using sub_accessor_t = typename AccessorPolicy::offset_policy; return mdspan( - src.accessor().offset(src.data_handle(), sub_submdspan_mapping_result.offset), - sub_submdspan_mapping_result.mapping, - sub_accessor_t(src.accessor())); + src.accessor().offset(src.data_handle(), + sub_submdspan_mapping_result.offset), + sub_submdspan_mapping_result.mapping, sub_accessor_t(src.accessor())); } -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2630_bits/submdspan_extents.hpp b/include/experimental/__p2630_bits/submdspan_extents.hpp index 4fe5dc6e..a82a0936 100644 --- a/include/experimental/__p2630_bits/submdspan_extents.hpp +++ b/include/experimental/__p2630_bits/submdspan_extents.hpp @@ -29,33 +29,37 @@ namespace detail { // to contain the mapped indices. // end of recursion specialization containing the final index_sequence template -MDSPAN_INLINE_FUNCTION -constexpr auto inv_map_rank(std::integral_constant, std::index_sequence) { +MDSPAN_INLINE_FUNCTION constexpr auto inv_map_rank( + std::integral_constant, std::index_sequence) { return std::index_sequence(); } // specialization reducing rank by one (i.e., integral slice specifier) -template -MDSPAN_INLINE_FUNCTION -constexpr auto inv_map_rank(std::integral_constant, std::index_sequence, Slice, - SliceSpecifiers... slices) { - using next_idx_seq_t = std::conditional_t, - std::index_sequence, - std::index_sequence>; - - return inv_map_rank(std::integral_constant(), next_idx_seq_t(), - slices...); +template +MDSPAN_INLINE_FUNCTION constexpr auto inv_map_rank( + std::integral_constant, std::index_sequence, + Slice, SliceSpecifiers... slices) { + using next_idx_seq_t = + std::conditional_t, + std::index_sequence, + std::index_sequence>; + + return inv_map_rank(std::integral_constant(), + next_idx_seq_t(), slices...); } // Helper for identifying strided_slice -template struct is_strided_slice : std::false_type {}; +template +struct is_strided_slice : std::false_type {}; template -struct is_strided_slice< - strided_slice> : std::true_type {}; +struct is_strided_slice> + : std::true_type {}; // Helper for identifying valid pair like things -template struct index_pair_like : std::false_type {}; +template +struct index_pair_like : std::false_type {}; template struct index_pair_like, IndexType> { @@ -87,62 +91,47 @@ struct index_pair_like, IndexType> { // first_of(slice): getting begin of slice specifier range MDSPAN_TEMPLATE_REQUIRES( - class Integral, - /* requires */(std::is_convertible_v) -) + class Integral, + /* requires */ (std::is_convertible_v)) MDSPAN_INLINE_FUNCTION -constexpr Integral first_of(const Integral &i) { - return i; -} +constexpr Integral first_of(const Integral &i) { return i; } -template -MDSPAN_INLINE_FUNCTION -constexpr Integral first_of(const std::integral_constant&) { +template +MDSPAN_INLINE_FUNCTION constexpr Integral first_of( + const std::integral_constant &) { return integral_constant(); } MDSPAN_INLINE_FUNCTION -constexpr integral_constant -first_of(const ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t &) { +constexpr integral_constant first_of( + const ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t &) { return integral_constant(); } -MDSPAN_TEMPLATE_REQUIRES( - class Slice, - /* requires */(index_pair_like::value) -) +MDSPAN_TEMPLATE_REQUIRES(class Slice, + /* requires */ (index_pair_like::value)) MDSPAN_INLINE_FUNCTION -constexpr auto first_of(const Slice &i) { - return get<0>(i); -} +constexpr auto first_of(const Slice &i) { return get<0>(i); } MDSPAN_TEMPLATE_REQUIRES( - class IdxT1, class IdxT2, - /* requires */ (index_pair_like, size_t>::value) - ) -constexpr auto first_of(const std::tuple& i) { - return get<0>(i); -} + class IdxT1, class IdxT2, + /* requires */ (index_pair_like, size_t>::value)) +constexpr auto first_of(const std::tuple &i) { return get<0>(i); } MDSPAN_TEMPLATE_REQUIRES( - class IdxT1, class IdxT2, - /* requires */ (index_pair_like, size_t>::value) - ) + class IdxT1, class IdxT2, + /* requires */ (index_pair_like, size_t>::value)) MDSPAN_INLINE_FUNCTION -constexpr auto first_of(const std::pair& i) { - return i.first; -} +constexpr auto first_of(const std::pair &i) { return i.first; } -template -MDSPAN_INLINE_FUNCTION -constexpr auto first_of(const std::complex &i) { +template +MDSPAN_INLINE_FUNCTION constexpr auto first_of(const std::complex &i) { return i.real(); } template -MDSPAN_INLINE_FUNCTION -constexpr OffsetType -first_of(const strided_slice &r) { +MDSPAN_INLINE_FUNCTION constexpr OffsetType first_of( + const strided_slice &r) { return r.offset; } @@ -151,19 +140,16 @@ first_of(const strided_slice &r) { // of the original view and which rank from the extents. // This is needed in the case of slice being full_extent_t. MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class Integral, - /* requires */(std::is_convertible_v) -) + size_t k, class Extents, class Integral, + /* requires */ (std::is_convertible_v)) MDSPAN_INLINE_FUNCTION -constexpr Integral - last_of(std::integral_constant, const Extents &, const Integral &i) { +constexpr Integral last_of(std::integral_constant, const Extents &, + const Integral &i) { return i; } -MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class Slice, - /* requires */(index_pair_like::value) -) +MDSPAN_TEMPLATE_REQUIRES(size_t k, class Extents, class Slice, + /* requires */ (index_pair_like::value)) MDSPAN_INLINE_FUNCTION constexpr auto last_of(std::integral_constant, const Extents &, const Slice &i) { @@ -171,25 +157,26 @@ constexpr auto last_of(std::integral_constant, const Extents &, } MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class IdxT1, class IdxT2, - /* requires */ (index_pair_like, size_t>::value) - ) -constexpr auto last_of(std::integral_constant, const Extents &, const std::tuple& i) { + size_t k, class Extents, class IdxT1, class IdxT2, + /* requires */ (index_pair_like, size_t>::value)) +constexpr auto last_of(std::integral_constant, const Extents &, + const std::tuple &i) { return get<1>(i); } MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class IdxT1, class IdxT2, - /* requires */ (index_pair_like, size_t>::value) - ) + size_t k, class Extents, class IdxT1, class IdxT2, + /* requires */ (index_pair_like, size_t>::value)) MDSPAN_INLINE_FUNCTION -constexpr auto last_of(std::integral_constant, const Extents &, const std::pair& i) { +constexpr auto last_of(std::integral_constant, const Extents &, + const std::pair &i) { return i.second; } -template -MDSPAN_INLINE_FUNCTION -constexpr auto last_of(std::integral_constant, const Extents &, const std::complex &i) { +template +MDSPAN_INLINE_FUNCTION constexpr auto last_of(std::integral_constant, + const Extents &, + const std::complex &i) { return i.imag(); } @@ -199,23 +186,23 @@ constexpr auto last_of(std::integral_constant, const Extents &, const // and the diagnostic push. I tried really hard to find something shorter // but no luck ... #if defined __NVCC__ - #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ - #pragma nv_diagnostic push - #pragma nv_diag_suppress = implicit_return_from_non_void_function - #else - #ifdef __CUDA_ARCH__ - #pragma diagnostic push - #pragma diag_suppress implicit_return_from_non_void_function - #endif - #endif +#ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ +#pragma nv_diagnostic push +#pragma nv_diag_suppress = implicit_return_from_non_void_function +#else +#ifdef __CUDA_ARCH__ +#pragma diagnostic push +#pragma diag_suppress implicit_return_from_non_void_function +#endif +#endif #elif defined __NVCOMPILER - #pragma diagnostic push - #pragma diag_suppress = implicit_return_from_non_void_function +#pragma diagnostic push +#pragma diag_suppress = implicit_return_from_non_void_function #endif template -MDSPAN_INLINE_FUNCTION -constexpr auto last_of(std::integral_constant, const Extents &ext, - ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t) { +MDSPAN_INLINE_FUNCTION constexpr auto last_of( + std::integral_constant, const Extents &ext, + ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t) { if constexpr (Extents::static_extent(k) == dynamic_extent) { return ext.extent(k); } else { @@ -227,72 +214,68 @@ constexpr auto last_of(std::integral_constant, const Extents &ext, #endif } #if defined __NVCC__ - #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ - #pragma nv_diagnostic pop - #else - #ifdef __CUDA_ARCH__ - #pragma diagnostic pop - #endif - #endif +#ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ +#pragma nv_diagnostic pop +#else +#ifdef __CUDA_ARCH__ +#pragma diagnostic pop +#endif +#endif #elif defined __NVCOMPILER - #pragma diagnostic pop +#pragma diagnostic pop #endif template -MDSPAN_INLINE_FUNCTION -constexpr OffsetType -last_of(std::integral_constant, const Extents &, - const strided_slice &r) { +MDSPAN_INLINE_FUNCTION constexpr OffsetType last_of( + std::integral_constant, const Extents &, + const strided_slice &r) { return r.extent; } // get stride of slices template -MDSPAN_INLINE_FUNCTION -constexpr auto stride_of(const T &) { +MDSPAN_INLINE_FUNCTION constexpr auto stride_of(const T &) { return integral_constant(); } template -MDSPAN_INLINE_FUNCTION -constexpr auto -stride_of(const strided_slice &r) { +MDSPAN_INLINE_FUNCTION constexpr auto stride_of( + const strided_slice &r) { return r.stride; } // divide which can deal with integral constant preservation template -MDSPAN_INLINE_FUNCTION -constexpr auto divide(const T0 &v0, const T1 &v1) { +MDSPAN_INLINE_FUNCTION constexpr auto divide(const T0 &v0, const T1 &v1) { return IndexT(v0) / IndexT(v1); } template -MDSPAN_INLINE_FUNCTION -constexpr auto divide(const std::integral_constant &, - const std::integral_constant &) { +MDSPAN_INLINE_FUNCTION constexpr auto divide( + const std::integral_constant &, + const std::integral_constant &) { // cutting short division by zero // this is used for strided_slice with zero extent/stride - return integral_constant(); + return integral_constant < IndexT, v0 == 0 ? 0 : v0 / v1 > (); } // multiply which can deal with integral constant preservation template -MDSPAN_INLINE_FUNCTION -constexpr auto multiply(const T0 &v0, const T1 &v1) { +MDSPAN_INLINE_FUNCTION constexpr auto multiply(const T0 &v0, const T1 &v1) { return IndexT(v0) * IndexT(v1); } template -MDSPAN_INLINE_FUNCTION -constexpr auto multiply(const std::integral_constant &, - const std::integral_constant &) { +MDSPAN_INLINE_FUNCTION constexpr auto multiply( + const std::integral_constant &, + const std::integral_constant &) { return integral_constant(); } // compute new static extent from range, preserving static knowledge -template struct StaticExtentFromRange { +template +struct StaticExtentFromRange { constexpr static size_t value = dynamic_extent; }; @@ -310,7 +293,8 @@ struct StaticExtentFromRange, // compute new static extent from strided_slice, preserving static // knowledge -template struct StaticExtentFromStridedRange { +template +struct StaticExtentFromStridedRange { constexpr static size_t value = dynamic_extent; }; @@ -330,11 +314,10 @@ struct StaticExtentFromStridedRange, // next_extent has different overloads for different types of stride specifiers template struct extents_constructor { - MDSPAN_TEMPLATE_REQUIRES( - class Slice, class... SlicesAndExtents, - /* requires */(!std::is_convertible_v && - !is_strided_slice::value) - ) + MDSPAN_TEMPLATE_REQUIRES(class Slice, class... SlicesAndExtents, + /* requires */ + (!std::is_convertible_v && + !is_strided_slice::value)) MDSPAN_INLINE_FUNCTION constexpr static auto next_extent(const Extents &ext, const Slice &sl, SlicesAndExtents... slices_and_extents) { @@ -349,15 +332,14 @@ struct extents_constructor { using index_t = typename Extents::index_type; return next_t::next_extent( ext, slices_and_extents..., - index_t(last_of(std::integral_constant(), ext, - sl)) - + index_t(last_of(std::integral_constant(), + ext, sl)) - index_t(first_of(sl))); } MDSPAN_TEMPLATE_REQUIRES( - class Slice, class... SlicesAndExtents, - /* requires */ (std::is_convertible_v) - ) + class Slice, class... SlicesAndExtents, + /* requires */ (std::is_convertible_v)) MDSPAN_INLINE_FUNCTION constexpr static auto next_extent(const Extents &ext, const Slice &, SlicesAndExtents... slices_and_extents) { @@ -367,11 +349,10 @@ struct extents_constructor { template - MDSPAN_INLINE_FUNCTION - constexpr static auto - next_extent(const Extents &ext, - const strided_slice &r, - SlicesAndExtents... slices_and_extents) { + MDSPAN_INLINE_FUNCTION constexpr static auto next_extent( + const Extents &ext, + const strided_slice &r, + SlicesAndExtents... slices_and_extents) { using index_t = typename Extents::index_type; using new_static_extent_t = StaticExtentFromStridedRange; @@ -386,33 +367,31 @@ struct extents_constructor { using next_t = extents_constructor; return next_t::next_extent( - ext, slices_and_extents..., index_t(divide(ExtentType(), StrideType()))); + ext, slices_and_extents..., + index_t(divide(ExtentType(), StrideType()))); } } }; template struct extents_constructor<0, Extents, NewStaticExtents...> { - template - MDSPAN_INLINE_FUNCTION - constexpr static auto next_extent(const Extents &, NewExtents... new_exts) { + MDSPAN_INLINE_FUNCTION constexpr static auto next_extent( + const Extents &, NewExtents... new_exts) { return extents( new_exts...); } }; -} // namespace detail +} // namespace detail // submdspan_extents creates new extents given src extents and submdspan slice // specifiers template -MDSPAN_INLINE_FUNCTION -constexpr auto submdspan_extents(const extents &src_exts, - SliceSpecifiers... slices) { - +MDSPAN_INLINE_FUNCTION constexpr auto submdspan_extents( + const extents &src_exts, SliceSpecifiers... slices) { using ext_t = extents; return detail::extents_constructor::next_extent( src_exts, slices...); } -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2630_bits/submdspan_mapping.hpp b/include/experimental/__p2630_bits/submdspan_mapping.hpp index 82f9193a..ff58f4b2 100644 --- a/include/experimental/__p2630_bits/submdspan_mapping.hpp +++ b/include/experimental/__p2630_bits/submdspan_mapping.hpp @@ -18,7 +18,7 @@ #include #include -#include // index_sequence +#include // index_sequence #include "../__p0009_bits/utility.hpp" // Suppress spurious warning with NVCC about no return statement. @@ -45,7 +45,8 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { //****************************************** // Return type of submdspan_mapping overloads //****************************************** -template struct submdspan_mapping_result { +template +struct submdspan_mapping_result { MDSPAN_IMPL_NO_UNIQUE_ADDRESS LayoutMapping mapping{}; size_t offset; }; @@ -58,8 +59,8 @@ namespace detail { // still don't want to pass those (possibly of size 64 x 3 bits) // objects by value. template -MDSPAN_INLINE_FUNCTION constexpr bool -one_slice_out_of_bounds(const IndexType &ext, const Slice &slice) { +MDSPAN_INLINE_FUNCTION constexpr bool one_slice_out_of_bounds( + const IndexType &ext, const Slice &slice) { using common_t = std::common_type_t; return static_cast(detail::first_of(slice)) == @@ -68,58 +69,59 @@ one_slice_out_of_bounds(const IndexType &ext, const Slice &slice) { template -MDSPAN_INLINE_FUNCTION constexpr bool -any_slice_out_of_bounds_helper(std::index_sequence, - const extents &exts, - const Slices &... slices) { +MDSPAN_INLINE_FUNCTION constexpr bool any_slice_out_of_bounds_helper( + std::index_sequence, + const extents &exts, const Slices &...slices) { return MDSPAN_IMPL_FOLD_OR( (one_slice_out_of_bounds(exts.extent(RankIndices), slices))); } template -MDSPAN_INLINE_FUNCTION constexpr bool -any_slice_out_of_bounds(const extents &exts, - const Slices &... slices) { +MDSPAN_INLINE_FUNCTION constexpr bool any_slice_out_of_bounds( + const extents &exts, const Slices &...slices) { return any_slice_out_of_bounds_helper( std::make_index_sequence(), exts, slices...); } // constructs sub strides -template -struct sub_strides -{ +template +struct sub_strides { T values[N > 0 ? N : 1]; }; template MDSPAN_INLINE_FUNCTION constexpr auto construct_sub_strides( const SrcMapping &src_mapping, std::index_sequence, - const MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple &slices_stride_factor) { + const MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple + &slices_stride_factor) { using index_type = typename SrcMapping::index_type; - return sub_strides{{ - (static_cast(src_mapping.stride(InvMapIdxs)) * - static_cast(get(slices_stride_factor)))...}}; + return sub_strides{ + {(static_cast(src_mapping.stride(InvMapIdxs)) * + static_cast(get(slices_stride_factor)))...}}; } -template +template struct is_range_slice { constexpr static bool value = - std::is_same_v || - index_pair_like::value; + std::is_same_v || + index_pair_like::value; }; -template -constexpr bool is_range_slice_v = is_range_slice::value; +template +constexpr bool is_range_slice_v = + is_range_slice::value; -template +template struct is_index_slice { - constexpr static bool value = std::is_convertible_v; + constexpr static bool value = + std::is_convertible_v; }; -template -constexpr bool is_index_slice_v = is_index_slice::value; +template +constexpr bool is_index_slice_v = + is_index_slice::value; -} // namespace detail +} // namespace detail //********************************** // layout_left submdspan_mapping @@ -135,7 +137,6 @@ template struct deduce_layout_left_submapping< IndexType, SubRank, std::index_sequence, SliceSpecifiers...> { - using count_range = index_sequence_scan_impl< 0u, (is_index_slice_v ? 0u : 1u)...>; @@ -151,16 +152,21 @@ struct deduce_layout_left_submapping< // Use layout_left for rank 0 if constexpr (SubRank == 0) { return true; - // Use layout_left for rank 1 result if leftmost slice specifier is range like + // Use layout_left for rank 1 result if leftmost slice specifier is range + // like } else if constexpr (SubRank == 1) { return ((Idx > 0 || is_range_slice_v)&&...); } else { // Preserve if leftmost SubRank-1 slices are full_extent_t and // the slice at idx Subrank - 1 is a range and // for idx > SubRank the slice is an index - return ((((Idx < SubRank - 1) && std::is_same_v) || - ((Idx == SubRank - 1) && is_range_slice_v) || - ((Idx > SubRank - 1) && is_index_slice_v)) && ...); + return ((((Idx < SubRank - 1) && + std::is_same_v) || + ((Idx == SubRank - 1) && + is_range_slice_v) || + ((Idx > SubRank - 1) && + is_index_slice_v)) && + ...); } #if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) __builtin_unreachable(); @@ -180,30 +186,41 @@ struct deduce_layout_left_submapping< // then another range slice // then more index slices // e.g. R I I I F F F R I I for obtaining a rank-5 from a rank-10 - return ((((Idx == 0) && is_range_slice_v) || - ((Idx > 0 && Idx <= gap_len) && is_index_slice_v) || - ((Idx > gap_len && Idx < gap_len + SubRank - 1) && std::is_same_v) || - ((Idx == gap_len + SubRank - 1) && is_range_slice_v) || - ((Idx > gap_len + SubRank - 1) && is_index_slice_v)) && ... ); + return ((((Idx == 0) && is_range_slice_v) || + ((Idx > 0 && Idx <= gap_len) && + is_index_slice_v) || + ((Idx > gap_len && Idx < gap_len + SubRank - 1) && + std::is_same_v) || + ((Idx == gap_len + SubRank - 1) && + is_range_slice_v) || + ((Idx > gap_len + SubRank - 1) && + is_index_slice_v)) && + ...); } }; // We are reusing the same thing for layout_left and layout_left_padded // For layout_left as source StaticStride is static_extent(0) -template +template struct compute_s_static_layout_left { // Neither StaticStride nor any of the provided extents can be zero. - // StaticStride can never be zero, the static_extents we are looking at are associated with - // integral slice specifiers - which wouldn't be valid for zero extent - template - MDSPAN_INLINE_FUNCTION - static constexpr size_t value(std::index_sequence) { - size_t val = ((Idx>0 && Idx<=NumGaps ? (Extents::static_extent(Idx) == dynamic_extent?0:Extents::static_extent(Idx)) : 1) * ... * (StaticStride == dynamic_extent?0:StaticStride)); - return val == 0?dynamic_extent:val; + // StaticStride can never be zero, the static_extents we are looking at are + // associated with integral slice specifiers - which wouldn't be valid for + // zero extent + template + MDSPAN_INLINE_FUNCTION static constexpr size_t value( + std::index_sequence) { + size_t val = ((Idx > 0 && Idx <= NumGaps + ? (Extents::static_extent(Idx) == dynamic_extent + ? 0 + : Extents::static_extent(Idx)) + : 1) * + ... * (StaticStride == dynamic_extent ? 0 : StaticStride)); + return val == 0 ? dynamic_extent : val; } }; -} // namespace detail +} // namespace detail // Actual submdspan mapping call template @@ -211,17 +228,15 @@ template MDSPAN_INLINE_FUNCTION constexpr auto layout_left::mapping::submdspan_mapping_impl( SliceSpecifiers... slices) const { - // compute sub extents using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); + auto dst_ext = submdspan_extents(extents(), slices...); using dst_ext_t = decltype(dst_ext); // figure out sub layout type using deduce_layout = detail::deduce_layout_left_submapping< typename dst_ext_t::index_type, dst_ext_t::rank(), - std::make_index_sequence, - SliceSpecifiers...>; + std::make_index_sequence, SliceSpecifiers...>; // Figure out if any slice's lower bound equals the corresponding extent. // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. @@ -237,8 +252,13 @@ layout_left::mapping::submdspan_mapping_impl( return submdspan_mapping_result{dst_mapping_t(dst_ext), offset}; } else if constexpr (deduce_layout::layout_left_padded_value()) { - constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_left::value(std::make_index_sequence()); - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded::template mapping; + constexpr size_t S_static = + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_left< + Extents, deduce_layout::gap_len, Extents::static_extent(0)>:: + value(std::make_index_sequence()); + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded< + S_static>::template mapping; return submdspan_mapping_result{ dst_mapping_t(dst_ext, stride(1 + deduce_layout::gap_len)), offset}; } else { @@ -256,9 +276,11 @@ layout_left::mapping::submdspan_mapping_impl( // disable it for CUDA altogether #if defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_CUDA) detail::tuple{ - detail::stride_of(slices)...}).values), + detail::stride_of(slices)...}) + .values), #else - detail::tuple{detail::stride_of(slices)...}).values), + detail::tuple{detail::stride_of(slices)...}) + .values), #endif offset }; @@ -272,79 +294,109 @@ template template template MDSPAN_INLINE_FUNCTION constexpr auto -MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded::mapping::submdspan_mapping_impl( - SliceSpecifiers... slices) const { - +MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded::mapping< + Extents>::submdspan_mapping_impl(SliceSpecifiers... slices) const { // compute sub extents using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); + auto dst_ext = submdspan_extents(extents(), slices...); using dst_ext_t = decltype(dst_ext); - if constexpr (Extents::rank() == 0) { // rank-0 case - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded::template mapping; + if constexpr (Extents::rank() == 0) { // rank-0 case + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded< + PaddingValue>::template mapping; return submdspan_mapping_result{*this, 0}; } else { const bool out_of_bounds = - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::any_slice_out_of_bounds(this->extents(), slices...); + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::any_slice_out_of_bounds( + this->extents(), slices...); auto offset = static_cast( - out_of_bounds ? this->required_span_size() - : this->operator()(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::first_of(slices)...)); - if constexpr (dst_ext_t::rank() == 0) { // result rank-0 - // The following for some reasons leads to compiler error later, while not using a typedef works: - // Compilers: CUDA 11.2 with GCC 9.1 + out_of_bounds + ? this->required_span_size() + : this->operator()( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::first_of(slices)...)); + if constexpr (dst_ext_t::rank() == 0) { // result rank-0 + // The following for some reasons leads to compiler error later, while not + // using a typedef works: Compilers: CUDA 11.2 with GCC 9.1 // - // using dst_mapping_t = typename layout_left::template mapping; - // return submdspan_mapping_result{dst_mapping_t{dst_ext}, offset}; + // using dst_mapping_t = typename layout_left::template + // mapping; return + // submdspan_mapping_result{dst_mapping_t{dst_ext}, + // offset}; // - // Error: submdspan_mapping.hpp:299:23: error: 'dst_mapping_t' does not name a type - // 299 | using dst_mapping_t = typename layout_left::template mapping; - // The same error is given (about dst_mapping_t not naming type) when a different name is used in 299: - // using dst_mapping_t2 = typename layout_left::template mapping; - - return submdspan_mapping_result> - {typename layout_left::template mapping{dst_ext}, offset}; - } else { // general case + // Error: submdspan_mapping.hpp:299:23: error: 'dst_mapping_t' does not + // name a type + // 299 | using dst_mapping_t = typename + // layout_left::template mapping; + // The same error is given (about dst_mapping_t not naming type) when a + // different name is used in 299: + // using dst_mapping_t2 = typename layout_left::template + // mapping; + + return submdspan_mapping_result< + typename layout_left::template mapping>{ + typename layout_left::template mapping{dst_ext}, offset}; + } else { // general case // Figure out if any slice's lower bound equals the corresponding extent. - // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. - // figure out sub layout type - using deduce_layout = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::deduce_layout_left_submapping< - typename dst_ext_t::index_type, dst_ext_t::rank(), - decltype(std::make_index_sequence()), - SliceSpecifiers...>; - - if constexpr (deduce_layout::layout_left_value() && dst_ext_t::rank() == 1) { // getting rank-1 from leftmost + // If so, bypass evaluating the layout mapping. This fixes LWG Issue + // 4060. figure out sub layout type + using deduce_layout = + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::deduce_layout_left_submapping< + typename dst_ext_t::index_type, dst_ext_t::rank(), + decltype(std::make_index_sequence()), + SliceSpecifiers...>; + + if constexpr (deduce_layout::layout_left_value() && + dst_ext_t::rank() == 1) { // getting rank-1 from leftmost using dst_mapping_t = typename layout_left::template mapping; - return submdspan_mapping_result{dst_mapping_t{dst_ext}, offset}; - } else if constexpr (deduce_layout::layout_left_padded_value()) { // can keep layout_left_padded - constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_left::value(std::make_index_sequence()); - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded::template mapping; + return submdspan_mapping_result{dst_mapping_t{dst_ext}, + offset}; + } else if constexpr ( + deduce_layout::layout_left_padded_value()) { // can keep + // layout_left_padded + constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + compute_s_static_layout_left:: + value(std::make_index_sequence()); + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded< + S_static>::template mapping; return submdspan_mapping_result{ - dst_mapping_t(dst_ext, stride(1 + deduce_layout::gap_len)), offset}; - } else { // layout_stride - auto inv_map = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::inv_map_rank(std::integral_constant(), - std::index_sequence<>(), slices...); - using dst_mapping_t = typename layout_stride::template mapping; - return submdspan_mapping_result { - dst_mapping_t(mdspan_non_standard, dst_ext, - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::construct_sub_strides( - *this, inv_map, + dst_mapping_t(dst_ext, stride(1 + deduce_layout::gap_len)), offset}; + } else { // layout_stride + auto inv_map = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::inv_map_rank( + std::integral_constant(), std::index_sequence<>(), + slices...); + using dst_mapping_t = + typename layout_stride::template mapping; + return submdspan_mapping_result { + dst_mapping_t( + mdspan_non_standard, dst_ext, + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::construct_sub_strides( + *this, inv_map, // HIP needs deduction guides to have markups so we need to be explicit // NVCC 11.0 has a bug with deduction guide here, tested that 11.2 does not have // the issue but Clang-CUDA also doesn't accept the use of deduction guide so // disable it for CUDA alltogether #if defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_CUDA) - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple< + decltype(MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + stride_of(slices))...>{ + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of( + slices)...}) + .values), #else - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of( + slices)...}) + .values), #endif - offset - }; + offset + }; } } } - #if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) __builtin_unreachable(); #endif @@ -364,9 +416,8 @@ template struct deduce_layout_right_submapping< IndexType, SubRank, std::index_sequence, SliceSpecifiers...> { - static constexpr size_t Rank = sizeof...(Idx); - using count_range = index_sequence_scan_impl< + using count_range = index_sequence_scan_impl< 0u, (std::is_convertible_v ? 0u : 1u)...>; //__static_partial_sums...>; @@ -382,16 +433,22 @@ struct deduce_layout_right_submapping< // Use layout_right for rank 0 if constexpr (SubRank == 0) { return true; - // Use layout_right for rank 1 result if rightmost slice specifier is range like + // Use layout_right for rank 1 result if rightmost slice specifier is + // range like } else if constexpr (SubRank == 1) { - return ((Idx < Rank - 1 || is_range_slice_v)&&...); + return ((Idx < Rank - 1 || + is_range_slice_v)&&...); } else { // Preserve if rightmost SubRank-1 slices are full_extent_t and // the slice at idx Rank-Subrank is a range and // for idx < Rank - SubRank the slice is an index - return ((((Idx >= Rank - SubRank) && std::is_same_v) || - ((Idx == Rank - SubRank) && is_range_slice_v) || - ((Idx < Rank - SubRank) && is_index_slice_v)) && ...); + return ((((Idx >= Rank - SubRank) && + std::is_same_v) || + ((Idx == Rank - SubRank) && + is_range_slice_v) || + ((Idx < Rank - SubRank) && + is_index_slice_v)) && + ...); } #if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) __builtin_unreachable(); @@ -411,30 +468,43 @@ struct deduce_layout_right_submapping< // then another range slice // then more index slices // e.g. I I R F F F I I I R for obtaining a rank-5 from a rank-10 - return ((((Idx == Rank - 1) && is_range_slice_v) || - ((Idx >= Rank - gap_len - 1 && Idx < Rank - 1) && is_index_slice_v) || - ((Idx > Rank - gap_len - SubRank && Idx < Rank - gap_len - 1) && std::is_same_v) || - ((Idx == Rank - gap_len - SubRank) && is_range_slice_v) || - ((Idx < Rank - gap_len - SubRank) && is_index_slice_v)) && ... ); + return ( + (((Idx == Rank - 1) && is_range_slice_v) || + ((Idx >= Rank - gap_len - 1 && Idx < Rank - 1) && + is_index_slice_v) || + ((Idx > Rank - gap_len - SubRank && Idx < Rank - gap_len - 1) && + std::is_same_v) || + ((Idx == Rank - gap_len - SubRank) && + is_range_slice_v) || + ((Idx < Rank - gap_len - SubRank) && + is_index_slice_v)) && + ...); } }; // We are reusing the same thing for layout_right and layout_right_padded // For layout_right as source StaticStride is static_extent(Rank-1) -template +template struct compute_s_static_layout_right { // Neither StaticStride nor any of the provided extents can be zero. - // StaticStride can never be zero, the static_extents we are looking at are associated with - // integral slice specifiers - which wouldn't be valid for zero extent - template - MDSPAN_INLINE_FUNCTION - static constexpr size_t value(std::index_sequence) { - size_t val = ((Idx >= Extents::rank() - 1 - NumGaps && Idx < Extents::rank() - 1 ? (Extents::static_extent(Idx) == dynamic_extent?0:Extents::static_extent(Idx)) : 1) * ... * (StaticStride == dynamic_extent?0:StaticStride)); - return val == 0?dynamic_extent:val; + // StaticStride can never be zero, the static_extents we are looking at are + // associated with integral slice specifiers - which wouldn't be valid for + // zero extent + template + MDSPAN_INLINE_FUNCTION static constexpr size_t value( + std::index_sequence) { + size_t val = + ((Idx >= Extents::rank() - 1 - NumGaps && Idx < Extents::rank() - 1 + ? (Extents::static_extent(Idx) == dynamic_extent + ? 0 + : Extents::static_extent(Idx)) + : 1) * + ... * (StaticStride == dynamic_extent ? 0 : StaticStride)); + return val == 0 ? dynamic_extent : val; } }; -} // namespace detail +} // namespace detail // Actual submdspan mapping call template @@ -442,17 +512,15 @@ template MDSPAN_INLINE_FUNCTION constexpr auto layout_right::mapping::submdspan_mapping_impl( SliceSpecifiers... slices) const { - // compute sub extents using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); + auto dst_ext = submdspan_extents(extents(), slices...); using dst_ext_t = decltype(dst_ext); // figure out sub layout type using deduce_layout = detail::deduce_layout_right_submapping< typename dst_ext_t::index_type, dst_ext_t::rank(), - std::make_index_sequence, - SliceSpecifiers...>; + std::make_index_sequence, SliceSpecifiers...>; // Figure out if any slice's lower bound equals the corresponding extent. // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. @@ -468,8 +536,14 @@ layout_right::mapping::submdspan_mapping_impl( return submdspan_mapping_result{dst_mapping_t(dst_ext), offset}; } else if constexpr (deduce_layout::layout_right_padded_value()) { - constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_left::value(std::make_index_sequence()); - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded::template mapping; + constexpr size_t S_static = + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_left< + Extents, deduce_layout::gap_len, + Extents::static_extent(Extents::rank() - 1)>:: + value(std::make_index_sequence()); + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded< + S_static>::template mapping; return submdspan_mapping_result{ dst_mapping_t(dst_ext, stride(src_ext_t::rank() - 2 - deduce_layout::gap_len)), @@ -488,10 +562,14 @@ layout_right::mapping::submdspan_mapping_impl( // the issue but Clang-CUDA also doesn't accept the use of deduction guide so // disable it for CUDA altogether #if defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_CUDA) - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ - detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple< + decltype(detail::stride_of(slices))...>{ + detail::stride_of(slices)...}) + .values), #else - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ + detail::stride_of(slices)...}) + .values), #endif offset }; @@ -505,71 +583,100 @@ template template template MDSPAN_INLINE_FUNCTION constexpr auto -MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded::mapping::submdspan_mapping_impl( - SliceSpecifiers... slices) const { - +MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded::mapping< + Extents>::submdspan_mapping_impl(SliceSpecifiers... slices) const { // compute sub extents using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); + auto dst_ext = submdspan_extents(extents(), slices...); using dst_ext_t = decltype(dst_ext); - if constexpr (Extents::rank() == 0) { // rank-0 case - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded::template mapping; + if constexpr (Extents::rank() == 0) { // rank-0 case + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded< + PaddingValue>::template mapping; return submdspan_mapping_result{*this, 0}; } else { // Figure out if any slice's lower bound equals the corresponding extent. // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. // figure out sub layout type const bool out_of_bounds = - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::any_slice_out_of_bounds(this->extents(), slices...); + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::any_slice_out_of_bounds( + this->extents(), slices...); auto offset = static_cast( - out_of_bounds ? this->required_span_size() - : this->operator()(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::first_of(slices)...)); - if constexpr (dst_ext_t::rank() == 0) { // result rank-0 + out_of_bounds + ? this->required_span_size() + : this->operator()( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::first_of(slices)...)); + if constexpr (dst_ext_t::rank() == 0) { // result rank-0 // Same issue as in layout_left_padded: see comment there - // using dst_mapping_t = typename layout_right::template mapping; - // return submdspan_mapping_result{dst_mapping_t{dst_ext}, offset}; - return submdspan_mapping_result> - {typename layout_right::template mapping{dst_ext}, offset}; - } else { // general case - using deduce_layout = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::deduce_layout_right_submapping< - typename dst_ext_t::index_type, dst_ext_t::rank(), - decltype(std::make_index_sequence()), - SliceSpecifiers...>; - - if constexpr (deduce_layout::layout_right_value() && dst_ext_t::rank() == 1) { // getting rank-1 from rightmost - using dst_mapping_t = typename layout_right::template mapping; - return submdspan_mapping_result{dst_mapping_t{dst_ext}, offset}; - } else if constexpr (deduce_layout::layout_right_padded_value()) { // can keep layout_right_padded - constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::compute_s_static_layout_right::value(std::make_index_sequence()); - using dst_mapping_t = typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded::template mapping; + // using dst_mapping_t = typename layout_right::template + // mapping; return + // submdspan_mapping_result{dst_mapping_t{dst_ext}, + // offset}; + return submdspan_mapping_result< + typename layout_right::template mapping>{ + typename layout_right::template mapping{dst_ext}, offset}; + } else { // general case + using deduce_layout = MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + deduce_layout_right_submapping< + typename dst_ext_t::index_type, dst_ext_t::rank(), + decltype(std::make_index_sequence()), + SliceSpecifiers...>; + + if constexpr (deduce_layout::layout_right_value() && + dst_ext_t::rank() == 1) { // getting rank-1 from rightmost + using dst_mapping_t = + typename layout_right::template mapping; + return submdspan_mapping_result{dst_mapping_t{dst_ext}, + offset}; + } else if constexpr ( + deduce_layout::layout_right_padded_value()) { // can keep + // layout_right_padded + constexpr size_t S_static = MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + compute_s_static_layout_right:: + value(std::make_index_sequence()); + using dst_mapping_t = + typename MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded< + S_static>::template mapping; return submdspan_mapping_result{ - dst_mapping_t(dst_ext, stride(Extents::rank() - 2 - deduce_layout::gap_len)), offset}; - } else { // layout_stride - auto inv_map = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::inv_map_rank(std::integral_constant(), - std::index_sequence<>(), slices...); - using dst_mapping_t = typename layout_stride::template mapping; - return submdspan_mapping_result { - dst_mapping_t(mdspan_non_standard, dst_ext, - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::construct_sub_strides( - *this, inv_map, + dst_mapping_t(dst_ext, + stride(Extents::rank() - 2 - deduce_layout::gap_len)), + offset}; + } else { // layout_stride + auto inv_map = MDSPAN_IMPL_STANDARD_NAMESPACE::detail::inv_map_rank( + std::integral_constant(), std::index_sequence<>(), + slices...); + using dst_mapping_t = + typename layout_stride::template mapping; + return submdspan_mapping_result { + dst_mapping_t( + mdspan_non_standard, dst_ext, + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::construct_sub_strides( + *this, inv_map, // HIP needs deduction guides to have markups so we need to be explicit // NVCC 11.0 has a bug with deduction guide here, tested that 11.2 does not have // the issue but Clang-CUDA also doesn't accept the use of deduction guide so // disable it for CUDA alltogether #if defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_CUDA) - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple< + decltype(MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + stride_of(slices))...>{ + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of( + slices)...}) + .values), #else - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of(slices)...}).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple{ + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::stride_of( + slices)...}) + .values), #endif - offset - }; + offset + }; } } } - #if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) __builtin_unreachable(); #endif @@ -583,10 +690,10 @@ template MDSPAN_INLINE_FUNCTION constexpr auto layout_stride::mapping::submdspan_mapping_impl( SliceSpecifiers... slices) const { - auto dst_ext = submdspan_extents(extents(), slices...); + auto dst_ext = submdspan_extents(extents(), slices...); using dst_ext_t = decltype(dst_ext); - auto inv_map = detail::inv_map_rank(std::integral_constant(), - std::index_sequence<>(), slices...); + auto inv_map = detail::inv_map_rank(std::integral_constant(), + std::index_sequence<>(), slices...); using dst_mapping_t = typename layout_stride::template mapping; // Figure out if any slice's lower bound equals the corresponding extent. @@ -606,16 +713,20 @@ layout_stride::mapping::submdspan_mapping_impl( // the issue but Clang-CUDA also doesn't accept the use of deduction guide so // disable it for CUDA alltogether #if defined(MDSPAN_IMPL_HAS_HIP) || defined(MDSPAN_IMPL_HAS_CUDA) - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple( - detail::stride_of(slices)...)).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple< + decltype(detail::stride_of(slices))...>( + detail::stride_of(slices)...)) + .values), #else - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple(detail::stride_of(slices)...)).values), + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::tuple( + detail::stride_of(slices)...)) + .values), #endif offset }; } -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE #if defined __NVCC__ #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ diff --git a/include/experimental/__p2642_bits/layout_padded.hpp b/include/experimental/__p2642_bits/layout_padded.hpp index 713fa2b1..18236dff 100644 --- a/include/experimental/__p2642_bits/layout_padded.hpp +++ b/include/experimental/__p2642_bits/layout_padded.hpp @@ -28,15 +28,12 @@ namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { namespace detail { -template -MDSPAN_INLINE_FUNCTION -constexpr T -find_next_multiple(T alignment, U offset) -{ - if ( alignment == T(0) ) { +template +MDSPAN_INLINE_FUNCTION constexpr T find_next_multiple(T alignment, U offset) { + if (alignment == T(0)) { return T(0); } else { - return ( ( offset + alignment - 1 ) / alignment) * alignment; + return ((offset + alignment - 1) / alignment) * alignment; } } @@ -77,8 +74,8 @@ template struct static_array_type_for_padded_extent { static constexpr size_t padding_value = PaddingValue; - using index_type = typename Extents::index_type; - using extents_type = Extents; + using index_type = typename Extents::index_type; + using extents_type = Extents; using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array< index_type, size_t, dynamic_extent, ::MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: @@ -90,7 +87,7 @@ template struct static_array_type_for_padded_extent< PaddingValue, Extents, ExtentToPadIdx, Rank, std::enable_if_t> { - using index_type = typename Extents::index_type; + using index_type = typename Extents::index_type; using extents_type = Extents; using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array< index_type, size_t, dynamic_extent, 0>; @@ -99,8 +96,8 @@ struct static_array_type_for_padded_extent< template struct padded_extent { static constexpr size_t padding_value = PaddingValue; - using index_type = typename Extents::index_type; - using extents_type = Extents; + using index_type = typename Extents::index_type; + using extents_type = Extents; using static_array_type = typename static_array_type_for_padded_extent< padding_value, Extents, ExtentToPadIdx, Extents::rank()>::type; @@ -122,9 +119,8 @@ struct padded_extent { #endif } - MDSPAN_INLINE_FUNCTION static constexpr static_array_type - init_padding([[maybe_unused]] const Extents &exts, - [[maybe_unused]] size_t pv) { + MDSPAN_INLINE_FUNCTION static constexpr static_array_type init_padding( + [[maybe_unused]] const Extents &exts, [[maybe_unused]] size_t pv) { using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range; if constexpr (Extents::rank() > 1) { auto strd = find_next_multiple(pv, exts.extent(ExtentToPadIdx)); @@ -140,9 +136,9 @@ struct padded_extent { } template - MDSPAN_INLINE_FUNCTION static constexpr static_array_type - init_padding([[maybe_unused]] const Mapping &other_mapping, - std::integral_constant) { + MDSPAN_INLINE_FUNCTION static constexpr static_array_type init_padding( + [[maybe_unused]] const Mapping &other_mapping, + std::integral_constant) { if constexpr (Extents::rank() > 1) { return {other_mapping.stride(PaddingStrideIdx)}; } else { @@ -156,20 +152,21 @@ struct padded_extent { }; template -MDSPAN_INLINE_FUNCTION constexpr bool -check_static_extents_representability() { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; +MDSPAN_INLINE_FUNCTION constexpr bool check_static_extents_representability() { + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; // We cannot check statically for sure if the extents are representable // if we have dynamic values -- this can only be checked by a precondition - // We can check if the product of only the static extents is representable though... + // We can check if the product of only the static extents is representable + // though... using index_type = typename Extents::index_type; - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - if constexpr ( Extents::rank() > 0 ) { + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" + if constexpr (Extents::rank() > 0) { auto prod = index_type(1); for (size_t i = 0; i < Extents::rank(); ++i) { - if (Extents::static_extent(i) == dynamic_extent) - continue; + if (Extents::static_extent(i) == dynamic_extent) continue; if (!check_mul_result_is_nonnegative_and_representable( prod, static_cast(Extents::static_extent(i)))) return false; @@ -181,13 +178,15 @@ check_static_extents_representability() { } template -MDSPAN_INLINE_FUNCTION constexpr bool -check_extents_representability(const Extents &exts) { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; +MDSPAN_INLINE_FUNCTION constexpr bool check_extents_representability( + const Extents &exts) { + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; using index_type = typename Extents::index_type; - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - if constexpr ( Extents::rank() > 0 ) { + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" + if constexpr (Extents::rank() > 0) { auto prod = index_type(1); for (size_t i = 0; i < Extents::rank(); ++i) { if (!check_mul_result_is_nonnegative_and_representable( @@ -203,24 +202,29 @@ check_extents_representability(const Extents &exts) { template MDSPAN_INLINE_FUNCTION constexpr bool check_static_extents_and_left_padding_representability() { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; if constexpr (Extents::rank() < 2) { return true; } - // We cannot check statically for sure if the product of the extents and padding value - // are representable if we have dynamic values -- this can only be checked by a precondition - // We can check if the product of only the static extents and potentially the padding value (if it is static) - // is representable though... - // We already checked that StaticPaddingValue is representable by index_type - - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - if constexpr ( Extents::rank() > 0 ) { - auto prod = (StaticPaddingValue != dynamic_extent) ? static_cast< CheckType >(StaticPaddingValue) : CheckType(1); + // We cannot check statically for sure if the product of the extents and + // padding value are representable if we have dynamic values -- this can only + // be checked by a precondition We can check if the product of only the static + // extents and potentially the padding value (if it is static) is + // representable though... We already checked that StaticPaddingValue is + // representable by index_type + + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" + if constexpr (Extents::rank() > 0) { + auto prod = (StaticPaddingValue != dynamic_extent) + ? static_cast(StaticPaddingValue) + : CheckType(1); for (size_t i = 1; i < Extents::rank(); ++i) { - if (Extents::static_extent(i) == dynamic_extent) - continue; - if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(Extents::static_extent(i)))) + if (Extents::static_extent(i) == dynamic_extent) continue; + if (!check_mul_result_is_nonnegative_and_representable( + prod, static_cast(Extents::static_extent(i)))) return false; prod *= Extents::static_extent(i); } @@ -231,13 +235,14 @@ check_static_extents_and_left_padding_representability() { template MDSPAN_INLINE_FUNCTION constexpr bool -check_extents_and_left_padding_representability(const Extents &exts, - [[maybe_unused]] size_t dynamic_padding_value) { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; - - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - // And also a rank 1 layout cannot overflow - if constexpr ( Extents::rank() > 1 ) { +check_extents_and_left_padding_representability( + const Extents &exts, [[maybe_unused]] size_t dynamic_padding_value) { + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; + + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" And also a rank 1 layout cannot overflow + if constexpr (Extents::rank() > 1) { auto prod = static_cast(dynamic_padding_value); for (size_t i = 1; i < Extents::rank(); ++i) { if (!check_mul_result_is_nonnegative_and_representable( @@ -253,22 +258,26 @@ check_extents_and_left_padding_representability(const Extents &exts, template MDSPAN_INLINE_FUNCTION constexpr bool check_static_extents_and_right_padding_representability() { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; - - // We cannot check statically for sure if the product of the extents and padding value - // are representable if we have dynamic values -- this can only be checked by a precondition - // We can check if the product of only the static extents and potentially the padding value (if it is static) - // is representable though... - // We already checked that StaticPaddingValue is representable by index_type - - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - // And also a rank 1 layout cannot overflow - if constexpr ( Extents::rank() > 1 ) { - auto prod = (StaticPaddingValue != dynamic_extent) ? static_cast< CheckType >(StaticPaddingValue) : CheckType(1); + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; + + // We cannot check statically for sure if the product of the extents and + // padding value are representable if we have dynamic values -- this can only + // be checked by a precondition We can check if the product of only the static + // extents and potentially the padding value (if it is static) is + // representable though... We already checked that StaticPaddingValue is + // representable by index_type + + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" And also a rank 1 layout cannot overflow + if constexpr (Extents::rank() > 1) { + auto prod = (StaticPaddingValue != dynamic_extent) + ? static_cast(StaticPaddingValue) + : CheckType(1); for (size_t i = 0; i < Extents::rank() - 1; ++i) { - if (Extents::static_extent(i) == dynamic_extent) - continue; - if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(Extents::static_extent(i)))) + if (Extents::static_extent(i) == dynamic_extent) continue; + if (!check_mul_result_is_nonnegative_and_representable( + prod, static_cast(Extents::static_extent(i)))) return false; prod *= Extents::static_extent(i); } @@ -279,16 +288,18 @@ check_static_extents_and_right_padding_representability() { template MDSPAN_INLINE_FUNCTION constexpr bool -check_extents_and_right_padding_representability(const Extents &exts, - [[maybe_unused]] size_t dynamic_padding_value) { - using MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_mul_result_is_nonnegative_and_representable; - - // get rid of NVCC warning "pointless comparison of unsigned integer with zero" - // And also a rank 1 layout cannot overflow - if constexpr ( Extents::rank() > 1 ) { +check_extents_and_right_padding_representability( + const Extents &exts, [[maybe_unused]] size_t dynamic_padding_value) { + using MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: + check_mul_result_is_nonnegative_and_representable; + + // get rid of NVCC warning "pointless comparison of unsigned integer with + // zero" And also a rank 1 layout cannot overflow + if constexpr (Extents::rank() > 1) { auto prod = static_cast(dynamic_padding_value); for (size_t i = 0; i < Extents::rank() - 1; ++i) { - if (!check_mul_result_is_nonnegative_and_representable(prod, static_cast< CheckType >(exts.extent(i)))) + if (!check_mul_result_is_nonnegative_and_representable( + prod, static_cast(exts.extent(i)))) return false; prod *= exts.extent(i); } @@ -296,60 +307,76 @@ check_extents_and_right_padding_representability(const Extents &exts, return true; } -} // namespace detail +} // namespace detail template template class layout_left_padded::mapping { -public: + public: static constexpr size_t padding_value = PaddingValue; using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left_padded; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_left_padded; #ifndef MDSPAN_INTERNAL_TEST -private: -#endif // MDSPAN_INTERNAL_TEST - - static constexpr rank_type padded_stride_idx = detail::layout_padded_constants::padded_stride_idx; - static constexpr rank_type extent_to_pad_idx = detail::layout_padded_constants::extent_to_pad_idx; - - static_assert((padding_value != 0) - || (extents_type::static_extent(extent_to_pad_idx) == 0) - || (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent), + private: +#endif // MDSPAN_INTERNAL_TEST + + static constexpr rank_type padded_stride_idx = + detail::layout_padded_constants::padded_stride_idx; + static constexpr rank_type extent_to_pad_idx = + detail::layout_padded_constants::extent_to_pad_idx; + + static_assert((padding_value != 0) || + (extents_type::static_extent(extent_to_pad_idx) == 0) || + (extents_type::static_extent(extent_to_pad_idx) == + dynamic_extent), "out of bounds access for rank 0"); - static_assert(detail::check_static_extents_representability(), "The size of the muiltidimensional index space given by the extents must be representable as a value of index_type"); - static_assert((padding_value == dynamic_extent) || MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range(padding_value), "padding_value must be representable as a value of type index_type"); - - using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >; - - static constexpr size_t static_padding_stride = padded_stride_type::static_value(); - - static_assert(detail::check_static_extents_and_left_padding_representability() - && detail::check_static_extents_and_left_padding_representability(), - "the product of static_padding_stride and static extents 1 through rank must be representable as a value of type size_t and index_type"); + static_assert(detail::check_static_extents_representability(), + "The size of the muiltidimensional index space given by the " + "extents must be representable as a value of index_type"); + static_assert( + (padding_value == dynamic_extent) || + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range( + padding_value), + "padding_value must be representable as a value of type index_type"); + + using padded_stride_type = + detail::padded_extent; + + static constexpr size_t static_padding_stride = + padded_stride_type::static_value(); + + static_assert( + detail::check_static_extents_and_left_padding_representability< + index_type, static_padding_stride, extents_type>() && + detail::check_static_extents_and_left_padding_representability< + size_t, static_padding_stride, extents_type>(), + "the product of static_padding_stride and static extents 1 through rank " + "must be representable as a value of type size_t and index_type"); typename padded_stride_type::static_array_type padded_stride = {}; - extents_type exts = {}; + extents_type exts = {}; - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<>) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence<>) const { return 0; } template - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence, IndexOffset index_offset) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence, IndexOffset index_offset) const { return index_offset; } template - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence, - IndexOffsets... index_offsets) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence, IndexOffsets... index_offsets) const { index_type indices[] = {static_cast(index_offsets)...}; // self-recursive fold trick from // https://github.com/llvm/llvm-project/blob/96e1914aa2e6d8966acbfbe2f4d184201f1aa318/libcxx/include/mdspan/layout_left.h#L144 @@ -363,26 +390,26 @@ class layout_left_padded::mapping { return res; } -public: + public: #if !MDSPAN_HAS_CXX_20 || defined(__NVCC__) MDSPAN_INLINE_FUNCTION - constexpr mapping() - : mapping(extents_type{}) - {} + constexpr mapping() : mapping(extents_type{}) {} #else MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() - requires(static_padding_stride != dynamic_extent) = default; + requires(static_padding_stride != dynamic_extent) + = default; MDSPAN_INLINE_FUNCTION constexpr mapping() requires(static_padding_stride == dynamic_extent) - : mapping(extents_type{}) - {} + : mapping(extents_type{}) {} #endif - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping& operator=(const mapping&) noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping &) noexcept = + default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping &operator=( + const mapping &) noexcept = default; /** * Initializes the mapping with the given extents. @@ -390,9 +417,8 @@ class layout_left_padded::mapping { * \param ext the given extents */ MDSPAN_INLINE_FUNCTION - constexpr mapping(const extents_type& ext) - : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) - { + constexpr mapping(const extents_type &ext) + : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) { MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext)); MDSPAN_IMPL_PRECONDITION( detail::check_extents_and_left_padding_representability( @@ -400,26 +426,28 @@ class layout_left_padded::mapping { } /** - * Initializes the mapping with the given extents and the specified padding value. + * Initializes the mapping with the given extents and the specified padding + * value. * - * This overload participates in overload resolution only if `is_convertible_v` - * is `true` and `is_nothrow_constructible_v` is `true` + * This overload participates in overload resolution only if + * `is_convertible_v` is `true` and + * `is_nothrow_constructible_v` is `true` * * \param ext the given extents * \param padding_value the padding value */ MDSPAN_TEMPLATE_REQUIRES( - class Size, - /* requires */ ( - std::is_convertible_v - && std::is_nothrow_constructible_v - ) - ) + class Size, + /* requires */ (std::is_convertible_v + &&std::is_nothrow_constructible_v)) MDSPAN_INLINE_FUNCTION constexpr mapping(const extents_type &ext, Size dynamic_padding_value) - : padded_stride(padded_stride_type::init_padding(ext, dynamic_padding_value)), exts(ext) - { - assert((padding_value == dynamic_extent) || (static_cast(padding_value) == static_cast(dynamic_padding_value))); + : padded_stride( + padded_stride_type::init_padding(ext, dynamic_padding_value)), + exts(ext) { + assert((padding_value == dynamic_extent) || + (static_cast(padding_value) == + static_cast(dynamic_padding_value))); MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext)); MDSPAN_IMPL_PRECONDITION( detail::check_extents_and_left_padding_representability( @@ -539,13 +567,13 @@ class layout_left_padded::mapping { exts, padded_stride.value(0))); } - MDSPAN_INLINE_FUNCTION constexpr const extents_type & - extents() const noexcept { + MDSPAN_INLINE_FUNCTION constexpr const extents_type &extents() + const noexcept { return exts; } - constexpr std::array - strides() const noexcept { + constexpr std::array strides() + const noexcept { if constexpr (extents_type::rank() == 0) { return {}; } else if constexpr (extents_type::rank() == 1) { @@ -565,8 +593,8 @@ class layout_left_padded::mapping { } } - MDSPAN_INLINE_FUNCTION constexpr index_type - required_span_size() const noexcept { + MDSPAN_INLINE_FUNCTION constexpr index_type required_span_size() + const noexcept { if constexpr (extents_type::rank() == 0) { return 1; } else if constexpr (extents_type::rank() == 1) { @@ -593,12 +621,12 @@ class layout_left_padded::mapping { /* requires */ (sizeof...(Indices) == extents_type::rank() && (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: are_valid_indices()))) - MDSPAN_INLINE_FUNCTION constexpr size_t - operator()(Indices... idxs) const noexcept { + MDSPAN_INLINE_FUNCTION constexpr size_t operator()( + Indices... idxs) const noexcept { #if !defined(NDEBUG) ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG +#endif // ! NDEBUG return compute_offset(std::index_sequence_for{}, idxs...); } @@ -629,12 +657,10 @@ class layout_left_padded::mapping { MDSPAN_INLINE_FUNCTION constexpr index_type stride(rank_type r) const noexcept { assert(r < extents_type::rank()); - if (r == 0) - return index_type(1); + if (r == 0) return index_type(1); index_type value = padded_stride.value(0); - for (rank_type k = 1; k < r; k++) - value *= exts.extent(k); + for (rank_type k = 1; k < r; k++) value *= exts.extent(k); return value; } @@ -653,8 +679,8 @@ class layout_left_padded::mapping { class Mapping, /* requires */ (detail::is_layout_left_padded_mapping::value && (Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const mapping &left, const Mapping &right) noexcept { + MDSPAN_INLINE_FUNCTION friend constexpr bool operator==( + const mapping &left, const Mapping &right) noexcept { // Workaround for some compilers not short-circuiting properly with // compile-time checks i.e. we can't access stride(_padding_stride_idx) of a // rank 0 mapping @@ -677,78 +703,92 @@ class layout_left_padded::mapping { class Mapping, /* requires */ (detail::is_layout_left_padded_mapping::value && (Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(const mapping &left, const Mapping &right) noexcept { + MDSPAN_INLINE_FUNCTION friend constexpr bool operator!=( + const mapping &left, const Mapping &right) noexcept { return !(left == right); } #endif - // [mdspan.submdspan.mapping], submdspan mapping specialization - template - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template - MDSPAN_INLINE_FUNCTION - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } + // [mdspan.submdspan.mapping], submdspan mapping specialization + template + MDSPAN_INLINE_FUNCTION constexpr auto submdspan_mapping_impl( + SliceSpecifiers... slices) const; + + template + MDSPAN_INLINE_FUNCTION friend constexpr auto submdspan_mapping( + const mapping &src, SliceSpecifiers... slices) { + return src.submdspan_mapping_impl(slices...); + } }; template template class layout_right_padded::mapping { -public: + public: static constexpr size_t padding_value = PaddingValue; using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right_padded; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_right_padded; #ifndef MDSPAN_INTERNAL_TEST - private: -#endif // MDSPAN_INTERNAL_TEST - - static constexpr rank_type padded_stride_idx = detail::layout_padded_constants::padded_stride_idx; - static constexpr rank_type extent_to_pad_idx = detail::layout_padded_constants::extent_to_pad_idx; - - static_assert((padding_value != 0) - || (extents_type::static_extent(extent_to_pad_idx) == 0) - || (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent), - "if padding stride is 0, static_extent(extent-to-pad-rank) must also be 0 or dynamic_extent"); - static_assert(detail::check_static_extents_representability(), "The size of the muiltidimensional index space given by the extents must be representable as a value of index_type"); - static_assert((padding_value == dynamic_extent) || MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range(padding_value), "padding_value must be representable as a value of type index_type"); - - - using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >; - static constexpr size_t static_padding_stride = padded_stride_type::static_value(); - - static_assert(detail::check_static_extents_and_right_padding_representability() - && detail::check_static_extents_and_right_padding_representability(), - "the product of static_padding_stride and static extents 1 through rank must be representable as a value of type size_t and index_type"); + private: +#endif // MDSPAN_INTERNAL_TEST + + static constexpr rank_type padded_stride_idx = + detail::layout_padded_constants::padded_stride_idx; + static constexpr rank_type extent_to_pad_idx = + detail::layout_padded_constants::extent_to_pad_idx; + + static_assert((padding_value != 0) || + (extents_type::static_extent(extent_to_pad_idx) == 0) || + (extents_type::static_extent(extent_to_pad_idx) == + dynamic_extent), + "if padding stride is 0, static_extent(extent-to-pad-rank) " + "must also be 0 or dynamic_extent"); + static_assert(detail::check_static_extents_representability(), + "The size of the muiltidimensional index space given by the " + "extents must be representable as a value of index_type"); + static_assert( + (padding_value == dynamic_extent) || + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::in_range( + padding_value), + "padding_value must be representable as a value of type index_type"); + + using padded_stride_type = + detail::padded_extent; + static constexpr size_t static_padding_stride = + padded_stride_type::static_value(); + + static_assert( + detail::check_static_extents_and_right_padding_representability< + index_type, static_padding_stride, extents_type>() && + detail::check_static_extents_and_right_padding_representability< + size_t, static_padding_stride, extents_type>(), + "the product of static_padding_stride and static extents 1 through rank " + "must be representable as a value of type size_t and index_type"); typename padded_stride_type::static_array_type padded_stride = {}; - extents_type exts = {}; + extents_type exts = {}; - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<>) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence<>) const { return 0; } template - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence, IndexOffset index_offset) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence, IndexOffset index_offset) const { return index_offset; } template - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence, - IndexOffsets... index_offsets) const { + MDSPAN_INLINE_FUNCTION constexpr index_type compute_offset( + std::index_sequence, IndexOffsets... index_offsets) const { // self-recursive fold trick from // https://github.com/llvm/llvm-project/blob/4d9771741d40cc9cfcccb6b033f43689d36b705a/libcxx/include/mdspan/layout_right.h#L141 index_type res = 0; @@ -760,26 +800,26 @@ class layout_right_padded::mapping { return res; } -public: + public: #if !MDSPAN_HAS_CXX_20 || defined(__NVCC__) MDSPAN_INLINE_FUNCTION - constexpr mapping() - : mapping(extents_type{}) - {} + constexpr mapping() : mapping(extents_type{}) {} #else MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr mapping() - requires(static_padding_stride != dynamic_extent) = default; + constexpr mapping() + requires(static_padding_stride != dynamic_extent) + = default; MDSPAN_INLINE_FUNCTION - constexpr mapping() + constexpr mapping() requires(static_padding_stride == dynamic_extent) - : mapping(extents_type{}) - {} + : mapping(extents_type{}) {} #endif - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping& operator=(const mapping&) noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping &) noexcept = + default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping &operator=( + const mapping &) noexcept = default; /** * Initializes the mapping with the given extents. @@ -796,27 +836,28 @@ class layout_right_padded::mapping { } /** - * Initializes the mapping with the given extents and the specified padding value. + * Initializes the mapping with the given extents and the specified padding + * value. * - * This overload participates in overload resolution only if `is_convertible_v` - * is `true` and `is_nothrow_constructible_v` is `true` + * This overload participates in overload resolution only if + * `is_convertible_v` is `true` and + * `is_nothrow_constructible_v` is `true` * * \param ext the given extents * \param padding_value the padding value */ MDSPAN_TEMPLATE_REQUIRES( class Size, - /* requires */ ( - std::is_convertible_v - && std::is_nothrow_constructible_v - ) - ) + /* requires */ (std::is_convertible_v + &&std::is_nothrow_constructible_v)) MDSPAN_INLINE_FUNCTION constexpr mapping(const extents_type &ext, Size dynamic_padding_value) - : padded_stride(padded_stride_type::init_padding(ext, static_cast(dynamic_padding_value))), + : padded_stride(padded_stride_type::init_padding( + ext, static_cast(dynamic_padding_value))), exts(ext) { assert((padding_value == dynamic_extent) || - (static_cast(padding_value) == static_cast(dynamic_padding_value))); + (static_cast(padding_value) == + static_cast(dynamic_padding_value))); MDSPAN_IMPL_PRECONDITION(detail::check_extents_representability(ext)); MDSPAN_IMPL_PRECONDITION( detail::check_extents_and_right_padding_representability( @@ -826,9 +867,12 @@ class layout_right_padded::mapping { /** * Converting constructor from `layout_right::mapping`. * - * This overload participates in overload resolution only if `is_constructible_v` is true. - * If `OtherExtents::rank() > 1` then one of `padding_value`, `static_extent(0)`, or `OtherExtents::static_extent(0)` must be `dynamic_extent`; - * otherwise, `OtherExtents::static_extent(0)` must be equal to the least multiple of `padding_value` greater than or equal to `extents_type::static_extent(0)` + * This overload participates in overload resolution only if + * `is_constructible_v` is true. If + * `OtherExtents::rank() > 1` then one of `padding_value`, `static_extent(0)`, + * or `OtherExtents::static_extent(0)` must be `dynamic_extent`; otherwise, + * `OtherExtents::static_extent(0)` must be equal to the least multiple of + * `padding_value` greater than or equal to `extents_type::static_extent(0)` */ MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, @@ -933,13 +977,13 @@ class layout_right_padded::mapping { exts, padded_stride.value(0))); } - MDSPAN_INLINE_FUNCTION constexpr const extents_type & - extents() const noexcept { + MDSPAN_INLINE_FUNCTION constexpr const extents_type &extents() + const noexcept { return exts; } - constexpr std::array - strides() const noexcept { + constexpr std::array strides() + const noexcept { if constexpr (extents_type::rank() == 0) { return {}; } else if constexpr (extents_type::rank() == 1) { @@ -958,8 +1002,8 @@ class layout_right_padded::mapping { } } - MDSPAN_INLINE_FUNCTION constexpr index_type - required_span_size() const noexcept { + MDSPAN_INLINE_FUNCTION constexpr index_type required_span_size() + const noexcept { if constexpr (extents_type::rank() == 0) { return 1; } else if constexpr (extents_type::rank() == 1) { @@ -986,8 +1030,8 @@ class layout_right_padded::mapping { /* requires */ (sizeof...(Indices) == extents_type::rank() && (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: are_valid_indices()))) - MDSPAN_INLINE_FUNCTION constexpr size_t - operator()(Indices... idxs) const noexcept { + MDSPAN_INLINE_FUNCTION constexpr size_t operator()( + Indices... idxs) const noexcept { return compute_offset(std::index_sequence_for{}, idxs...); } @@ -1015,11 +1059,10 @@ class layout_right_padded::mapping { return true; } - MDSPAN_INLINE_FUNCTION constexpr index_type - stride(rank_type r) const noexcept { + MDSPAN_INLINE_FUNCTION constexpr index_type stride( + rank_type r) const noexcept { assert(r < extents_type::rank()); - if (r == extents_type::rank() - 1) - return index_type(1); + if (r == extents_type::rank() - 1) return index_type(1); index_type value = padded_stride.value(0); for (rank_type k = extents_type::rank() - 2; k > r; k--) @@ -1042,8 +1085,8 @@ class layout_right_padded::mapping { class Mapping, /* requires */ (detail::is_layout_right_padded_mapping::value && (Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const mapping &left, const Mapping &right) noexcept { + MDSPAN_INLINE_FUNCTION friend constexpr bool operator==( + const mapping &left, const Mapping &right) noexcept { // Workaround for some compilers not short-circuiting properly with // compile-time checks i.e. we can't access stride(_padding_stride_idx) of a // rank 0 mapping @@ -1066,24 +1109,22 @@ class layout_right_padded::mapping { class Mapping, /* requires */ (detail::is_layout_right_padded_mapping::value && (Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(const mapping &left, const Mapping &right) noexcept { + MDSPAN_INLINE_FUNCTION friend constexpr bool operator!=( + const mapping &left, const Mapping &right) noexcept { return !(left == right); } #endif - // [mdspan.submdspan.mapping], submdspan mapping specialization - template - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template - MDSPAN_INLINE_FUNCTION - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } + // [mdspan.submdspan.mapping], submdspan mapping specialization + template + MDSPAN_INLINE_FUNCTION constexpr auto submdspan_mapping_impl( + SliceSpecifiers... slices) const; + + template + MDSPAN_INLINE_FUNCTION friend constexpr auto submdspan_mapping( + const mapping &src, SliceSpecifiers... slices) { + return src.submdspan_mapping_impl(slices...); + } }; -} -} +} // namespace MDSPAN_IMPL_PROPOSED_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/experimental/__p2642_bits/layout_padded_fwd.hpp b/include/experimental/__p2642_bits/layout_padded_fwd.hpp index 481b1d5c..7a8ef5ca 100644 --- a/include/experimental/__p2642_bits/layout_padded_fwd.hpp +++ b/include/experimental/__p2642_bits/layout_padded_fwd.hpp @@ -35,21 +35,21 @@ struct layout_right_padded { }; namespace detail { -// The layout_padded_constants structs are only useful if rank > 1, otherwise they may wrap +// The layout_padded_constants structs are only useful if rank > 1, otherwise +// they may wrap template struct layout_padded_constants; template -struct layout_padded_constants, ExtentsType> -{ +struct layout_padded_constants, ExtentsType> { using rank_type = typename ExtentsType::rank_type; static constexpr rank_type padded_stride_idx = 1; static constexpr rank_type extent_to_pad_idx = 0; }; template -struct layout_padded_constants, ExtentsType> -{ +struct layout_padded_constants, + ExtentsType> { using rank_type = typename ExtentsType::rank_type; static constexpr rank_type padded_stride_idx = ExtentsType::rank() - 2; static constexpr rank_type extent_to_pad_idx = ExtentsType::rank() - 1; @@ -59,79 +59,96 @@ template struct is_layout_left_padded : std::false_type {}; template -struct is_layout_left_padded> : std::true_type {}; +struct is_layout_left_padded> + : std::true_type {}; template struct is_layout_left_padded_mapping : std::false_type {}; template -struct is_layout_left_padded_mapping::template mapping>::value>> +struct is_layout_left_padded_mapping< + Mapping, + std::enable_if_t:: + template mapping>::value>> : std::true_type {}; template struct is_layout_right_padded : std::false_type {}; template -struct is_layout_right_padded> : std::true_type {}; +struct is_layout_right_padded> + : std::true_type {}; template struct is_layout_right_padded_mapping : std::false_type {}; template -struct is_layout_right_padded_mapping::template mapping>::value>> +struct is_layout_right_padded_mapping< + Mapping, + std::enable_if_t:: + template mapping>::value>> : std::true_type {}; - template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>) {} +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_mandates( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>) {} template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>) {} +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_mandates( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>) {} template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank) -{ - using extents_type = typename PaddedLayoutMappingType::extents_type; +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_mandates( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank) { + using extents_type = typename PaddedLayoutMappingType::extents_type; constexpr auto padding_value = PaddedLayoutMappingType::padding_value; - constexpr auto idx = layout_padded_constants::extent_to_pad_idx; + constexpr auto idx = + layout_padded_constants::extent_to_pad_idx; constexpr auto statically_determinable = - (LayoutExtentsType::static_extent(idx) != dynamic_extent) && - (extents_type::static_extent(idx) != dynamic_extent) && - (padding_value != dynamic_extent); - - static_assert(!statically_determinable || - (padding_value == 0 - ? LayoutExtentsType::static_extent(idx) == 0 - : LayoutExtentsType::static_extent(idx) % padding_value == 0), - ""); + (LayoutExtentsType::static_extent(idx) != dynamic_extent) && + (extents_type::static_extent(idx) != dynamic_extent) && + (padding_value != dynamic_extent); + + static_assert( + !statically_determinable || + (padding_value == 0 + ? LayoutExtentsType::static_extent(idx) == 0 + : LayoutExtentsType::static_extent(idx) % padding_value == 0), + ""); } template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>, - const OtherMapping&) {} +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_preconditions( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>, + const OtherMapping &) {} template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>, - const OtherMapping&) {} +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_preconditions( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>, + const OtherMapping &) {} template -MDSPAN_INLINE_FUNCTION -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank, - const OtherMapping &other_mapping) { +MDSPAN_INLINE_FUNCTION constexpr void +check_padded_layout_converting_constructor_preconditions( + MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank, + const OtherMapping &other_mapping) { constexpr auto padded_stride_idx = - layout_padded_constants::padded_stride_idx; - constexpr auto extent_to_pad_idx = layout_padded_constants::extent_to_pad_idx; - MDSPAN_IMPL_PRECONDITION(other_mapping.stride(padded_stride_idx) == other_mapping.extents().extent(extent_to_pad_idx)); + layout_padded_constants::padded_stride_idx; + constexpr auto extent_to_pad_idx = + layout_padded_constants::extent_to_pad_idx; + MDSPAN_IMPL_PRECONDITION(other_mapping.stride(padded_stride_idx) == + other_mapping.extents().extent(extent_to_pad_idx)); } - -} -} -} +} // namespace detail +} // namespace MDSPAN_IMPL_PROPOSED_NAMESPACE +} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/include/mdspan/mdarray.hpp b/include/mdspan/mdarray.hpp index fd8f61c5..cf7e7638 100644 --- a/include/mdspan/mdarray.hpp +++ b/include/mdspan/mdarray.hpp @@ -18,14 +18,14 @@ #define MDARRAY_HPP_ #ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos +#define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos #endif #ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental +#define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental #endif #include "mdspan.hpp" #include "../experimental/__p1684_bits/mdarray.hpp" -#endif // MDARRAY_HPP_ +#endif // MDARRAY_HPP_ diff --git a/include/mdspan/mdspan.hpp b/include/mdspan/mdspan.hpp index 4a0e354f..14c59d9e 100644 --- a/include/mdspan/mdspan.hpp +++ b/include/mdspan/mdspan.hpp @@ -18,11 +18,11 @@ #define MDSPAN_HPP_ #ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos +#define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos #endif #ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental +#define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental #endif #include "../experimental/__p0009_bits/default_accessor.hpp" @@ -40,4 +40,4 @@ #endif #include "../experimental/__p2389_bits/dims.hpp" -#endif // MDSPAN_HPP_ +#endif // MDSPAN_HPP_ diff --git a/tests/foo_customizations.hpp b/tests/foo_customizations.hpp index 59ee0214..02f18e28 100644 --- a/tests/foo_customizations.hpp +++ b/tests/foo_customizations.hpp @@ -20,234 +20,255 @@ #include namespace Foo { - template - struct foo_ptr { - T* data; - MDSPAN_INLINE_FUNCTION - constexpr foo_ptr(T* ptr):data(ptr) {} - }; - - template - struct foo_accessor { - using offset_policy = foo_accessor; - using element_type = T; - using reference = T&; - using data_handle_type = foo_ptr; - - MDSPAN_INLINE_FUNCTION - constexpr foo_accessor(int* ptr = nullptr) noexcept { flag = ptr; } - - template - MDSPAN_INLINE_FUNCTION - constexpr foo_accessor(Kokkos::default_accessor) noexcept { flag = nullptr; } - - template - MDSPAN_INLINE_FUNCTION - constexpr foo_accessor(foo_accessor other) noexcept { flag = other.flag; } - - - MDSPAN_INLINE_FUNCTION - constexpr reference access(data_handle_type p, size_t i) const noexcept { - return p.data[i]; - } - - MDSPAN_INLINE_FUNCTION - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { - return data_handle_type(p.data+i); - } - int* flag; +template +struct foo_ptr { + T* data; + MDSPAN_INLINE_FUNCTION + constexpr foo_ptr(T* ptr) : data(ptr) {} +}; - MDSPAN_INLINE_FUNCTION - friend constexpr void swap(foo_accessor& x, foo_accessor& y) { - x.flag[0] = 99; - y.flag[0] = 77; - std::swap(x.flag, y.flag); - } - }; +template +struct foo_accessor { + using offset_policy = foo_accessor; + using element_type = T; + using reference = T&; + using data_handle_type = foo_ptr; + + MDSPAN_INLINE_FUNCTION + constexpr foo_accessor(int* ptr = nullptr) noexcept { flag = ptr; } + + template + MDSPAN_INLINE_FUNCTION constexpr foo_accessor( + Kokkos::default_accessor) noexcept { + flag = nullptr; + } + + template + MDSPAN_INLINE_FUNCTION constexpr foo_accessor( + foo_accessor other) noexcept { + flag = other.flag; + } + + MDSPAN_INLINE_FUNCTION + constexpr reference access(data_handle_type p, size_t i) const noexcept { + return p.data[i]; + } + + MDSPAN_INLINE_FUNCTION + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { + return data_handle_type(p.data + i); + } + int* flag; + + MDSPAN_INLINE_FUNCTION + friend constexpr void swap(foo_accessor& x, foo_accessor& y) { + x.flag[0] = 99; + y.flag[0] = 77; + std::swap(x.flag, y.flag); + } +}; struct layout_foo { - template - class mapping; + template + class mapping; }; template class layout_foo::mapping { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_foo; - private: + public: + using extents_type = Extents; + using index_type = typename extents_type::index_type; + using size_type = typename extents_type::size_type; + using rank_type = typename extents_type::rank_type; + using layout_type = layout_foo; - static_assert(Kokkos::detail::impl_is_extents_v, - "layout_foo::mapping must be instantiated with a specialization of Kokkos::extents."); - static_assert(extents_type::rank() < 3, "layout_foo only supports 0D, 1D and 2D"); + private: + static_assert(Kokkos::detail::impl_is_extents_v, + "layout_foo::mapping must be instantiated with a " + "specialization of Kokkos::extents."); + static_assert(extents_type::rank() < 3, + "layout_foo only supports 0D, 1D and 2D"); - template - friend class mapping; + template + friend class mapping; - public: + public: + //-------------------------------------------------------------------------------- - //-------------------------------------------------------------------------------- + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = + default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; + constexpr mapping(extents_type const& exts) noexcept : m_extents(exts) {} - constexpr mapping(extents_type const& exts) noexcept - :m_extents(exts) - { } - - MDSPAN_TEMPLATE_REQUIRES( + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - MDSPAN_TEMPLATE_REQUIRES( + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { + /* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ + } + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(Kokkos::layout_right::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - {} - - MDSPAN_TEMPLATE_REQUIRES( + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(Kokkos::layout_right::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) {} + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) && - (extents_type::rank() <= 1) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(Kokkos::layout_left::mapping const& other) noexcept // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - {} - - MDSPAN_TEMPLATE_REQUIRES( + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents) && + (extents_type::rank() <= 1))) + MDSPAN_CONDITIONAL_EXPLICIT( + (!std::is_convertible::value)) // needs two () due to comma + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(Kokkos::layout_left::mapping const& + other) noexcept // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) {} + + MDSPAN_TEMPLATE_REQUIRES( class OtherExtents, - /* requires */ ( - MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 - mapping(Kokkos::layout_stride::mapping const& other) // NOLINT(google-explicit-constructor) - :m_extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - #ifndef __CUDA_ARCH__ - size_t stride = 1; - for(rank_type r=m_extents.rank(); r>0; r--) { - if(stride != other.stride(r-1)) - throw std::runtime_error("Assigning layout_stride to layout_foo with invalid strides."); - stride *= m_extents.extent(r-1); - } - #endif - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION - constexpr const extents_type& extents() const noexcept { - return m_extents; + /* requires */ (MDSPAN_IMPL_TRAIT(std::is_constructible, extents_type, + OtherExtents))) + MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) + MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 + mapping(Kokkos::layout_stride::mapping const& + other) // NOLINT(google-explicit-constructor) + : m_extents(other.extents()) { +/* + * TODO: check precondition + * other.required_span_size() is a representable value of type index_type + */ +#ifndef __CUDA_ARCH__ + size_t stride = 1; + for (rank_type r = m_extents.rank(); r > 0; r--) { + if (stride != other.stride(r - 1)) + throw std::runtime_error( + "Assigning layout_stride to layout_foo with invalid strides."); + stride *= m_extents.extent(r - 1); } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type value = 1; - for(rank_type r=0; r != extents_type::rank(); ++r) value*=m_extents.extent(r); - return value; - } - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION - constexpr index_type operator() () const noexcept { return index_type(0); } - - template - MDSPAN_INLINE_FUNCTION - constexpr index_type operator()(Indx0 idx0) const noexcept { - return static_cast(idx0); - } - - template - MDSPAN_INLINE_FUNCTION - constexpr index_type operator()(Indx0 idx0, Indx1 idx1) const noexcept { - return static_cast(idx0 * m_extents.extent(1) + idx1); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { return true; } - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { return true; } - MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return true; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type i) const noexcept { - index_type value = 1; - for(rank_type r=extents_type::rank()-1; r>i; r--) value*=m_extents.extent(r); - return value; - } - - template - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping const& rhs) noexcept { - return lhs.extents() == rhs.extents(); - } - - // In C++ 20 the not equal exists if equal is found +#endif + } + + MDSPAN_INLINE_FUNCTION_DEFAULTED MDSPAN_IMPL_CONSTEXPR_14_DEFAULTED mapping& + operator=(mapping const&) noexcept = default; + + MDSPAN_INLINE_FUNCTION + constexpr const extents_type& extents() const noexcept { return m_extents; } + + MDSPAN_INLINE_FUNCTION + constexpr index_type required_span_size() const noexcept { + index_type value = 1; + for (rank_type r = 0; r != extents_type::rank(); ++r) + value *= m_extents.extent(r); + return value; + } + + //-------------------------------------------------------------------------------- + + MDSPAN_INLINE_FUNCTION + constexpr index_type operator()() const noexcept { return index_type(0); } + + template + MDSPAN_INLINE_FUNCTION constexpr index_type operator()( + Indx0 idx0) const noexcept { + return static_cast(idx0); + } + + template + MDSPAN_INLINE_FUNCTION constexpr index_type operator()( + Indx0 idx0, Indx1 idx1) const noexcept { + return static_cast(idx0 * m_extents.extent(1) + idx1); + } + + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { + return true; + } + MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { + return true; + } + + MDSPAN_INLINE_FUNCTION + constexpr index_type stride(rank_type i) const noexcept { + index_type value = 1; + for (rank_type r = extents_type::rank() - 1; r > i; r--) + value *= m_extents.extent(r); + return value; + } + + template + MDSPAN_INLINE_FUNCTION friend constexpr bool operator==( + mapping const& lhs, mapping const& rhs) noexcept { + return lhs.extents() == rhs.extents(); + } + + // In C++ 20 the not equal exists if equal is found #if MDSPAN_HAS_CXX_20 - template - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping const& rhs) noexcept { - return lhs.extents() != rhs.extents(); - } + template + MDSPAN_INLINE_FUNCTION friend constexpr bool operator!=( + mapping const& lhs, mapping const& rhs) noexcept { + return lhs.extents() != rhs.extents(); + } #endif #if MDSPAN_HAS_CXX_17 - template - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - // use the fact that layout_foo is layout_right with rank 1 or rank 2 - // i.e. we don't need to implement everything here, we just reuse submdspan_mapping for layout_right - Kokkos::layout_right::mapping compatible_mapping(src.extents()); - auto sub_right = submdspan_mapping(compatible_mapping, slices...); - if constexpr (std::is_same_v) { - // NVCC does not like deduction here, so get the extents type explicitly - using sub_ext_t = std::remove_const_t>; - auto sub_mapping = layout_foo::mapping(sub_right.mapping.extents()); - return Kokkos::submdspan_mapping_result{sub_mapping, sub_right.offset}; - } else { - return sub_right; - } - } + template + friend constexpr auto submdspan_mapping(const mapping& src, + SliceSpecifiers... slices) { + // use the fact that layout_foo is layout_right with rank 1 or rank 2 + // i.e. we don't need to implement everything here, we just reuse + // submdspan_mapping for layout_right + Kokkos::layout_right::mapping compatible_mapping(src.extents()); + auto sub_right = submdspan_mapping(compatible_mapping, slices...); + if constexpr (std::is_same_v< + typename decltype(sub_right.mapping)::layout_type, + Kokkos::layout_right>) { + // NVCC does not like deduction here, so get the extents type explicitly + using sub_ext_t = std::remove_const_t< + std::remove_reference_t>; + auto sub_mapping = + layout_foo::mapping(sub_right.mapping.extents()); + return Kokkos::submdspan_mapping_result{ + sub_mapping, sub_right.offset}; + } else { + return sub_right; + } + } #endif -private: - MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; - + private: + MDSPAN_IMPL_NO_UNIQUE_ADDRESS extents_type m_extents{}; }; -} +} // namespace Foo #endif diff --git a/tests/libcxx-backports/ConvertibleToIntegral.h b/tests/libcxx-backports/ConvertibleToIntegral.h index 2f31941a..c2fc5d08 100644 --- a/tests/libcxx-backports/ConvertibleToIntegral.h +++ b/tests/libcxx-backports/ConvertibleToIntegral.h @@ -12,7 +12,7 @@ struct IntType { int val; constexpr IntType() = default; - constexpr IntType(int v) noexcept : val(v){} + constexpr IntType(int v) noexcept : val(v) {} constexpr bool operator==(const IntType& rhs) const { return val == rhs.val; } constexpr operator int() const noexcept { return val; } @@ -24,7 +24,7 @@ struct IntType { struct IntTypeNC { int val; constexpr IntTypeNC() = default; - constexpr IntTypeNC(int v) noexcept : val(v){} + constexpr IntTypeNC(int v) noexcept : val(v) {} constexpr bool operator==(const IntType& rhs) const { return val == rhs.val; } constexpr operator int() noexcept { return val; } @@ -33,12 +33,20 @@ struct IntTypeNC { }; // weird configurability of convertibility to int -template +template struct IntConfig { int val; - constexpr explicit IntConfig(int val_):val(val_){} - constexpr operator int() noexcept(ctor_nt_nc) requires(conv_nc) { return val; } - constexpr operator int() const noexcept(ctor_nt_c) requires(conv_c) { return val; } + constexpr explicit IntConfig(int val_) : val(val_) {} + constexpr operator int() noexcept(ctor_nt_nc) + requires(conv_nc) + { + return val; + } + constexpr operator int() const noexcept(ctor_nt_c) + requires(conv_c) + { + return val; + } }; -#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_CONVERTIBLE_TO_INTEGRAL_H +#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_CONVERTIBLE_TO_INTEGRAL_H diff --git a/tests/libcxx-backports/CustomTestLayouts.h b/tests/libcxx-backports/CustomTestLayouts.h index 36eb05f6..83c6dbe9 100644 --- a/tests/libcxx-backports/CustomTestLayouts.h +++ b/tests/libcxx-backports/CustomTestLayouts.h @@ -44,7 +44,7 @@ struct not_extents_constructible_tag {}; template class layout_wrapping_integral { -public: + public: template class mapping; }; @@ -52,36 +52,40 @@ class layout_wrapping_integral { template template class layout_wrapping_integral::mapping { - static constexpr typename Extents::index_type Wrap = static_cast(WrapArg); + static constexpr typename Extents::index_type Wrap = + static_cast(WrapArg); -public: + public: using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_wrapping_integral; -private: - static constexpr bool required_span_size_is_representable(const extents_type& ext) { - if constexpr (extents_type::rank() == 0) - return true; + private: + static constexpr bool required_span_size_is_representable( + const extents_type& ext) { + if constexpr (extents_type::rank() == 0) return true; index_type prod = ext.extent(0); for (rank_type r = 1; r < extents_type::rank(); r++) { - bool overflowed = __builtin_mul_overflow(prod, std::min(ext.extent(r), Wrap), &prod); - if (overflowed) - return false; + bool overflowed = + __builtin_mul_overflow(prod, std::min(ext.extent(r), Wrap), &prod); + if (overflowed) return false; } return true; } -public: + public: constexpr mapping() noexcept = delete; - constexpr mapping(const mapping& other) noexcept : extents_(other.extents()){} + constexpr mapping(const mapping& other) noexcept + : extents_(other.extents()) {} constexpr mapping(extents_type&& ext) noexcept requires(Wrap == 8) : extents_(ext) {} - constexpr mapping(const extents_type& ext, not_extents_constructible_tag) noexcept : extents_(ext) {} + constexpr mapping(const extents_type& ext, + not_extents_constructible_tag) noexcept + : extents_(ext) {} template requires(std::is_constructible_v && (Wrap != 8)) @@ -125,15 +129,18 @@ class layout_wrapping_integral::mapping { } template - requires((sizeof...(Indices) == extents_type::rank()) && (std::is_convertible_v && ...) && + requires((sizeof...(Indices) == extents_type::rank()) && + (std::is_convertible_v && ...) && (std::is_nothrow_constructible_v && ...)) constexpr index_type operator()(Indices... idx) const noexcept { - std::array idx_a{static_cast(static_cast(idx) % Wrap)...}; + std::array idx_a{ + static_cast(static_cast(idx) % Wrap)...}; return [&](std::index_sequence) { index_type res = 0; ((res = idx_a[extents_type::rank() - 1 - Pos] + - (extents_.extent(extents_type::rank() - 1 - Pos) < Wrap ? extents_.extent(extents_type::rank() - 1 - Pos) - : Wrap) * + (extents_.extent(extents_type::rank() - 1 - Pos) < Wrap + ? extents_.extent(extents_type::rank() - 1 - Pos) + : Wrap) * res), ...); return res; @@ -146,16 +153,14 @@ class layout_wrapping_integral::mapping { constexpr bool is_unique() const noexcept { for (rank_type r = 0; r < extents_type::rank(); r++) { - if (extents_.extent(r) > Wrap) - return false; + if (extents_.extent(r) > Wrap) return false; } return true; } static constexpr bool is_exhaustive() noexcept { return true; } constexpr bool is_strided() const noexcept { for (rank_type r = 0; r < extents_type::rank(); r++) { - if (extents_.extent(r) > Wrap) - return false; + if (extents_.extent(r) > Wrap) return false; } return true; } @@ -171,7 +176,8 @@ class layout_wrapping_integral::mapping { template requires(OtherExtents::rank() == extents_type::rank()) - friend constexpr bool operator==(const mapping& lhs, const mapping& rhs) noexcept { + friend constexpr bool operator==(const mapping& lhs, + const mapping& rhs) noexcept { return lhs.extents() == rhs.extents(); } @@ -190,7 +196,7 @@ class layout_wrapping_integral::mapping { } #endif -private: + private: extents_type extents_{}; }; @@ -205,48 +211,52 @@ constexpr auto construct_mapping(std::layout_right, Extents exts) { } template -constexpr auto construct_mapping(layout_wrapping_integral, Extents exts) { - return typename layout_wrapping_integral::template mapping(exts, not_extents_constructible_tag{}); +constexpr auto construct_mapping(layout_wrapping_integral, + Extents exts) { + return typename layout_wrapping_integral::template mapping( + exts, not_extents_constructible_tag{}); } // This layout does not check convertibility of extents for its conversion ctor // Allows triggering mdspan's ctor static assertion on convertibility of extents // It also allows for negative strides and offsets via runtime arguments class always_convertible_layout { -public: + public: template class mapping; }; template class always_convertible_layout::mapping { -public: + public: using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = always_convertible_layout; -private: - static constexpr bool required_span_size_is_representable(const extents_type& ext) { - if constexpr (extents_type::rank() == 0) - return true; + private: + static constexpr bool required_span_size_is_representable( + const extents_type& ext) { + if constexpr (extents_type::rank() == 0) return true; index_type prod = ext.extent(0); for (rank_type r = 1; r < extents_type::rank(); r++) { bool overflowed = __builtin_mul_overflow(prod, ext.extent(r), &prod); - if (overflowed) - return false; + if (overflowed) return false; } return true; } -public: + public: constexpr mapping() noexcept = delete; constexpr mapping(const mapping& other) noexcept - : extents_(other.extents_), offset_(other.offset_), scaling_(other.scaling_){} - constexpr mapping(const extents_type& ext, index_type offset = 0, index_type scaling = 1) noexcept - : extents_(ext), offset_(offset), scaling_(scaling){} + : extents_(other.extents_), + offset_(other.offset_), + scaling_(other.scaling_) {} + constexpr mapping(const extents_type& ext, index_type offset = 0, + index_type scaling = 1) noexcept + : extents_(ext), offset_(offset), scaling_(scaling) {} template constexpr mapping(const mapping& other) noexcept { @@ -283,14 +293,17 @@ class always_convertible_layout::mapping { } template - requires((sizeof...(Indices) == extents_type::rank()) && (std::is_convertible_v && ...) && + requires((sizeof...(Indices) == extents_type::rank()) && + (std::is_convertible_v && ...) && (std::is_nothrow_constructible_v && ...)) constexpr index_type operator()(Indices... idx) const noexcept { - std::array idx_a{static_cast(static_cast(idx))...}; + std::array idx_a{ + static_cast(static_cast(idx))...}; return offset_ + scaling_ * ([&](std::index_sequence) { index_type res = 0; - ((res = idx_a[extents_type::rank() - 1 - Pos] + extents_.extent(extents_type::rank() - 1 - Pos) * res), + ((res = idx_a[extents_type::rank() - 1 - Pos] + + extents_.extent(extents_type::rank() - 1 - Pos) * res), ...); return res; }(std::make_index_sequence())); @@ -308,15 +321,16 @@ class always_convertible_layout::mapping { requires(extents_type::rank() > 0) { index_type s = 1; - for (rank_type i = 0; i < r; i++) - s *= extents_.extent(i); + for (rank_type i = 0; i < r; i++) s *= extents_.extent(i); return s * scaling_; } template requires(OtherExtents::rank() == extents_type::rank()) - friend constexpr bool operator==(const mapping& lhs, const mapping& rhs) noexcept { - return lhs.extents() == rhs.extents() && lhs.offset_ == rhs.offset && lhs.scaling_ == rhs.scaling_; + friend constexpr bool operator==(const mapping& lhs, + const mapping& rhs) noexcept { + return lhs.extents() == rhs.extents() && lhs.offset_ == rhs.offset && + lhs.scaling_ == rhs.scaling_; } #if MDSPAN_HAS_CXX_23 @@ -333,7 +347,7 @@ class always_convertible_layout::mapping { } #endif -private: + private: template friend class mapping; @@ -341,4 +355,4 @@ class always_convertible_layout::mapping { index_type offset_{}; index_type scaling_{}; }; -#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_CUSTOM_TEST_LAYOUTS_H +#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_CUSTOM_TEST_LAYOUTS_H diff --git a/tests/libcxx-backports/MinimalElementType.h b/tests/libcxx-backports/MinimalElementType.h index 38679089..e8374ae8 100644 --- a/tests/libcxx-backports/MinimalElementType.h +++ b/tests/libcxx-backports/MinimalElementType.h @@ -9,39 +9,37 @@ #ifndef TEST_STD_CONTAINERS_VIEWS_MDSPAN_MINIMAL_ELEMENT_TYPE_H #define TEST_STD_CONTAINERS_VIEWS_MDSPAN_MINIMAL_ELEMENT_TYPE_H -#include +#include // Idiosyncratic element type for mdspan // Make sure we don't assume copyable, default constructible, movable etc. struct MinimalElementType { int val; - constexpr MinimalElementType() = delete; + constexpr MinimalElementType() = delete; constexpr MinimalElementType(const MinimalElementType&) = delete; - constexpr explicit MinimalElementType(int v) noexcept : val(v){} + constexpr explicit MinimalElementType(int v) noexcept : val(v) {} constexpr MinimalElementType& operator=(const MinimalElementType&) = delete; }; // Helper class to create pointer to MinimalElementType -template +template struct ElementPool { constexpr ElementPool() { nc_ptr_ = std::allocator>().allocate(N); - ptr_ = nc_ptr_; - for (int i = 0; i != N; ++i) - std::construct_at(nc_ptr_ + i, 42); + ptr_ = nc_ptr_; + for (int i = 0; i != N; ++i) std::construct_at(nc_ptr_ + i, 42); } constexpr T* get_ptr() { return ptr_; } constexpr ~ElementPool() { - for (int i = 0; i != N; ++i) - std::destroy_at(nc_ptr_ + i); + for (int i = 0; i != N; ++i) std::destroy_at(nc_ptr_ + i); std::allocator>().deallocate(nc_ptr_, N); } -private: + private: std::remove_const_t* nc_ptr_; T* ptr_; }; -#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_MINIMAL_ELEMENT_TYPE_H +#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_MINIMAL_ELEMENT_TYPE_H diff --git a/tests/libcxx-backports/default_accessor/default_accessor.access.pass.cpp b/tests/libcxx-backports/default_accessor/default_accessor.access.pass.cpp index b173bbbd..61943279 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.access.pass.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.access.pass.cpp @@ -27,8 +27,9 @@ constexpr void test_access() { ElementPool, 10> data; T* ptr = data.get_ptr(); std::default_accessor acc; - for(int i = 0; i < 10; i++) { - static_assert(std::is_same_v::reference>); + for (int i = 0; i < 10; i++) { + static_assert(std::is_same_v::reference>); ASSERT_NOEXCEPT(acc.access(ptr, i)); assert(&acc.access(ptr, i) == ptr + i); } diff --git a/tests/libcxx-backports/default_accessor/default_accessor.ctor.conversion.pass.cpp b/tests/libcxx-backports/default_accessor/default_accessor.ctor.conversion.pass.cpp index 807505dc..b345594c 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.ctor.conversion.pass.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.ctor.conversion.pass.cpp @@ -15,7 +15,8 @@ // template // constexpr default_accessor(default_accessor) noexcept {} // -// Constraints: is_convertible_v is true. +// Constraints: is_convertible_v is +// true. #include #include @@ -27,7 +28,7 @@ #include "../MinimalElementType.h" struct Base {}; -struct Derived: public Base {}; +struct Derived : public Base {}; template constexpr void test_conversion() { @@ -46,17 +47,26 @@ constexpr bool test() { test_conversion(); // char is convertible to int, but accessors are not - static_assert(!std::is_constructible_v, std::default_accessor>); + 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>); + 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>); + static_assert(!std::is_constructible_v< + std::default_accessor, + std::default_accessor>); // don't allow conversion from Base to Derived - static_assert(!std::is_constructible_v, std::default_accessor>); + 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>); + static_assert(!std::is_constructible_v, + std::default_accessor>); return true; } diff --git a/tests/libcxx-backports/default_accessor/default_accessor.ctor.default.pass.cpp b/tests/libcxx-backports/default_accessor/default_accessor.ctor.default.pass.cpp index e3226af1..6ae95ccd 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.ctor.default.pass.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.ctor.default.pass.cpp @@ -27,7 +27,8 @@ template constexpr void test_construction() { ASSERT_NOEXCEPT(std::default_accessor{}); [[maybe_unused]] std::default_accessor acc; - static_assert(std::is_trivially_default_constructible_v>); + static_assert( + std::is_trivially_default_constructible_v>); } constexpr bool test() { diff --git a/tests/libcxx-backports/default_accessor/default_accessor.element_type.verify.cpp b/tests/libcxx-backports/default_accessor/default_accessor.element_type.verify.cpp index e7260c8e..8e31caa2 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.element_type.verify.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.element_type.verify.cpp @@ -12,23 +12,25 @@ // template // class default_accessor; -// ElementType is required to be a complete object type that is neither an abstract class type nor an array type. +// ElementType is required to be a complete object type that is neither an +// abstract class type nor an array type. #include #include "../llvm_test_macros.h" class AbstractClass { -public: + public: virtual void method() = 0; }; void not_abstract_class() { - // expected-error-re@*:* {{static assertion failed {{.*}}default_accessor: template argument may not be an abstract class}} + // expected-error-re@*:* {{static assertion failed {{.*}}default_accessor: + // template argument may not be an abstract class}} [[maybe_unused]] std::default_accessor acc; } void not_array_type() { - // expected-error-re@*:* {{static assertion failed {{.*}}default_accessor: template argument may not be an array type}} + // expected-error-re@*:* {{static assertion failed {{.*}}default_accessor: + // template argument may not be an array type}} [[maybe_unused]] std::default_accessor acc; } - diff --git a/tests/libcxx-backports/default_accessor/default_accessor.offset.pass.cpp b/tests/libcxx-backports/default_accessor/default_accessor.offset.pass.cpp index 00142cff..902b51c3 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.offset.pass.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.offset.pass.cpp @@ -10,7 +10,8 @@ // -// constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; +// constexpr data_handle_type offset(data_handle_type p, size_t i) const +// noexcept; // // Effects: Equivalent to: return p+i; @@ -27,8 +28,10 @@ constexpr void test_offset() { ElementPool, 10> data; T* ptr = data.get_ptr(); std::default_accessor acc; - for(int i = 0; i < 10; i++) { - static_assert(std::is_same_v::data_handle_type>); + for (int i = 0; i < 10; i++) { + static_assert( + std::is_same_v::data_handle_type>); ASSERT_NOEXCEPT(acc.offset(ptr, i)); assert(acc.offset(ptr, i) == ptr + i); } diff --git a/tests/libcxx-backports/default_accessor/default_accessor.types.pass.cpp b/tests/libcxx-backports/default_accessor/default_accessor.types.pass.cpp index 4da59bc2..0750d4fd 100644 --- a/tests/libcxx-backports/default_accessor/default_accessor.types.pass.cpp +++ b/tests/libcxx-backports/default_accessor/default_accessor.types.pass.cpp @@ -19,8 +19,8 @@ // ... // }; // -// Each specialization of default_accessor is a trivially copyable type that models semiregular. - +// Each specialization of default_accessor is a trivially copyable type that +// models semiregular. #include #include diff --git a/tests/libcxx-backports/extents/CtorTestCombinations.h b/tests/libcxx-backports/extents/CtorTestCombinations.h index 4b8f4957..54147ff3 100644 --- a/tests/libcxx-backports/extents/CtorTestCombinations.h +++ b/tests/libcxx-backports/extents/CtorTestCombinations.h @@ -19,10 +19,11 @@ // Helper file to implement combinatorical testing of extents constructor // -// std::extents can be constructed from just indices, a std::array, or a std::span -// In each of those cases one can either provide all extents, or just the dynamic ones -// If constructed from std::span, the span needs to have a static extent -// Furthermore, the indices/array/span can have integer types other than index_type +// std::extents can be constructed from just indices, a std::array, or a +// std::span In each of those cases one can either provide all extents, or just +// the dynamic ones If constructed from std::span, the span needs to have a +// static extent Furthermore, the indices/array/span can have integer types +// other than index_type template constexpr void test_runtime_observers(E ext, AllExtents expected) { @@ -41,7 +42,8 @@ constexpr void test_implicit_construction_call(E e, AllExtents all_ext) { template constexpr void test_construction(AllExtents all_ext) { // test construction from all extents - Test::template test_construction(all_ext, all_ext, std::make_index_sequence()); + Test::template test_construction(all_ext, all_ext, + std::make_index_sequence()); // test construction from just dynamic extents // create an array of just the extents corresponding to dynamic values @@ -54,10 +56,12 @@ constexpr void test_construction(AllExtents all_ext) { dynamic_idx++; } } - Test::template test_construction(all_ext, dyn_ext, std::make_index_sequence()); + Test::template test_construction( + all_ext, dyn_ext, std::make_index_sequence()); } else { std::array dyn_ext{}; - Test::template test_construction(all_ext, dyn_ext, std::make_index_sequence()); + Test::template test_construction( + all_ext, dyn_ext, std::make_index_sequence()); } } @@ -75,18 +79,29 @@ constexpr void test() { test_construction, Test>(std::array{3, 7}); test_construction, Test>(std::array{3, 7}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); - test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); + test_construction, Test>( + std::array{3, 7, 9}); - test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); - test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); - test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); } template diff --git a/tests/libcxx-backports/extents/comparison.pass.cpp b/tests/libcxx-backports/extents/comparison.pass.cpp index 44fb58f1..ab306da1 100644 --- a/tests/libcxx-backports/extents/comparison.pass.cpp +++ b/tests/libcxx-backports/extents/comparison.pass.cpp @@ -11,10 +11,12 @@ // // template // friend constexpr bool operator==(const extents& lhs, -// const extents& rhs) noexcept; +// const extents& rhs) noexcept; // // Returns: true if lhs.rank() equals rhs.rank() and -// if lhs.extent(r) equals rhs.extent(r) for every rank index r of rhs, otherwise false. +// if lhs.extent(r) equals rhs.extent(r) for every rank index r of rhs, +// otherwise false. // #include @@ -59,19 +61,24 @@ constexpr void test_comparison_same_rank() { test_comparison(true, std::extents(5), std::extents(5)); test_comparison(true, std::extents(), std::extents(5)); test_comparison(true, std::extents(5), std::extents()); - test_comparison(true, std::extents(), std::extents< T2, 5>()); + test_comparison(true, std::extents(), std::extents()); test_comparison(false, std::extents(5), std::extents(7)); test_comparison(false, std::extents(), std::extents(7)); test_comparison(false, std::extents(5), std::extents()); test_comparison(false, std::extents(), std::extents()); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 7, 8, 9)); - test_comparison(true, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents()); - test_comparison( - false, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 3, 8, 9)); - test_comparison(false, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(false, std::extents(5, 6, 7, 8, 9), std::extents()); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 7, 8, 9)); + test_comparison(true, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents()); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 3, 8, 9)); + test_comparison(false, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents()); } template diff --git a/tests/libcxx-backports/extents/conversion.pass.cpp b/tests/libcxx-backports/extents/conversion.pass.cpp index edae21fd..313b27ad 100644 --- a/tests/libcxx-backports/extents/conversion.pass.cpp +++ b/tests/libcxx-backports/extents/conversion.pass.cpp @@ -10,7 +10,8 @@ // // template -// constexpr explicit(see below) extents(const extents&) noexcept; +// constexpr explicit(see below) extents(const extents&) noexcept; // // Constraints: // * sizeof...(OtherExtents) == rank() is true. @@ -25,8 +26,9 @@ // every rank index r of other. // // Remarks: The expression inside explicit is equivalent to: -// (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) || -// (numeric_limits::max() < numeric_limits::max()) +// (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) +// || ... ) || (numeric_limits::max() < +// numeric_limits::max()) #include #include @@ -56,7 +58,8 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); @@ -78,45 +81,76 @@ constexpr void test_conversion() { constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(std::is_convertible_v, std::extents>, ""); + static_assert( + std::is_constructible_v, std::extents>, ""); + static_assert( + std::is_convertible_v, std::extents>, ""); // Check that dynamic to static conversion only works explicitly only - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_convertible_v, std::extents>, ""); + static_assert( + std::is_constructible_v, std::extents>, ""); + static_assert( + !std::is_convertible_v, std::extents>, ""); // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(std::is_convertible_v, std::extents>, ""); + static_assert( + std::is_constructible_v, std::extents>, + ""); + static_assert( + std::is_convertible_v, std::extents>, + ""); // Check that dynamic to static conversion only works explicitly only - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_convertible_v, std::extents>, ""); + static_assert( + std::is_constructible_v, std::extents>, + ""); + static_assert( + !std::is_convertible_v, std::extents>, + ""); // Sanity check that smaller index_type to larger index_type conversion works - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(std::is_convertible_v, std::extents>, ""); - - // Check that larger index_type to smaller index_type conversion works explicitly only - static_assert(std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_convertible_v, std::extents>, ""); + static_assert( + std::is_constructible_v, std::extents>, + ""); + static_assert( + std::is_convertible_v, std::extents>, ""); + + // Check that larger index_type to smaller index_type conversion works + // explicitly only + static_assert( + std::is_constructible_v, std::extents>, + ""); + static_assert( + !std::is_convertible_v, std::extents>, + ""); } constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert( + !std::is_constructible_v, std::extents>, ""); + static_assert( + !std::is_constructible_v, std::extents>, ""); + static_assert( + !std::is_constructible_v, std::extents>, + ""); + static_assert(!std::is_constructible_v, + std::extents>, + ""); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_constructible_v, std::extents>, ""); - static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, + std::extents>, + ""); + static_assert( + !std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, + std::extents>, + ""); } constexpr bool test() { diff --git a/tests/libcxx-backports/extents/ctad.pass.cpp b/tests/libcxx-backports/extents/ctad.pass.cpp index 482a99c8..e00df31e 100644 --- a/tests/libcxx-backports/extents/ctad.pass.cpp +++ b/tests/libcxx-backports/extents/ctad.pass.cpp @@ -24,7 +24,7 @@ struct NoDefaultCtorIndex { size_t value; constexpr NoDefaultCtorIndex() = delete; - constexpr NoDefaultCtorIndex(size_t val) : value(val){} + constexpr NoDefaultCtorIndex(size_t val) : value(val) {} constexpr operator size_t() const noexcept { return value; } }; @@ -41,8 +41,10 @@ constexpr bool test() { test(std::extents(1), std::extents(1)); test(std::extents(1, 2u), std::extents(1, 2u)); test(std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9), - std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9)); - test(std::extents(NoDefaultCtorIndex{1}, NoDefaultCtorIndex{2}), std::extents(1, 2)); + std::extents(1, 2u, 3, 4, 5, 6, + 7, 8, 9)); + test(std::extents(NoDefaultCtorIndex{1}, NoDefaultCtorIndex{2}), + std::extents(1, 2)); return true; } diff --git a/tests/libcxx-backports/extents/ctor_default.pass.cpp b/tests/libcxx-backports/extents/ctor_default.pass.cpp index 0e7997ad..7eab0a88 100644 --- a/tests/libcxx-backports/extents/ctor_default.pass.cpp +++ b/tests/libcxx-backports/extents/ctor_default.pass.cpp @@ -13,8 +13,8 @@ // // constexpr extents() noexcept = default; // -// Remarks: since the standard uses an exposition only array member, dynamic extents -// need to be zero intialized! +// Remarks: since the standard uses an exposition only array member, dynamic +// extents need to be zero intialized! #include #include @@ -26,10 +26,12 @@ struct DefaultCtorTest { template - static constexpr void test_construction(AllExtents all_ext, Extents, std::index_sequence) { - // This function gets called twice: once with Extents being just the dynamic ones, and once with all the extents specified. - // We only test during the all extent case, since then Indices is the correct number. This allows us to reuse the same - // testing machinery used in other constructor tests. + static constexpr void test_construction(AllExtents all_ext, Extents, + std::index_sequence) { + // This function gets called twice: once with Extents being just the dynamic + // ones, and once with all the extents specified. We only test during the + // all extent case, since then Indices is the correct number. This allows us + // to reuse the same testing machinery used in other constructor tests. if constexpr (sizeof...(Indices) == E::rank()) { ASSERT_NOEXCEPT(E{}); // Need to construct new expected values, replacing dynamic values with 0 diff --git a/tests/libcxx-backports/extents/ctor_from_array.pass.cpp b/tests/libcxx-backports/extents/ctor_from_array.pass.cpp index d2ad901f..36c42564 100644 --- a/tests/libcxx-backports/extents/ctor_from_array.pass.cpp +++ b/tests/libcxx-backports/extents/ctor_from_array.pass.cpp @@ -12,11 +12,13 @@ // Test construction from array: // // template -// constexpr explicit(N != rank_dynamic()) extents(const array& exts) noexcept; +// constexpr explicit(N != rank_dynamic()) extents(const +// array& exts) noexcept; // // Constraints: // * is_convertible_v is true, -// * is_nothrow_constructible_v is true, and +// * is_nothrow_constructible_v is true, +// and // * N == rank_dynamic() || N == rank() is true. // // Preconditions: @@ -24,7 +26,8 @@ // Er is a static extent, and // * either // - N is zero, or -// - exts[r] is nonnegative and is representable as a value of type index_type +// - exts[r] is nonnegative and is representable as a value of type +// index_type // for every rank index r. // @@ -39,7 +42,8 @@ struct ArrayCtorTest { template - static constexpr void test_construction(std::array all_ext, Extents ext, std::index_sequence) { + static constexpr void test_construction(std::array all_ext, Extents ext, + std::index_sequence) { ASSERT_NOEXCEPT(E(ext)); if constexpr (N == E::rank_dynamic()) { test_implicit_construction_call(ext, all_ext); @@ -64,35 +68,47 @@ int main(int, char**) { using E = std::extents; // check can't construct from too few arguments - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); // check can't construct from rank_dynamic < #args < rank - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); // check can't construct from too many arguments - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); - // test implicit construction fails from span and array if all extents are given + // test implicit construction fails from span and array if all extents are + // given std::array a5{3, 4, 5, 6, 7}; // check that explicit construction works, i.e. no error - static_assert(std::is_constructible_v< std::extents, decltype(a5)>, - "extents unexpectectly not constructible"); + static_assert( + std::is_constructible_v, decltype(a5)>, + "extents unexpectectly not constructible"); // check that implicit construction doesn't work - assert((implicit_construction>(a5).value == false)); + assert((implicit_construction>(a5).value == + false)); - // test construction fails from types not convertible to index_type but convertible to other integer types - static_assert(std::is_convertible_v, "Test helper IntType unexpectedly not convertible to int"); - static_assert(!std::is_constructible_v< std::extents, std::array>, + // test construction fails from types not convertible to index_type but + // convertible to other integer types + static_assert(std::is_convertible_v, + "Test helper IntType unexpectedly not convertible to int"); + static_assert(!std::is_constructible_v, + std::array>, "extents constructible from illegal arguments"); // index_type is not nothrow constructible static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); - static_assert(!std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v, std::array>); + static_assert( + !std::is_nothrow_constructible_v); + static_assert(!std::is_constructible_v, + std::array>); // convertible from non-const to index_type but not from const static_assert(std::is_convertible_v); static_assert(!std::is_convertible_v); static_assert(std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v, std::array>); + static_assert(!std::is_constructible_v, + std::array>); return 0; } diff --git a/tests/libcxx-backports/extents/ctor_from_integral.pass.cpp b/tests/libcxx-backports/extents/ctor_from_integral.pass.cpp index aea4340d..5256ce17 100644 --- a/tests/libcxx-backports/extents/ctor_from_integral.pass.cpp +++ b/tests/libcxx-backports/extents/ctor_from_integral.pass.cpp @@ -15,19 +15,23 @@ // constexpr explicit extents(OtherIndexTypes ... exts) noexcept; // // Let N be sizeof...(OtherIndexTypes), and let -// exts_arr be array{static_cast(std::move(exts))...}. +// exts_arr be array{static_cast(std::move(exts))...}. // // Constraints: // * (is_convertible_v && ...) is true, -// * (is_nothrow_constructible_v && ...) is true, and +// * (is_nothrow_constructible_v && ...) is true, +// and // * N == rank_dynamic() || N == rank() is true. // // Preconditions: -// * If N != rank_dynamic() is true, exts_arr[r] equals Er for each r for which +// * If N != rank_dynamic() is true, exts_arr[r] equals Er for each r for +// which // Er is a static extent, and // * either // - sizeof...(exts) == 0 is true, or -// - each element of exts is nonnegative and is representable as a value of type index_type. +// - each element of exts is nonnegative and is representable as a value of +// type index_type. // #include @@ -40,7 +44,8 @@ struct IntegralCtorTest { template - static constexpr void test_construction(AllExtents all_ext, Extents ext, std::index_sequence) { + static constexpr void test_construction(AllExtents all_ext, Extents ext, + std::index_sequence) { // construction from indices ASSERT_NOEXCEPT(E(ext[Indices]...)); test_runtime_observers(E(ext[Indices]...), all_ext); @@ -55,15 +60,21 @@ int main(int, char**) { using E = std::extents; // check can't construct from too few arguments - static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v, + "extents constructible from illegal arguments"); // check can't construct from rank_dynamic < #args < rank - static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v, + "extents constructible from illegal arguments"); // check can't construct from too many arguments - static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); - - // test construction fails from types not convertible to index_type but convertible to other integer types - static_assert(std::is_convertible_v, "Test helper IntType unexpectedly not convertible to int"); - static_assert(!std::is_constructible_v< std::extents, IntType>, + static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + + // test construction fails from types not convertible to index_type but + // convertible to other integer types + static_assert(std::is_convertible_v, + "Test helper IntType unexpectedly not convertible to int"); + static_assert( + !std::is_constructible_v, IntType>, + "extents constructible from illegal arguments"); return 0; } diff --git a/tests/libcxx-backports/extents/ctor_from_span.pass.cpp b/tests/libcxx-backports/extents/ctor_from_span.pass.cpp index 7f412ff1..259cda0f 100644 --- a/tests/libcxx-backports/extents/ctor_from_span.pass.cpp +++ b/tests/libcxx-backports/extents/ctor_from_span.pass.cpp @@ -12,11 +12,13 @@ // Test construction from span: // // template -// constexpr explicit(N != rank_dynamic()) extents(span exts) noexcept; +// constexpr explicit(N != rank_dynamic()) extents(span +// exts) noexcept; // // Constraints: // * is_convertible_v is true, -// * is_nothrow_constructible_v is true, and +// * is_nothrow_constructible_v is true, +// and // * N == rank_dynamic() || N == rank() is true. // // Preconditions: @@ -24,7 +26,8 @@ // Er is a static extent, and // * either // - N is zero, or -// - exts[r] is nonnegative and is representable as a value of type index_type +// - exts[r] is nonnegative and is representable as a value of type +// index_type // for every rank index r. // @@ -40,7 +43,8 @@ struct SpanCtorTest { template - static constexpr void test_construction(std::array all_ext, Extents ext, std::index_sequence) { + static constexpr void test_construction(std::array all_ext, Extents ext, + std::index_sequence) { ASSERT_NOEXCEPT(E(ext)); if constexpr (N == E::rank_dynamic()) { test_implicit_construction_call(std::span(ext), all_ext); @@ -65,36 +69,48 @@ int main(int, char**) { using E = std::extents; // check can't construct from too few arguments - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); // check can't construct from rank_dynamic < #args < rank - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); // check can't construct from too many arguments - static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, + "extents constructible from illegal arguments"); - // test implicit construction fails from span and array if all extents are given + // test implicit construction fails from span and array if all extents are + // given std::array a5{3, 4, 5, 6, 7}; std::span s5(a5.data(), 5); // check that explicit construction works, i.e. no error - static_assert(std::is_constructible_v< std::extents, decltype(s5)>, - "extents unexpectectly not constructible"); + static_assert( + std::is_constructible_v, decltype(s5)>, + "extents unexpectectly not constructible"); // check that implicit construction doesn't work - assert((implicit_construction>(s5).value == false)); + assert((implicit_construction>(s5).value == + false)); - // test construction fails from types not convertible to index_type but convertible to other integer types - static_assert(std::is_convertible_v, "Test helper IntType unexpectedly not convertible to int"); - static_assert(!std::is_constructible_v< std::extents, std::span>, + // test construction fails from types not convertible to index_type but + // convertible to other integer types + static_assert(std::is_convertible_v, + "Test helper IntType unexpectedly not convertible to int"); + static_assert(!std::is_constructible_v, + std::span>, "extents constructible from illegal arguments"); // index_type is not nothrow constructible static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); - static_assert(!std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v, std::span>); + static_assert( + !std::is_nothrow_constructible_v); + static_assert(!std::is_constructible_v, + std::span>); // convertible from non-const to index_type but not from const static_assert(std::is_convertible_v); static_assert(!std::is_convertible_v); static_assert(std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v, std::span>); + static_assert( + !std::is_constructible_v, std::span>); return 0; } diff --git a/tests/libcxx-backports/extents/dextents.pass.cpp b/tests/libcxx-backports/extents/dextents.pass.cpp index 7a855281..14224548 100644 --- a/tests/libcxx-backports/extents/dextents.pass.cpp +++ b/tests/libcxx-backports/extents/dextents.pass.cpp @@ -27,8 +27,10 @@ void test_alias_template_dextents() { ASSERT_SAME_TYPE(std::dextents, std::extents); ASSERT_SAME_TYPE(std::dextents, std::extents); ASSERT_SAME_TYPE(std::dextents, std::extents); - ASSERT_SAME_TYPE(std::dextents, std::extents); - ASSERT_SAME_TYPE(std::dextents, std::extents); + ASSERT_SAME_TYPE(std::dextents, + std::extents); + ASSERT_SAME_TYPE(std::dextents, + std::extents); } int main(int, char**) { diff --git a/tests/libcxx-backports/extents/obs_static.pass.cpp b/tests/libcxx-backports/extents/obs_static.pass.cpp index e284f337..91af6940 100644 --- a/tests/libcxx-backports/extents/obs_static.pass.cpp +++ b/tests/libcxx-backports/extents/obs_static.pass.cpp @@ -32,8 +32,10 @@ #include "../llvm_test_macros.h" -template -void test_static_observers(std::index_sequence, std::index_sequence) { +template +void test_static_observers(std::index_sequence, + std::index_sequence) { ASSERT_NOEXCEPT(E::rank()); static_assert(E::rank() == rank); ASSERT_NOEXCEPT(E::rank_dynamic()); @@ -50,7 +52,8 @@ void test_static_observers(std::index_sequence, std::index_sequen template void test_static_observers() { test_static_observers( - std::index_sequence(), std::make_index_sequence()); + std::index_sequence(), + std::make_index_sequence()); } template diff --git a/tests/libcxx-backports/extents/types.pass.cpp b/tests/libcxx-backports/extents/types.pass.cpp index 47501d5b..da88641e 100644 --- a/tests/libcxx-backports/extents/types.pass.cpp +++ b/tests/libcxx-backports/extents/types.pass.cpp @@ -18,7 +18,8 @@ // using rank_type = size_t; // // static constexpr rank_type rank() noexcept { return sizeof...(Extents); } -// static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); } +// static constexpr rank_type rank_dynamic() noexcept { return +// dynamic-index(rank()); } // ... // } @@ -36,7 +37,8 @@ void testExtents() { ASSERT_SAME_TYPE(typename E::rank_type, size_t); static_assert(sizeof...(Extents) == E::rank()); - static_assert((static_cast(Extents == std::dynamic_extent) + ...) == E::rank_dynamic()); + static_assert((static_cast(Extents == std::dynamic_extent) + ...) == + E::rank_dynamic()); static_assert(std::regular); static_assert(std::is_trivially_copyable_v); diff --git a/tests/libcxx-backports/layout_left/layout_left.comparison.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.comparison.pass.cpp index 1f797c78..0cc1772e 100644 --- a/tests/libcxx-backports/layout_left/layout_left.comparison.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.comparison.pass.cpp @@ -11,7 +11,8 @@ // // template -// friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; +// friend constexpr bool operator==(const mapping& x, const +// mapping& y) noexcept; // ` // Constraints: extents_type::rank() == OtherExtents::rank() is true. @@ -39,7 +40,8 @@ constexpr X compare_layout_mappings(...) { return {}; } template constexpr auto compare_layout_mappings(E1 e1, E2 e2) - -> decltype(std::layout_left::mapping(e1) == std::layout_left::mapping(e2)) { + -> decltype(std::layout_left::mapping(e1) == + std::layout_left::mapping(e2)) { return true; } @@ -48,25 +50,49 @@ constexpr void test_comparison_different_rank() { constexpr size_t D = std::dynamic_extent; // sanity check same rank - static_assert(compare_layout_mappings(std::extents(5), std::extents(5))); - static_assert(compare_layout_mappings(std::extents(), std::extents(5))); - static_assert(compare_layout_mappings(std::extents(5), std::extents())); - static_assert(compare_layout_mappings(std::extents(), std::extents())); + static_assert( + compare_layout_mappings(std::extents(5), std::extents(5))); + static_assert( + compare_layout_mappings(std::extents(), std::extents(5))); + static_assert( + compare_layout_mappings(std::extents(5), std::extents())); + static_assert( + compare_layout_mappings(std::extents(), std::extents())); // not equality comparable when rank is not the same - static_assert(compare_layout_mappings(std::extents(), std::extents(1)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(1), std::extents()).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(5), std::extents(5, 5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(5, 5), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(5), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents(1)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert( + compare_layout_mappings(std::extents(1), std::extents()) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert(compare_layout_mappings(std::extents(5), + std::extents(5, 5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert(compare_layout_mappings(std::extents(5, 5), + std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(5), std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); } template @@ -78,19 +104,24 @@ constexpr void test_comparison_same_rank() { test_comparison(true, std::extents(5), std::extents(5)); test_comparison(true, std::extents(), std::extents(5)); test_comparison(true, std::extents(5), std::extents()); - test_comparison(true, std::extents(), std::extents< T2, 5>()); + test_comparison(true, std::extents(), std::extents()); test_comparison(false, std::extents(5), std::extents(7)); test_comparison(false, std::extents(), std::extents(7)); test_comparison(false, std::extents(5), std::extents()); test_comparison(false, std::extents(), std::extents()); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 7, 8, 9)); - test_comparison(true, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents()); - test_comparison( - false, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 3, 8, 9)); - test_comparison(false, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(false, std::extents(5, 6, 7, 8, 9), std::extents()); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 7, 8, 9)); + test_comparison(true, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents()); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 3, 8, 9)); + test_comparison(false, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents()); } template diff --git a/tests/libcxx-backports/layout_left/layout_left.ctor.extents.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.ctor.extents.pass.cpp index 41185c8f..ab180f99 100644 --- a/tests/libcxx-backports/layout_left/layout_left.ctor.extents.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.ctor.extents.pass.cpp @@ -12,7 +12,8 @@ // constexpr mapping(const extents_type&) noexcept; // -// Preconditions: The size of the multidimensional index space e is representable +// Preconditions: The size of the multidimensional index space e is +// representable // as a value of type index_type ([basic.fundamental]). // // Effects: Direct-non-list-initializes extents_ with e. diff --git a/tests/libcxx-backports/layout_left/layout_left.ctor.layout_right.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.ctor.layout_right.pass.cpp index 78d54c79..d1613b11 100644 --- a/tests/libcxx-backports/layout_left/layout_left.ctor.layout_right.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.ctor.layout_right.pass.cpp @@ -18,7 +18,8 @@ // - extents_type::rank() <= 1 is true, and // - is_constructible_v is true. // -// Preconditions: other.required_span_size() is representable as a value of type index_type +// Preconditions: other.required_span_size() is representable as a value of type +// index_type #include #include @@ -53,7 +54,8 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); @@ -64,49 +66,68 @@ constexpr void test_conversion() { } template -using lr_mapping_t = typename std::layout_right::template mapping>; +using lr_mapping_t = typename std::layout_right::template mapping< + std::extents>; template -using ll_mapping_t = typename std::layout_left::template mapping>; +using ll_mapping_t = + typename std::layout_left::template mapping>; constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, lr_mapping_t>); - static_assert(std::is_convertible_v, ll_mapping_t>); + static_assert( + std::is_constructible_v, lr_mapping_t>); + static_assert( + std::is_convertible_v, ll_mapping_t>); // Check that dynamic to static conversion only works explicitly - static_assert(std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_convertible_v, ll_mapping_t>); + static_assert( + std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_convertible_v, ll_mapping_t>); // Sanity check that smaller index_type to larger index_type conversion works - static_assert(std::is_constructible_v, lr_mapping_t>); - static_assert(std::is_convertible_v, ll_mapping_t>); - - // Check that larger index_type to smaller index_type conversion works explicitly only - static_assert(std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_convertible_v, ll_mapping_t>); + static_assert( + std::is_constructible_v, lr_mapping_t>); + static_assert( + std::is_convertible_v, ll_mapping_t>); + + // Check that larger index_type to smaller index_type conversion works + // explicitly only + static_assert( + std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_convertible_v, ll_mapping_t>); } constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_constructible_v, lr_mapping_t>); + static_assert(!std::is_constructible_v, + lr_mapping_t>); } constexpr void test_static_extent_mismatch() { - static_assert(!std::is_constructible_v, lr_mapping_t>); + static_assert( + !std::is_constructible_v, lr_mapping_t>); } constexpr void test_rank_greater_one() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_constructible_v, lr_mapping_t>); - static_assert(!std::is_constructible_v, lr_mapping_t>); + static_assert(!std::is_constructible_v, + lr_mapping_t>); + static_assert(!std::is_constructible_v, + lr_mapping_t>); + static_assert(!std::is_constructible_v, + lr_mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_left/layout_left.ctor.layout_stride.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.ctor.layout_stride.pass.cpp index 05417d1b..57320834 100644 --- a/tests/libcxx-backports/layout_left/layout_left.ctor.layout_stride.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.ctor.layout_stride.pass.cpp @@ -17,9 +17,11 @@ // Constraints: is_constructible_v is true. // // Preconditions: -// - If extents_type::rank() > 0 is true, then for all r in the range [0, extents_type::rank()), +// - If extents_type::rank() > 0 is true, then for all r in the range [0, +// extents_type::rank()), // other.stride(r) equals other.extents().fwd-prod-of-extents(r), and -// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]). +// - other.required_span_size() is representable as a value of type index_type +// ([basic.fundamental]). // // Effects: Direct-non-list-initializes extents_ with other.extents(). @@ -80,25 +82,34 @@ constexpr void test_conversion() { } template -using ll_mapping_t = typename std::layout_left::template mapping>; +using ll_mapping_t = + typename std::layout_left::template mapping>; template -using ls_mapping_t = typename std::layout_stride::template mapping>; +using ls_mapping_t = typename std::layout_stride::template mapping< + std::extents>; constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_left/layout_left.ctor.mapping.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.ctor.mapping.pass.cpp index a1cdcabc..8ce45349 100644 --- a/tests/libcxx-backports/layout_left/layout_left.ctor.mapping.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.ctor.mapping.pass.cpp @@ -16,7 +16,8 @@ // Constraints: is_constructible_v is true. // -// Preconditions: other.required_span_size() is representable as a value of type index_type +// Preconditions: other.required_span_size() is representable as a value of type +// index_type #include #include @@ -51,7 +52,8 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); @@ -71,7 +73,8 @@ constexpr void test_conversion() { } template -using mapping_t = typename std::layout_left::template mapping>; +using mapping_t = + typename std::layout_left::template mapping>; constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; @@ -85,20 +88,28 @@ constexpr void test_no_implicit_conversion() { static_assert(!std::is_convertible_v, mapping_t>); // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, mapping_t>); - static_assert(std::is_convertible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + std::is_convertible_v, mapping_t>); // Check that dynamic to static conversion only works explicitly - static_assert(std::is_constructible_v, mapping_t>); - static_assert(!std::is_convertible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + !std::is_convertible_v, mapping_t>); // Sanity check that smaller index_type to larger index_type conversion works - static_assert(std::is_constructible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); static_assert(std::is_convertible_v, mapping_t>); - // Check that larger index_type to smaller index_type conversion works explicitly only - static_assert(std::is_constructible_v, mapping_t>); - static_assert(!std::is_convertible_v, mapping_t>); + // Check that larger index_type to smaller index_type conversion works + // explicitly only + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + !std::is_convertible_v, mapping_t>); } constexpr void test_rank_mismatch() { @@ -106,16 +117,20 @@ constexpr void test_rank_mismatch() { static_assert(!std::is_constructible_v, mapping_t>); static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_left/layout_left.extents.verify.cpp b/tests/libcxx-backports/layout_left/layout_left.extents.verify.cpp index 85995d36..33954107 100644 --- a/tests/libcxx-backports/layout_left/layout_left.extents.verify.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.extents.verify.cpp @@ -23,11 +23,14 @@ #include void not_extents() { - // expected-error-re@*:* {{static assertion failed {{.*}}layout_left::mapping template argument must be a specialization of extents}} + // expected-error-re@*:* {{static assertion failed {{.*}}layout_left::mapping + // template argument must be a specialization of extents}} [[maybe_unused]] std::layout_left::mapping mapping; } void representable() { - // expected-error-re@*:* {{static assertion failed {{.*}}layout_left::mapping product of static extents must be representable as index_type.}} - [[maybe_unused]] std::layout_left::mapping> mapping; + // expected-error-re@*:* {{static assertion failed {{.*}}layout_left::mapping + // product of static extents must be representable as index_type.}} + [[maybe_unused]] std::layout_left::mapping> + mapping; } diff --git a/tests/libcxx-backports/layout_left/layout_left.index_operator.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.index_operator.pass.cpp index 1a3394e7..946f981d 100644 --- a/tests/libcxx-backports/layout_left/layout_left.index_operator.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.index_operator.pass.cpp @@ -31,28 +31,27 @@ #include "../ConvertibleToIntegral.h" -template -concept operator_constraints = requires(Mapping m, Indices ... idxs) { - {std::is_same_v}; +template +concept operator_constraints = requires(Mapping m, Indices... idxs) { + { std::is_same_v }; }; -template - requires( - operator_constraints - ) -constexpr bool check_operator_constraints(Mapping m, Indices ... idxs) { - (void) m(idxs...); +template + requires(operator_constraints) +constexpr bool check_operator_constraints(Mapping m, Indices... idxs) { + (void)m(idxs...); return true; } -template -constexpr bool check_operator_constraints(Mapping, Indices ...) { +template +constexpr bool check_operator_constraints(Mapping, Indices...) { return false; } template constexpr void iterate_left(M m, T& count, Args... args) { - constexpr int r = static_cast(M::extents_type::rank()) - 1 - static_cast(sizeof...(Args)); + constexpr int r = static_cast(M::extents_type::rank()) - 1 - + static_cast(sizeof...(Args)); if constexpr (-1 == r) { ASSERT_NOEXCEPT(m(args...)); assert(count == m(args...)); @@ -83,15 +82,28 @@ constexpr bool test() { test_iteration>(1, 1, 1, 1); // Check operator constraint for number of arguments - static_assert(check_operator_constraints(std::layout_left::mapping>(std::extents(1)), 0)); - static_assert(!check_operator_constraints(std::layout_left::mapping>(std::extents(1)), 0, 0)); + static_assert(check_operator_constraints( + std::layout_left::mapping>(std::extents(1)), + 0)); + static_assert(!check_operator_constraints( + std::layout_left::mapping>(std::extents(1)), + 0, 0)); // Check operator constraint for convertibility of arguments to index_type - static_assert(check_operator_constraints(std::layout_left::mapping>(std::extents(1)), IntType(0))); - static_assert(!check_operator_constraints(std::layout_left::mapping>(std::extents(1)), IntType(0))); - - // Check operator constraint for no-throw-constructibility of index_type from arguments - static_assert(!check_operator_constraints(std::layout_left::mapping>(std::extents(1)), IntType(0))); + static_assert(check_operator_constraints( + std::layout_left::mapping>(std::extents(1)), + IntType(0))); + static_assert(!check_operator_constraints( + std::layout_left::mapping>( + std::extents(1)), + IntType(0))); + + // Check operator constraint for no-throw-constructibility of index_type from + // arguments + static_assert(!check_operator_constraints( + std::layout_left::mapping>( + std::extents(1)), + IntType(0))); return true; } diff --git a/tests/libcxx-backports/layout_left/layout_left.required_span_size.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.required_span_size.pass.cpp index 39eb154a..07483e14 100644 --- a/tests/libcxx-backports/layout_left/layout_left.required_span_size.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.required_span_size.pass.cpp @@ -14,7 +14,6 @@ // // Returns: extents().fwd-prod-of-extents(extents_type::rank()). - #include #include #include @@ -22,7 +21,8 @@ #include "../llvm_test_macros.h" template -constexpr void test_required_span_size(E e, typename E::index_type expected_size) { +constexpr void test_required_span_size(E e, + typename E::index_type expected_size) { using M = std::layout_left::mapping; const M m(e); diff --git a/tests/libcxx-backports/layout_left/layout_left.static_requirements.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.static_requirements.pass.cpp index 329a852e..d058c6f8 100644 --- a/tests/libcxx-backports/layout_left/layout_left.static_requirements.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.static_requirements.pass.cpp @@ -16,7 +16,8 @@ // - is_nothrow_move_assignable_v is true, // - is_nothrow_swappable_v is true, and // -// the following types and expressions are well-formed and have the specified semantics. +// the following types and expressions are well-formed and have the specified +// semantics. // // typename M::extents_type // Result: A type that is a specialization of extents. @@ -28,14 +29,18 @@ // Result: typename M::extents_type::rank_type. // // typename M::layout_type -// Result: A type MP that meets the layout mapping policy requirements ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is true. +// Result: A type MP that meets the layout mapping policy requirements +// ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is +// true. // // m.extents() // Result: const typename M::extents_type& // // m(i...) // Result: typename M::index_type -// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to numeric_limits::max(). +// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to +// numeric_limits::max(). // // m(i...) == m(static_cast(i)...) // Result: bool @@ -43,21 +48,26 @@ // // m.required_span_size() // Result: typename M::index_type -// Returns: If the size of the multidimensional index space m.extents() is 0, then 0, else 1 plus the maximum value of m(i...) for all i. +// Returns: If the size of the multidimensional index space m.extents() is 0, +// then 0, else 1 plus the maximum value of m(i...) for all i. // // m.is_unique() // Result: bool -// Returns: true only if for every i and j where (i != j || ...) is true, m(i...) != m(j...) is true. +// Returns: true only if for every i and j where (i != j || ...) is true, +// m(i...) != m(j...) is true. // // m.is_exhaustive() // Result: bool -// Returns: true only if for all k in the range [0, m.required_span_size()) there exists an i such that m(i...) equals k. +// Returns: true only if for all k in the range [0, m.required_span_size()) +// there exists an i such that m(i...) equals k. // // m.is_strided() // Result: bool -// Returns: true only if for every rank index r of m.extents() there exists an integer -// sr such that, for all i where (i+dr) is a multidimensional index in m.extents() ([mdspan.overview]), -// m((i + dr)...) - m(i...) equals sr +// Returns: true only if for every rank index r of m.extents() there exists +// an integer +// sr such that, for all i where (i+dr) is a multidimensional index +// in m.extents() ([mdspan.overview]), m((i + dr)...) - m(i...) +// equals sr // // m.stride(r) // Preconditions: m.is_strided() is true. @@ -66,15 +76,18 @@ // // M::is_always_unique() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_unique() is true for all possible objects m of type M. +// Returns: true only if m.is_unique() is true for all possible objects m of +// type M. // // M::is_always_exhaustive() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_exhaustive() is true for all possible objects m of type M. +// Returns: true only if m.is_exhaustive() is true for all possible objects m +// of type M. // // M::is_always_strided() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_strided() is true for all possible objects m of type M. +// Returns: true only if m.is_strided() is true for all possible objects m of +// type M. #include #include @@ -97,14 +110,19 @@ void test_mapping_requirements(std::index_sequence) { ASSERT_SAME_TYPE(typename M::rank_type, typename E::rank_type); ASSERT_SAME_TYPE(typename M::layout_type, std::layout_left); ASSERT_SAME_TYPE(typename M::layout_type::template mapping, M); - static_assert(std::is_same_v().extents()), const E&>); - static_assert(std::is_same_v()(Idxs...)), typename M::index_type>); - static_assert(std::is_same_v().required_span_size()), typename M::index_type>); + static_assert( + std::is_same_v().extents()), const E&>); + static_assert(std::is_same_v()(Idxs...)), + typename M::index_type>); + static_assert(std::is_same_v().required_span_size()), + typename M::index_type>); static_assert(std::is_same_v().is_unique()), bool>); - static_assert(std::is_same_v().is_exhaustive()), bool>); + static_assert( + std::is_same_v().is_exhaustive()), bool>); static_assert(std::is_same_v().is_strided()), bool>); if constexpr (E::rank() > 0) - static_assert(std::is_same_v().stride(0)), typename M::index_type>); + static_assert(std::is_same_v().stride(0)), + typename M::index_type>); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); diff --git a/tests/libcxx-backports/layout_left/layout_left.stride.pass.cpp b/tests/libcxx-backports/layout_left/layout_left.stride.pass.cpp index 0e1a73d0..7acfabde 100644 --- a/tests/libcxx-backports/layout_left/layout_left.stride.pass.cpp +++ b/tests/libcxx-backports/layout_left/layout_left.stride.pass.cpp @@ -26,13 +26,13 @@ #include "../llvm_test_macros.h" template -constexpr void test_stride(std::array strides, Args... args) { +constexpr void test_stride( + std::array strides, Args... args) { using M = std::layout_left::mapping; M m(E(args...)); ASSERT_NOEXCEPT(m.stride(0)); - for (size_t r = 0; r < E::rank(); r++) - assert(strides[r] == m.stride(r)); + for (size_t r = 0; r < E::rank(); r++) assert(strides[r] == m.stride(r)); } constexpr bool test() { @@ -40,7 +40,8 @@ constexpr bool test() { test_stride>(std::array{1}, 7); test_stride>(std::array{1}); test_stride>(std::array{1, 7}); - test_stride>(std::array{1, 7, 56, 504}, 7, 9, 10); + test_stride>( + std::array{1, 7, 56, 504}, 7, 9, 10); return true; } diff --git a/tests/libcxx-backports/layout_right/layout_right.comparison.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.comparison.pass.cpp index d8c284e0..61d1b809 100644 --- a/tests/libcxx-backports/layout_right/layout_right.comparison.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.comparison.pass.cpp @@ -11,7 +11,8 @@ // // template -// friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; +// friend constexpr bool operator==(const mapping& x, const +// mapping& y) noexcept; // ` // Constraints: extents_type::rank() == OtherExtents::rank() is true. @@ -39,7 +40,8 @@ constexpr X compare_layout_mappings(...) { return {}; } template constexpr auto compare_layout_mappings(E1 e1, E2 e2) - -> decltype(std::layout_right::mapping(e1) == std::layout_right::mapping(e2)) { + -> decltype(std::layout_right::mapping(e1) == + std::layout_right::mapping(e2)) { return true; } @@ -48,25 +50,49 @@ constexpr void test_comparison_different_rank() { constexpr size_t D = std::dynamic_extent; // sanity check same rank - static_assert(compare_layout_mappings(std::extents(5), std::extents(5))); - static_assert(compare_layout_mappings(std::extents(), std::extents(5))); - static_assert(compare_layout_mappings(std::extents(5), std::extents())); - static_assert(compare_layout_mappings(std::extents(), std::extents())); + static_assert( + compare_layout_mappings(std::extents(5), std::extents(5))); + static_assert( + compare_layout_mappings(std::extents(), std::extents(5))); + static_assert( + compare_layout_mappings(std::extents(5), std::extents())); + static_assert( + compare_layout_mappings(std::extents(), std::extents())); // not equality comparable when rank is not the same - static_assert(compare_layout_mappings(std::extents(), std::extents(1)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(1), std::extents()).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(5), std::extents(5, 5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); - - static_assert(compare_layout_mappings(std::extents(5, 5), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(5), std::extents(5)).does_not_match()); - static_assert(compare_layout_mappings(std::extents(), std::extents()).does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents(1)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert( + compare_layout_mappings(std::extents(1), std::extents()) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert(compare_layout_mappings(std::extents(5), + std::extents(5, 5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); + + static_assert(compare_layout_mappings(std::extents(5, 5), + std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(5), std::extents(5)) + .does_not_match()); + static_assert( + compare_layout_mappings(std::extents(), std::extents()) + .does_not_match()); } template @@ -78,19 +104,24 @@ constexpr void test_comparison_same_rank() { test_comparison(true, std::extents(5), std::extents(5)); test_comparison(true, std::extents(), std::extents(5)); test_comparison(true, std::extents(5), std::extents()); - test_comparison(true, std::extents(), std::extents< T2, 5>()); + test_comparison(true, std::extents(), std::extents()); test_comparison(false, std::extents(5), std::extents(7)); test_comparison(false, std::extents(), std::extents(7)); test_comparison(false, std::extents(5), std::extents()); test_comparison(false, std::extents(), std::extents()); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 7, 8, 9)); - test_comparison(true, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents()); - test_comparison( - false, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 3, 8, 9)); - test_comparison(false, std::extents(5, 7, 9), std::extents(6, 7)); - test_comparison(false, std::extents(5, 6, 7, 8, 9), std::extents()); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 7, 8, 9)); + test_comparison(true, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents()); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 3, 8, 9)); + test_comparison(false, std::extents(5, 7, 9), + std::extents(6, 7)); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents()); } template diff --git a/tests/libcxx-backports/layout_right/layout_right.ctor.extents.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.ctor.extents.pass.cpp index e5c7f8ef..3b9d7e1f 100644 --- a/tests/libcxx-backports/layout_right/layout_right.ctor.extents.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.ctor.extents.pass.cpp @@ -12,7 +12,8 @@ // constexpr mapping(const extents_type&) noexcept; // -// Preconditions: The size of the multidimensional index space e is representable +// Preconditions: The size of the multidimensional index space e is +// representable // as a value of type index_type ([basic.fundamental]). // // Effects: Direct-non-list-initializes extents_ with e. diff --git a/tests/libcxx-backports/layout_right/layout_right.ctor.layout_left.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.ctor.layout_left.pass.cpp index 6bccfdee..902ed261 100644 --- a/tests/libcxx-backports/layout_right/layout_right.ctor.layout_left.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.ctor.layout_left.pass.cpp @@ -18,7 +18,8 @@ // - extents_type::rank() <= 1 is true, and // - is_constructible_v is true. // -// Preconditions: other.required_span_size() is representable as a value of type index_type +// Preconditions: other.required_span_size() is representable as a value of type +// index_type #include #include @@ -53,7 +54,8 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); @@ -64,49 +66,68 @@ constexpr void test_conversion() { } template -using lr_mapping_t = typename std::layout_right::template mapping>; +using lr_mapping_t = typename std::layout_right::template mapping< + std::extents>; template -using ll_mapping_t = typename std::layout_left::template mapping>; +using ll_mapping_t = + typename std::layout_left::template mapping>; constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, ll_mapping_t>); - static_assert(std::is_convertible_v, lr_mapping_t>); + static_assert( + std::is_constructible_v, ll_mapping_t>); + static_assert( + std::is_convertible_v, lr_mapping_t>); // Check that dynamic to static conversion only works explicitly - static_assert(std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_convertible_v, lr_mapping_t>); + static_assert( + std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_convertible_v, lr_mapping_t>); // Sanity check that smaller index_type to larger index_type conversion works - static_assert(std::is_constructible_v, ll_mapping_t>); - static_assert(std::is_convertible_v, lr_mapping_t>); - - // Check that larger index_type to smaller index_type conversion works explicitly only - static_assert(std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_convertible_v, lr_mapping_t>); + static_assert( + std::is_constructible_v, ll_mapping_t>); + static_assert( + std::is_convertible_v, lr_mapping_t>); + + // Check that larger index_type to smaller index_type conversion works + // explicitly only + static_assert( + std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_convertible_v, lr_mapping_t>); } constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_constructible_v, ll_mapping_t>); + static_assert(!std::is_constructible_v, + ll_mapping_t>); } constexpr void test_static_extent_mismatch() { - static_assert(!std::is_constructible_v, ll_mapping_t>); + static_assert( + !std::is_constructible_v, ll_mapping_t>); } constexpr void test_rank_greater_one() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_constructible_v, ll_mapping_t>); - static_assert(!std::is_constructible_v, ll_mapping_t>); + static_assert(!std::is_constructible_v, + ll_mapping_t>); + static_assert(!std::is_constructible_v, + ll_mapping_t>); + static_assert(!std::is_constructible_v, + ll_mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_right/layout_right.ctor.layout_stride.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.ctor.layout_stride.pass.cpp index 469f5406..6c156bfe 100644 --- a/tests/libcxx-backports/layout_right/layout_right.ctor.layout_stride.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.ctor.layout_stride.pass.cpp @@ -17,9 +17,11 @@ // Constraints: is_constructible_v is true. // // Preconditions: -// - If extents_type::rank() > 0 is true, then for all r in the range [0, extents_type::rank()), +// - If extents_type::rank() > 0 is true, then for all r in the range [0, +// extents_type::rank()), // other.stride(r) equals other.extents().fwd-prod-of-extents(r), and -// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]). +// - other.required_span_size() is representable as a value of type index_type +// ([basic.fundamental]). // // Effects: Direct-non-list-initializes extents_ with other.extents(). @@ -80,25 +82,34 @@ constexpr void test_conversion() { } template -using lr_mapping_t = typename std::layout_right::template mapping>; +using lr_mapping_t = typename std::layout_right::template mapping< + std::extents>; template -using ls_mapping_t = typename std::layout_stride::template mapping>; +using ls_mapping_t = typename std::layout_stride::template mapping< + std::extents>; constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); - static_assert(!std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); + static_assert( + !std::is_constructible_v, ls_mapping_t>); + static_assert(!std::is_constructible_v, + ls_mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_right/layout_right.ctor.mapping.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.ctor.mapping.pass.cpp index ab10e681..246340e0 100644 --- a/tests/libcxx-backports/layout_right/layout_right.ctor.mapping.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.ctor.mapping.pass.cpp @@ -16,7 +16,8 @@ // Constraints: is_constructible_v is true. // -// Preconditions: other.required_span_size() is representable as a value of type index_type +// Preconditions: other.required_span_size() is representable as a value of type +// index_type #include #include @@ -51,7 +52,8 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); @@ -71,7 +73,8 @@ constexpr void test_conversion() { } template -using mapping_t = typename std::layout_right::template mapping>; +using mapping_t = typename std::layout_right::template mapping< + std::extents>; constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; @@ -85,20 +88,28 @@ constexpr void test_no_implicit_conversion() { static_assert(!std::is_convertible_v, mapping_t>); // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, mapping_t>); - static_assert(std::is_convertible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + std::is_convertible_v, mapping_t>); // Check that dynamic to static conversion only works explicitly - static_assert(std::is_constructible_v, mapping_t>); - static_assert(!std::is_convertible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + !std::is_convertible_v, mapping_t>); // Sanity check that smaller index_type to larger index_type conversion works - static_assert(std::is_constructible_v, mapping_t>); + static_assert( + std::is_constructible_v, mapping_t>); static_assert(std::is_convertible_v, mapping_t>); - // Check that larger index_type to smaller index_type conversion works explicitly only - static_assert(std::is_constructible_v, mapping_t>); - static_assert(!std::is_convertible_v, mapping_t>); + // Check that larger index_type to smaller index_type conversion works + // explicitly only + static_assert( + std::is_constructible_v, mapping_t>); + static_assert( + !std::is_convertible_v, mapping_t>); } constexpr void test_rank_mismatch() { @@ -106,16 +117,20 @@ constexpr void test_rank_mismatch() { static_assert(!std::is_constructible_v, mapping_t>); static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); static_assert(!std::is_constructible_v, mapping_t>); - static_assert(!std::is_constructible_v, mapping_t>); + static_assert( + !std::is_constructible_v, mapping_t>); } constexpr bool test() { diff --git a/tests/libcxx-backports/layout_right/layout_right.extents.verify.cpp b/tests/libcxx-backports/layout_right/layout_right.extents.verify.cpp index 69c1cf79..f0ebcfaf 100644 --- a/tests/libcxx-backports/layout_right/layout_right.extents.verify.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.extents.verify.cpp @@ -23,11 +23,14 @@ #include void not_extents() { - // expected-error-re@*:* {{static assertion failed {{.*}}layout_right::mapping template argument must be a specialization of extents}} + // expected-error-re@*:* {{static assertion failed {{.*}}layout_right::mapping + // template argument must be a specialization of extents}} [[maybe_unused]] std::layout_right::mapping mapping; } void representable() { - // expected-error-re@*:* {{static assertion failed {{.*}}layout_right::mapping product of static extents must be representable as index_type.}} - [[maybe_unused]] std::layout_right::mapping> mapping; + // expected-error-re@*:* {{static assertion failed {{.*}}layout_right::mapping + // product of static extents must be representable as index_type.}} + [[maybe_unused]] std::layout_right::mapping> + mapping; } diff --git a/tests/libcxx-backports/layout_right/layout_right.index_operator.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.index_operator.pass.cpp index 61dca46d..f60044e4 100644 --- a/tests/libcxx-backports/layout_right/layout_right.index_operator.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.index_operator.pass.cpp @@ -31,22 +31,20 @@ #include "../ConvertibleToIntegral.h" -template -concept operator_constraints = requires(Mapping m, Indices ... idxs) { - {std::is_same_v}; +template +concept operator_constraints = requires(Mapping m, Indices... idxs) { + { std::is_same_v }; }; -template - requires( - operator_constraints - ) -constexpr bool check_operator_constraints(Mapping m, Indices ... idxs) { - (void) m(idxs...); +template + requires(operator_constraints) +constexpr bool check_operator_constraints(Mapping m, Indices... idxs) { + (void)m(idxs...); return true; } -template -constexpr bool check_operator_constraints(Mapping, Indices ...) { +template +constexpr bool check_operator_constraints(Mapping, Indices...) { return false; } @@ -83,15 +81,28 @@ constexpr bool test() { test_iteration>(1, 1, 1, 1); // Check operator constraint for number of arguments - static_assert(check_operator_constraints(std::layout_right::mapping>(std::extents(1)), 0)); - static_assert(!check_operator_constraints(std::layout_right::mapping>(std::extents(1)), 0, 0)); + static_assert(check_operator_constraints( + std::layout_right::mapping>(std::extents(1)), + 0)); + static_assert(!check_operator_constraints( + std::layout_right::mapping>(std::extents(1)), + 0, 0)); // Check operator constraint for convertibility of arguments to index_type - static_assert(check_operator_constraints(std::layout_right::mapping>(std::extents(1)), IntType(0))); - static_assert(!check_operator_constraints(std::layout_right::mapping>(std::extents(1)), IntType(0))); - - // Check operator constraint for no-throw-constructibility of index_type from arguments - static_assert(!check_operator_constraints(std::layout_right::mapping>(std::extents(1)), IntType(0))); + static_assert(check_operator_constraints( + std::layout_right::mapping>(std::extents(1)), + IntType(0))); + static_assert(!check_operator_constraints( + std::layout_right::mapping>( + std::extents(1)), + IntType(0))); + + // Check operator constraint for no-throw-constructibility of index_type from + // arguments + static_assert(!check_operator_constraints( + std::layout_right::mapping>( + std::extents(1)), + IntType(0))); return true; } diff --git a/tests/libcxx-backports/layout_right/layout_right.required_span_size.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.required_span_size.pass.cpp index 18c05129..957a8a2f 100644 --- a/tests/libcxx-backports/layout_right/layout_right.required_span_size.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.required_span_size.pass.cpp @@ -14,7 +14,6 @@ // // Returns: extents().fwd-prod-of-extents(extents_type::rank()). - #include #include #include @@ -22,7 +21,8 @@ #include "../llvm_test_macros.h" template -constexpr void test_required_span_size(E e, typename E::index_type expected_size) { +constexpr void test_required_span_size(E e, + typename E::index_type expected_size) { using M = std::layout_right::mapping; const M m(e); diff --git a/tests/libcxx-backports/layout_right/layout_right.static_requirements.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.static_requirements.pass.cpp index 51e76adb..1723bae4 100644 --- a/tests/libcxx-backports/layout_right/layout_right.static_requirements.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.static_requirements.pass.cpp @@ -16,7 +16,8 @@ // - is_nothrow_move_assignable_v is true, // - is_nothrow_swappable_v is true, and // -// the following types and expressions are well-formed and have the specified semantics. +// the following types and expressions are well-formed and have the specified +// semantics. // // typename M::extents_type // Result: A type that is a specialization of extents. @@ -28,14 +29,18 @@ // Result: typename M::extents_type::rank_type. // // typename M::layout_type -// Result: A type MP that meets the layout mapping policy requirements ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is true. +// Result: A type MP that meets the layout mapping policy requirements +// ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is +// true. // // m.extents() // Result: const typename M::extents_type& // // m(i...) // Result: typename M::index_type -// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to numeric_limits::max(). +// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to +// numeric_limits::max(). // // m(i...) == m(static_cast(i)...) // Result: bool @@ -43,21 +48,26 @@ // // m.required_span_size() // Result: typename M::index_type -// Returns: If the size of the multidimensional index space m.extents() is 0, then 0, else 1 plus the maximum value of m(i...) for all i. +// Returns: If the size of the multidimensional index space m.extents() is 0, +// then 0, else 1 plus the maximum value of m(i...) for all i. // // m.is_unique() // Result: bool -// Returns: true only if for every i and j where (i != j || ...) is true, m(i...) != m(j...) is true. +// Returns: true only if for every i and j where (i != j || ...) is true, +// m(i...) != m(j...) is true. // // m.is_exhaustive() // Result: bool -// Returns: true only if for all k in the range [0, m.required_span_size()) there exists an i such that m(i...) equals k. +// Returns: true only if for all k in the range [0, m.required_span_size()) +// there exists an i such that m(i...) equals k. // // m.is_strided() // Result: bool -// Returns: true only if for every rank index r of m.extents() there exists an integer -// sr such that, for all i where (i+dr) is a multidimensional index in m.extents() ([mdspan.overview]), -// m((i + dr)...) - m(i...) equals sr +// Returns: true only if for every rank index r of m.extents() there exists +// an integer +// sr such that, for all i where (i+dr) is a multidimensional index +// in m.extents() ([mdspan.overview]), m((i + dr)...) - m(i...) +// equals sr // // m.stride(r) // Preconditions: m.is_strided() is true. @@ -66,15 +76,18 @@ // // M::is_always_unique() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_unique() is true for all possible objects m of type M. +// Returns: true only if m.is_unique() is true for all possible objects m of +// type M. // // M::is_always_exhaustive() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_exhaustive() is true for all possible objects m of type M. +// Returns: true only if m.is_exhaustive() is true for all possible objects m +// of type M. // // M::is_always_strided() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_strided() is true for all possible objects m of type M. +// Returns: true only if m.is_strided() is true for all possible objects m of +// type M. #include #include @@ -87,7 +100,7 @@ template void test_mapping_requirements(std::index_sequence) { using E = typename M::extents_type; - //static_assert(std::__mdspan_detail::impl_is_extents_v); //FIXME + // static_assert(std::__mdspan_detail::impl_is_extents_v); //FIXME static_assert(std::is_copy_constructible_v); static_assert(std::is_nothrow_move_constructible_v); static_assert(std::is_nothrow_move_assignable_v); @@ -97,14 +110,19 @@ void test_mapping_requirements(std::index_sequence) { ASSERT_SAME_TYPE(typename M::rank_type, typename E::rank_type); ASSERT_SAME_TYPE(typename M::layout_type, std::layout_right); ASSERT_SAME_TYPE(typename M::layout_type::template mapping, M); - static_assert(std::is_same_v().extents()), const E&>); - static_assert(std::is_same_v()(Idxs...)), typename M::index_type>); - static_assert(std::is_same_v().required_span_size()), typename M::index_type>); + static_assert( + std::is_same_v().extents()), const E&>); + static_assert(std::is_same_v()(Idxs...)), + typename M::index_type>); + static_assert(std::is_same_v().required_span_size()), + typename M::index_type>); static_assert(std::is_same_v().is_unique()), bool>); - static_assert(std::is_same_v().is_exhaustive()), bool>); + static_assert( + std::is_same_v().is_exhaustive()), bool>); static_assert(std::is_same_v().is_strided()), bool>); if constexpr (E::rank() > 0) - static_assert(std::is_same_v().stride(0)), typename M::index_type>); + static_assert(std::is_same_v().stride(0)), + typename M::index_type>); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); diff --git a/tests/libcxx-backports/layout_right/layout_right.stride.pass.cpp b/tests/libcxx-backports/layout_right/layout_right.stride.pass.cpp index 8b0a4d0d..41ded2fe 100644 --- a/tests/libcxx-backports/layout_right/layout_right.stride.pass.cpp +++ b/tests/libcxx-backports/layout_right/layout_right.stride.pass.cpp @@ -26,13 +26,13 @@ #include "../llvm_test_macros.h" template -constexpr void test_stride(std::array strides, Args... args) { +constexpr void test_stride( + std::array strides, Args... args) { using M = std::layout_right::mapping; M m(E(args...)); ASSERT_NOEXCEPT(m.stride(0)); - for (size_t r = 0; r < E::rank(); r++) - assert(strides[r] == m.stride(r)); + for (size_t r = 0; r < E::rank(); r++) assert(strides[r] == m.stride(r)); } constexpr bool test() { @@ -40,7 +40,8 @@ constexpr bool test() { test_stride>(std::array{1}, 7); test_stride>(std::array{1}); test_stride>(std::array{8, 1}); - test_stride>(std::array{720, 90, 10, 1}, 7, 9, 10); + test_stride>( + std::array{720, 90, 10, 1}, 7, 9, 10); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.comparison.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.comparison.pass.cpp index f0d0ace3..96913ea3 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.comparison.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.comparison.pass.cpp @@ -11,16 +11,20 @@ // // template -// friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept; +// friend constexpr bool operator==(const mapping& x, const OtherMapping& y) +// noexcept; // // Constraints: // - layout-mapping-alike is satisfied. // - rank_ == OtherMapping::extents_type::rank() is true. // - OtherMapping::is_always_strided() is true. // -// Preconditions: OtherMapping meets the layout mapping requirements ([mdspan.layout.policy.reqmts]). +// Preconditions: OtherMapping meets the layout mapping requirements +// ([mdspan.layout.policy.reqmts]). // -// Returns: true if x.extents() == y.extents() is true, OFFSET(y) == 0 is true, and each of x.stride(r) == y.stride(r) is true for r in the range [0, x.extents().rank()). Otherwise, false. +// Returns: true if x.extents() == y.extents() is true, OFFSET(y) == 0 is true, +// and each of x.stride(r) == y.stride(r) is true for r in the range [0, +// x.extents().rank()). Otherwise, false. #include #include @@ -32,44 +36,54 @@ #include "../CustomTestLayouts.h" template -concept layout_mapping_comparable = requires( - E1 e1, - E2 e2, - std::array s1, - std::array s2) { - std::layout_stride::mapping(e1, s1) == std::layout_stride::mapping(e2, s2); -}; +concept layout_mapping_comparable = + requires(E1 e1, E2 e2, std::array s1, + std::array s2) { + std::layout_stride::mapping(e1, s1) == + std::layout_stride::mapping(e2, s2); + }; template constexpr void test_comparison_different_rank() { constexpr size_t D = std::dynamic_extent; // sanity check same rank - static_assert(layout_mapping_comparable, std::extents>); - static_assert(layout_mapping_comparable, std::extents>); - static_assert(layout_mapping_comparable, std::extents>); - static_assert(layout_mapping_comparable, std::extents>); + static_assert( + layout_mapping_comparable, std::extents>); + static_assert( + layout_mapping_comparable, std::extents>); + static_assert( + layout_mapping_comparable, std::extents>); + static_assert( + layout_mapping_comparable, std::extents>); // not equality comparable when rank is not the same - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); - static_assert(!layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); + static_assert( + !layout_mapping_comparable, std::extents>); } template -constexpr void test_comparison( - bool equal, - To dest_exts, - From src_exts, - std::array dest_strides, - std::array src_strides) { +constexpr void test_comparison(bool equal, To dest_exts, From src_exts, + std::array dest_strides, + std::array src_strides) { std::layout_stride::mapping dest(dest_exts, dest_strides); std::layout_stride::mapping src(src_exts, src_strides); ASSERT_NOEXCEPT(dest == src); @@ -81,67 +95,67 @@ template constexpr void test_comparison_same_rank() { constexpr size_t D = std::dynamic_extent; - test_comparison(true, std::extents(), std::extents(), std::array{}, std::array{}); - - test_comparison(true, std::extents(5), std::extents(5), std::array{1}, std::array{1}); - test_comparison(true, std::extents(0), std::extents(0), std::array{1}, std::array{1}); - test_comparison(true, std::extents(), std::extents(5), std::array{3}, std::array{3}); - test_comparison(true, std::extents(5), std::extents(), std::array{1}, std::array{1}); - test_comparison(true, std::extents(), std::extents< T2, 5>(), std::array{1}, std::array{1}); - test_comparison(false, std::extents(), std::extents(5), std::array{2}, std::array{1}); - test_comparison(false, std::extents(5), std::extents(5), std::array{2}, std::array{1}); - test_comparison(false, std::extents(5), std::extents(7), std::array{1}, std::array{1}); - test_comparison(false, std::extents(), std::extents(7), std::array{1}, std::array{1}); - test_comparison(false, std::extents(5), std::extents(), std::array{1}, std::array{1}); - test_comparison(false, std::extents(), std::extents(), std::array{1}, std::array{1}); - - test_comparison( - true, - std::extents(5, 6, 7, 8, 9), - std::extents(5, 6, 7, 8, 9), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - true, - std::extents(5, 7, 9), - std::extents(6, 7), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - true, - std::extents(5, 6, 7, 8, 9), - std::extents(), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - false, - std::extents(5, 6, 7, 8, 9), - std::extents(), - std::array{2, 20, 200, 20000, 2000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - false, - std::extents(5, 6, 7, 8, 9), - std::extents(5, 6, 3, 8, 9), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - false, - std::extents(5, 7, 9), - std::extents(6, 7), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); - test_comparison( - false, - std::extents(5, 6, 7, 8, 9), - std::extents(), - std::array{2, 20, 200, 2000, 20000}, - std::array{2, 20, 200, 2000, 20000}); + test_comparison(true, std::extents(), std::extents(), + std::array{}, std::array{}); + + test_comparison(true, std::extents(5), std::extents(5), + std::array{1}, std::array{1}); + test_comparison(true, std::extents(0), std::extents(0), + std::array{1}, std::array{1}); + test_comparison(true, std::extents(), std::extents(5), + std::array{3}, std::array{3}); + test_comparison(true, std::extents(5), std::extents(), + std::array{1}, std::array{1}); + test_comparison(true, std::extents(), std::extents(), + std::array{1}, std::array{1}); + test_comparison(false, std::extents(), std::extents(5), + std::array{2}, std::array{1}); + test_comparison(false, std::extents(5), std::extents(5), + std::array{2}, std::array{1}); + test_comparison(false, std::extents(5), std::extents(7), + std::array{1}, std::array{1}); + test_comparison(false, std::extents(), std::extents(7), + std::array{1}, std::array{1}); + test_comparison(false, std::extents(5), std::extents(), + std::array{1}, std::array{1}); + test_comparison(false, std::extents(), std::extents(), + std::array{1}, std::array{1}); + + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 7, 8, 9), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(true, std::extents(5, 7, 9), + std::extents(6, 7), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(true, std::extents(5, 6, 7, 8, 9), + std::extents(), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(), + std::array{2, 20, 200, 20000, 2000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(5, 6, 3, 8, 9), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(false, std::extents(5, 7, 9), + std::extents(6, 7), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); + test_comparison(false, std::extents(5, 6, 7, 8, 9), + std::extents(), + std::array{2, 20, 200, 2000, 20000}, + std::array{2, 20, 200, 2000, 20000}); } template constexpr void test_comparison_with( - bool expect_equal, E1 e1, std::array strides, E2 e2, OtherArgs... other_args) { + bool expect_equal, E1 e1, + std::array strides, E2 e2, + OtherArgs... other_args) { typename std::layout_stride::template mapping map(e1, strides); typename OtherLayout::template mapping other_map(e2, other_args...); @@ -151,26 +165,39 @@ constexpr void test_comparison_with( template constexpr void test_comparison_with() { constexpr size_t D = std::dynamic_extent; - bool is_left_based = - std::is_same_v || std::is_same_v; - test_comparison_with(true, std::extents(), std::array{}, std::extents()); - test_comparison_with(true, std::extents(), std::array{1}, std::extents()); - test_comparison_with(true, std::extents(5), std::array{1}, std::extents()); - test_comparison_with(false, std::extents(5), std::array{2}, std::extents()); + bool is_left_based = std::is_same_v || + std::is_same_v; + test_comparison_with(true, std::extents(), + std::array{}, + std::extents()); + test_comparison_with(true, std::extents(), + std::array{1}, + std::extents()); + test_comparison_with(true, std::extents(5), + std::array{1}, + std::extents()); + test_comparison_with(false, std::extents(5), + std::array{2}, + std::extents()); test_comparison_with( - is_left_based, std::extents(5, 7), std::array{1, 5}, std::extents(5, 7)); + is_left_based, std::extents(5, 7), std::array{1, 5}, + std::extents(5, 7)); test_comparison_with( - !is_left_based, std::extents(5, 7), std::array{7, 1}, std::extents(5, 7)); - test_comparison_with( - false, std::extents(5, 7), std::array{8, 1}, std::extents(5, 7)); + !is_left_based, std::extents(5, 7), std::array{7, 1}, + std::extents(5, 7)); + test_comparison_with(false, std::extents(5, 7), + std::array{8, 1}, + std::extents(5, 7)); if constexpr (std::is_same_v) { // test layout with strides not equal to product of extents - test_comparison_with( - true, std::extents(5, 7), std::array{2, 10}, std::extents(5, 7), 0, 2); + test_comparison_with(true, std::extents(5, 7), + std::array{2, 10}, + std::extents(5, 7), 0, 2); // make sure that offset != 0 results in false - test_comparison_with( - false, std::extents(5, 7), std::array{2, 10}, std::extents(5, 7), 1, 2); + test_comparison_with(false, std::extents(5, 7), + std::array{2, 10}, + std::extents(5, 7), 1, 2); } } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.ctor.default.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.ctor.default.pass.cpp index 0310d164..c67ab416 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.ctor.default.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.ctor.default.pass.cpp @@ -15,10 +15,13 @@ // constexpr mapping() noexcept; // // -// Preconditions: layout_right::mapping().required_span_size() is representable as a value of type index_type ([basic.fundamental]). +// Preconditions: layout_right::mapping().required_span_size() is +// representable as a value of type index_type ([basic.fundamental]). // -// Effects: Direct-non-list-initializes extents_ with extents_type(), and for all d in the range [0, rank_), -// direct-non-list-initializes strides_[d] with layout_right::mapping().stride(d). +// Effects: Direct-non-list-initializes extents_ with extents_type(), and for +// all d in the range [0, rank_), +// direct-non-list-initializes strides_[d] with +// layout_right::mapping().stride(d). #include #include @@ -43,7 +46,8 @@ constexpr void test_construction() { expected_size *= e.extent(r); assert(m.required_span_size() == expected_size); - // check strides: node stride function is constrained on rank>0, e.extent(r) is not + // check strides: node stride function is constrained on rank>0, e.extent(r) + // is not auto strides = m.strides(); ASSERT_NOEXCEPT(m.strides()); if constexpr (E::rank() > 0) { diff --git a/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_array.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_array.pass.cpp index ce1a532b..3428d7a3 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_array.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_array.pass.cpp @@ -11,7 +11,8 @@ // // template -// constexpr mapping(const extents_type& e, array s) noexcept; +// constexpr mapping(const extents_type& e, array s) +// noexcept; // // Constraints: // - is_convertible_v is true, and @@ -19,12 +20,17 @@ // // Preconditions: // - s[i] > 0 is true for all i in the range [0, rank_). -// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]). -// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_), -// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where pi is the ith element of P. -// Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. +// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type +// ([basic.fundamental]). +// - If rank_ is greater than 0, then there exists a permutation P of the +// integers in the range [0, rank_), +// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the +// range [1, rank_), where pi is the ith element of P. +// Note 1: For layout_stride, this condition is necessary and sufficient for +// is_unique() to be true. // -// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), +// Effects: Direct-non-list-initializes extents_ with e, and for all d in the +// range [0, rank_), // direct-non-list-initializes strides_[d] with as_const(s[d]). #include @@ -51,11 +57,13 @@ constexpr void test_construction(E e, S s) { expected_size = 0; break; } - expected_size += (e.extent(r) - 1) * static_cast(s[r]); + expected_size += + (e.extent(r) - 1) * static_cast(s[r]); } assert(m.required_span_size() == expected_size); - // check strides: node stride function is constrained on rank>0, e.extent(r) is not + // check strides: node stride function is constrained on rank>0, e.extent(r) + // is not auto strides = m.strides(); ASSERT_NOEXCEPT(m.strides()); if constexpr (E::rank() > 0) { @@ -114,18 +122,24 @@ constexpr bool test() { { using mapping_t = std::layout_stride::mapping>; // wrong strides size - static_assert(!std::is_constructible_v, std::array>); - static_assert(!std::is_constructible_v, std::array>); + static_assert(!std::is_constructible_v, + std::array>); + static_assert(!std::is_constructible_v, + std::array>); // wrong extents rank - static_assert(!std::is_constructible_v, std::array>); + static_assert(!std::is_constructible_v, + std::array>); // none-convertible strides - static_assert(!std::is_constructible_v, std::array>); + static_assert(!std::is_constructible_v, + std::array>); } { // not no-throw constructible index_type from stride - using mapping_t = std::layout_stride::mapping>; + using mapping_t = + std::layout_stride::mapping>; static_assert(std::is_convertible_v); - static_assert(!std::is_constructible_v, std::array>); + static_assert(!std::is_constructible_v, + std::array>); } return true; diff --git a/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_span.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_span.pass.cpp index 7c71a1f9..9d933878 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_span.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.ctor.extents_span.pass.cpp @@ -11,7 +11,8 @@ // // template -// constexpr mapping(const extents_type& e, span s) noexcept; +// constexpr mapping(const extents_type& e, span s) +// noexcept; // // Constraints: // - is_convertible_v is true, and @@ -19,12 +20,17 @@ // // Preconditions: // - s[i] > 0 is true for all i in the range [0, rank_). -// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type ([basic.fundamental]). -// - If rank_ is greater than 0, then there exists a permutation P of the integers in the range [0, rank_), -// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the range [1, rank_), where pi is the ith element of P. -// Note 1: For layout_stride, this condition is necessary and sufficient for is_unique() to be true. +// - REQUIRED-SPAN-SIZE(e, s) is representable as a value of type index_type +// ([basic.fundamental]). +// - If rank_ is greater than 0, then there exists a permutation P of the +// integers in the range [0, rank_), +// such that s[pi] >= s[pi_1] * e.extent(pi_1) is true for all i in the +// range [1, rank_), where pi is the ith element of P. +// Note 1: For layout_stride, this condition is necessary and sufficient for +// is_unique() to be true. // -// Effects: Direct-non-list-initializes extents_ with e, and for all d in the range [0, rank_), +// Effects: Direct-non-list-initializes extents_ with e, and for all d in the +// range [0, rank_), // direct-non-list-initializes strides_[d] with as_const(s[d]). #include @@ -51,11 +57,13 @@ constexpr void test_construction(E e, S s) { expected_size = 0; break; } - expected_size += (e.extent(r) - 1) * static_cast(s[r]); + expected_size += + (e.extent(r) - 1) * static_cast(s[r]); } assert(m.required_span_size() == expected_size); - // check strides: node stride function is constrained on rank>0, e.extent(r) is not + // check strides: node stride function is constrained on rank>0, e.extent(r) + // is not auto strides = m.strides(); ASSERT_NOEXCEPT(m.strides()); if constexpr (E::rank() > 0) { @@ -94,42 +102,60 @@ constexpr bool test() { } { std::array s{20, 2, 200, 2000}; - test_construction(std::extents(7, 9, 10), std::span(s)); + test_construction(std::extents(7, 9, 10), + std::span(s)); } { std::array s{20, 2, 200, 2000}; - test_construction(std::extents(7, 0, 10), std::span(s)); - test_construction(std::extents(0, 9, 10), std::span(s)); + test_construction(std::extents(7, 0, 10), + std::span(s)); + test_construction(std::extents(0, 9, 10), + std::span(s)); test_construction(std::extents(0, 8, 0), std::span(s)); } { std::array s{200, 20, 20, 2000}; - test_construction(std::extents(7, 0, 8, 9), std::span(s)); - test_construction(std::extents(7, 8, 0, 9), std::span(s)); - test_construction(std::extents(7, 1, 8, 9), std::span(s)); - test_construction(std::extents(7, 8, 1, 9), std::span(s)); - test_construction(std::extents(7, 1, 1, 9), std::span(s)); - test_construction(std::extents(7, 0, 0, 9), std::span(s)); - test_construction(std::extents(7, 1, 1, 9), std::span(s)); - test_construction(std::extents(7, 1, 0, 9), std::span(s)); - test_construction(std::extents(7, 0, 1, 9), std::span(s)); + test_construction(std::extents(7, 0, 8, 9), + std::span(s)); + test_construction(std::extents(7, 8, 0, 9), + std::span(s)); + test_construction(std::extents(7, 1, 8, 9), + std::span(s)); + test_construction(std::extents(7, 8, 1, 9), + std::span(s)); + test_construction(std::extents(7, 1, 1, 9), + std::span(s)); + test_construction(std::extents(7, 0, 0, 9), + std::span(s)); + test_construction(std::extents(7, 1, 1, 9), + std::span(s)); + test_construction(std::extents(7, 1, 0, 9), + std::span(s)); + test_construction(std::extents(7, 0, 1, 9), + std::span(s)); } { using mapping_t = std::layout_stride::mapping>; // wrong strides size - static_assert(!std::is_constructible_v, std::span>); - static_assert(!std::is_constructible_v, std::span>); + static_assert(!std::is_constructible_v, + std::span>); + static_assert(!std::is_constructible_v, + std::span>); // wrong extents rank - static_assert(!std::is_constructible_v, std::span>); + static_assert(!std::is_constructible_v, + std::span>); // none-convertible strides - static_assert(!std::is_constructible_v, std::span>); + static_assert(!std::is_constructible_v, + std::span>); } { // not no-throw constructible index_type from stride - using mapping_t = std::layout_stride::mapping>; + using mapping_t = + std::layout_stride::mapping>; static_assert(std::is_convertible_v); - static_assert(!std::is_constructible_v, std::span>); + static_assert(!std::is_constructible_v, + std::span>); } return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.ctor.strided_mapping.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.ctor.strided_mapping.pass.cpp index 7772cbe2..3f301fbe 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.ctor.strided_mapping.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.ctor.strided_mapping.pass.cpp @@ -16,21 +16,26 @@ // // Constraints: // - layout-mapping-alike is satisfied. -// - is_constructible_v is true. +// - is_constructible_v is true. // - StridedLayoutMapping::is_always_unique() is true. // - StridedLayoutMapping::is_always_strided() is true. // // Preconditions: -// - StridedLayoutMapping meets the layout mapping requirements ([mdspan.layout.policy.reqmts]), +// - StridedLayoutMapping meets the layout mapping requirements +// ([mdspan.layout.policy.reqmts]), // - other.stride(r) > 0 is true for every rank index r of extents(), -// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]), and +// - other.required_span_size() is representable as a value of type index_type +// ([basic.fundamental]), and // - OFFSET(other) == 0 is true. // -// Effects: Direct-non-list-initializes extents_ with other.extents(), and for all d in the range [0, rank_), +// Effects: Direct-non-list-initializes extents_ with other.extents(), and for +// all d in the range [0, rank_), // direct-non-list-initializes strides_[d] with other.stride(d). // // Remarks: The expression inside explicit is equivalent to: -// - !(is_convertible_v && +// - !(is_convertible_v && // (is-mapping-of || // is-mapping-of || // is-mapping-of)) @@ -86,10 +91,11 @@ template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = - static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); - constexpr bool l_convertible = - std::is_same_v || std::is_same_v || - std::is_same_v; + static_cast(std::numeric_limits::max()) >= + static_cast(std::numeric_limits::max()); + constexpr bool l_convertible = std::is_same_v || + std::is_same_v || + std::is_same_v; constexpr bool idx_l_convertible = idx_convertible && l_convertible; // clang-format off @@ -112,7 +118,8 @@ constexpr void test_conversion() { } template -using ToM = typename std::layout_stride::template mapping>; +using ToM = typename std::layout_stride::template mapping< + std::extents>; template using FromM = typename FromL::template mapping>; @@ -130,18 +137,22 @@ constexpr void test_no_implicit_conversion() { static_assert(!std::is_convertible_v, ToM>); // Sanity check that one static to dynamic conversion works - static_assert(std::is_constructible_v, FromM>); + static_assert( + std::is_constructible_v, FromM>); static_assert(std::is_convertible_v, ToM>); // Check that dynamic to static conversion only works explicitly - static_assert(std::is_constructible_v, FromM>); - static_assert(!std::is_convertible_v, ToM>); + static_assert( + std::is_constructible_v, FromM>); + static_assert( + !std::is_convertible_v, ToM>); // Sanity check that smaller index_type to larger index_type conversion works static_assert(std::is_constructible_v, FromM>); static_assert(std::is_convertible_v, ToM>); - // Check that larger index_type to smaller index_type conversion works explicitly only + // Check that larger index_type to smaller index_type conversion works + // explicitly only static_assert(std::is_constructible_v, FromM>); static_assert(!std::is_convertible_v, ToM>); } @@ -153,16 +164,19 @@ constexpr void test_rank_mismatch() { static_assert(!std::is_constructible_v, FromM>); static_assert(!std::is_constructible_v, FromM>); static_assert(!std::is_constructible_v, FromM>); - static_assert(!std::is_constructible_v, FromM>); + static_assert( + !std::is_constructible_v, FromM>); } template constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; - static_assert(!std::is_constructible_v, FromM>); + static_assert( + !std::is_constructible_v, FromM>); static_assert(!std::is_constructible_v, FromM>); - static_assert(!std::is_constructible_v, FromM>); + static_assert( + !std::is_constructible_v, FromM>); } template diff --git a/tests/libcxx-backports/layout_stride/layout_stride.deduction.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.deduction.pass.cpp index b69363a7..9d8b1e5f 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.deduction.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.deduction.pass.cpp @@ -26,24 +26,35 @@ constexpr bool test() { constexpr size_t D = std::dynamic_extent; - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::array())), + ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping( + std::extents(), std::array())), std::layout_stride::template mapping>); - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::array{1})), + ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping( + std::extents(), std::array{1})), std::layout_stride::template mapping>); - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::array{1})), + ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping( + std::extents(), std::array{1})), std::layout_stride::template mapping>); ASSERT_SAME_TYPE( - decltype(std::layout_stride::mapping(std::extents(), std::array{3, 100})), + decltype(std::layout_stride::mapping(std::extents(), + std::array{3, 100})), std::layout_stride::template mapping>); - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::span())), + ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping( + std::extents(), std::span())), std::layout_stride::template mapping>); - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::declval>())), - std::layout_stride::template mapping>); - ASSERT_SAME_TYPE(decltype(std::layout_stride::mapping(std::extents(), std::declval>())), - std::layout_stride::template mapping>); ASSERT_SAME_TYPE( - decltype(std::layout_stride::mapping(std::extents(), std::declval>())), + decltype(std::layout_stride::mapping(std::extents(), + std::declval>())), + std::layout_stride::template mapping>); + ASSERT_SAME_TYPE( + decltype(std::layout_stride::mapping(std::extents(), + std::declval>())), + std::layout_stride::template mapping>); + ASSERT_SAME_TYPE( + decltype(std::layout_stride::mapping( + std::extents(), + std::declval>())), std::layout_stride::template mapping>); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.extents.verify.cpp b/tests/libcxx-backports/layout_stride/layout_stride.extents.verify.cpp index 5ee5314e..b3f8cc1d 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.extents.verify.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.extents.verify.cpp @@ -24,11 +24,16 @@ #include "../llvm_test_macros.h" void not_extents() { - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}layout_stride::mapping template argument must be a specialization of extents}} + // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed + // {{.*}}layout_stride::mapping template argument must be a specialization of + // extents}} [[maybe_unused]] std::layout_stride::mapping mapping; } void representable() { - // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}layout_stride::mapping product of static extents must be representable as index_type.}} - [[maybe_unused]] std::layout_stride::mapping> mapping; + // expected-error-re@*:* {{{{(static_assert|static assertion)}} failed + // {{.*}}layout_stride::mapping product of static extents must be + // representable as index_type.}} + [[maybe_unused]] std::layout_stride::mapping> + mapping; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.index_operator.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.index_operator.pass.cpp index 781f1df7..acf09757 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.index_operator.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.index_operator.pass.cpp @@ -49,8 +49,11 @@ constexpr bool check_operator_constraints(Mapping, Indices...) { } template -constexpr void iterate_stride(M m, const std::array& strides, Args... args) { - constexpr int r = static_cast(M::extents_type::rank()) - 1 - static_cast(sizeof...(Args)); +constexpr void iterate_stride( + M m, const std::array& strides, + Args... args) { + constexpr int r = static_cast(M::extents_type::rank()) - 1 - + static_cast(sizeof...(Args)); if constexpr (-1 == r) { ASSERT_NOEXCEPT(m(args...)); size_t expected_val = [&](std::index_sequence) { @@ -65,7 +68,8 @@ constexpr void iterate_stride(M m, const std::array -constexpr void test_iteration(std::array strides, Args... args) { +constexpr void test_iteration(std::array strides, + Args... args) { using M = std::layout_stride::mapping; M m(E(args...), strides); @@ -79,23 +83,34 @@ constexpr bool test() { test_iteration>(std::array{3}, 7); test_iteration>(std::array{4}); test_iteration>(std::array{25, 3}); - test_iteration>(std::array{1, 1, 1, 1}, 1, 1, 1, 1); + test_iteration>(std::array{1, 1, 1, 1}, + 1, 1, 1, 1); // Check operator constraint for number of arguments static_assert(check_operator_constraints( - std::layout_stride::mapping>(std::extents(1), std::array{1}), 0)); + std::layout_stride::mapping>(std::extents(1), + std::array{1}), + 0)); static_assert(!check_operator_constraints( - std::layout_stride::mapping>(std::extents(1), std::array{1}), 0, 0)); + std::layout_stride::mapping>(std::extents(1), + std::array{1}), + 0, 0)); // Check operator constraint for convertibility of arguments to index_type static_assert(check_operator_constraints( - std::layout_stride::mapping>(std::extents(1), std::array{1}), IntType(0))); + std::layout_stride::mapping>(std::extents(1), + std::array{1}), + IntType(0))); static_assert(!check_operator_constraints( - std::layout_stride::mapping>(std::extents(1), std::array{1}), IntType(0))); + std::layout_stride::mapping>( + std::extents(1), std::array{1}), + IntType(0))); - // Check operator constraint for no-throw-constructibility of index_type from arguments + // Check operator constraint for no-throw-constructibility of index_type from + // arguments static_assert(!check_operator_constraints( - std::layout_stride::mapping>(std::extents(1), std::array{1}), + std::layout_stride::mapping>( + std::extents(1), std::array{1}), IntType(0))); return true; @@ -103,8 +118,10 @@ constexpr bool test() { constexpr bool test_large() { constexpr size_t D = std::dynamic_extent; - test_iteration>(std::array{2000, 2, 20, 200}, 7, 9, 10); - test_iteration>(std::array{2000, 20, 20, 200}, 7, 10); + test_iteration>( + std::array{2000, 2, 20, 200}, 7, 9, 10); + test_iteration>( + std::array{2000, 20, 20, 200}, 7, 10); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.is_exhaustive_corner_case.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.is_exhaustive_corner_case.pass.cpp index e5f768bd..79fd94ee 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.is_exhaustive_corner_case.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.is_exhaustive_corner_case.pass.cpp @@ -14,9 +14,11 @@ // // Returns: // - true if rank_ is 0. -// - Otherwise, true if there is a permutation P of the integers in the range [0, rank_) such that -// stride(p0) equals 1, and stride(pi) equals stride(pi_1) * extents().extent(pi_1) for i in the -// range [1, rank_), where pi is the ith element of P. +// - Otherwise, true if there is a permutation P of the integers in the range +// [0, rank_) such that +// stride(p0) equals 1, and stride(pi) equals stride(pi_1) * +// extents().extent(pi_1) for i in the range [1, rank_), where pi is the ith +// element of P. // - Otherwise, false. #include @@ -27,8 +29,9 @@ #include "../llvm_test_macros.h" template -constexpr void -test_layout_mapping_stride(E ext, std::array strides, bool exhaustive) { +constexpr void test_layout_mapping_stride( + E ext, std::array strides, + bool exhaustive) { using M = std::layout_stride::template mapping; M m(ext, strides); assert(m.is_exhaustive() == exhaustive); @@ -36,14 +39,20 @@ test_layout_mapping_stride(E ext, std::array constexpr bool test() { constexpr size_t D = std::dynamic_extent; - test_layout_mapping_stride(std::extents(), std::array{1}, true); - test_layout_mapping_stride(std::extents(0), std::array{3}, false); - test_layout_mapping_stride(std::extents(), std::array{6, 2}, true); - test_layout_mapping_stride(std::extents(3, 0), std::array{6, 2}, false); - test_layout_mapping_stride(std::extents(0, 0), std::array{6, 2}, false); - test_layout_mapping_stride( - std::extents(3, 3, 0, 3), std::array{3, 1, 27, 9}, true); - test_layout_mapping_stride(std::extents(0, 3, 3, 3), std::array{3, 1, 27, 9}, false); + test_layout_mapping_stride(std::extents(), std::array{1}, + true); + test_layout_mapping_stride(std::extents(0), + std::array{3}, false); + test_layout_mapping_stride(std::extents(), + std::array{6, 2}, true); + test_layout_mapping_stride(std::extents(3, 0), + std::array{6, 2}, false); + test_layout_mapping_stride(std::extents(0, 0), + std::array{6, 2}, false); + test_layout_mapping_stride(std::extents(3, 3, 0, 3), + std::array{3, 1, 27, 9}, true); + test_layout_mapping_stride(std::extents(0, 3, 3, 3), + std::array{3, 1, 27, 9}, false); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.properties.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.properties.pass.cpp index 36b7e007..dedb1f11 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.properties.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.properties.pass.cpp @@ -27,15 +27,18 @@ // } // // -// layout_stride::mapping is a trivially copyable type that models regular for each E. +// layout_stride::mapping is a trivially copyable type that models regular +// for each E. // // constexpr bool is_exhaustive() const noexcept; // // Returns: // - true if rank_ is 0. -// - Otherwise, true if there is a permutation P of the integers in the range [0, rank_) such that -// stride(p0) equals 1, and stride(pi) equals stride(pi_1) * extents().extent(pi_1) for i in the -// range [1, rank_), where pi is the ith element of P. +// - Otherwise, true if there is a permutation P of the integers in the range +// [0, rank_) such that +// stride(p0) equals 1, and stride(pi) equals stride(pi_1) * +// extents().extent(pi_1) for i in the range [1, rank_), where pi is the ith +// element of P. // - Otherwise, false. #include @@ -46,8 +49,9 @@ #include "../llvm_test_macros.h" template -constexpr void -test_layout_mapping_stride(E ext, std::array strides, bool exhaustive) { +constexpr void test_layout_mapping_stride( + E ext, std::array strides, + bool exhaustive) { using M = std::layout_stride::template mapping; M m(ext, strides); const M c_m = m; @@ -88,7 +92,8 @@ test_layout_mapping_stride(E ext, std::array expected_size = 0; break; } - expected_size += (ext.extent(r) - 1) * static_cast(strides[r]); + expected_size += + (ext.extent(r) - 1) * static_cast(strides[r]); } assert(m.required_span_size() == expected_size); assert(c_m.required_span_size() == expected_size); @@ -102,10 +107,14 @@ test_layout_mapping_stride(E ext, std::array constexpr bool test() { constexpr size_t D = std::dynamic_extent; test_layout_mapping_stride(std::extents(), std::array{}, true); - test_layout_mapping_stride(std::extents(), std::array{1, 4}, true); - test_layout_mapping_stride(std::extents(), std::array{1, 5}, false); - test_layout_mapping_stride(std::extents(7), std::array{20, 2}, false); - test_layout_mapping_stride(std::extents(3, 3, 3, 3), std::array{3, 1, 9, 27}, true); + test_layout_mapping_stride(std::extents(), + std::array{1, 4}, true); + test_layout_mapping_stride(std::extents(), + std::array{1, 5}, false); + test_layout_mapping_stride(std::extents(7), + std::array{20, 2}, false); + test_layout_mapping_stride(std::extents(3, 3, 3, 3), + std::array{3, 1, 9, 27}, true); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.required_span_size.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.required_span_size.pass.cpp index 62c59430..58bed8cd 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.required_span_size.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.required_span_size.pass.cpp @@ -13,7 +13,8 @@ // Let REQUIRED-SPAN-SIZE(e, strides) be: // - 1, if e.rank() == 0 is true, // - otherwise 0, if the size of the multidimensional index space e is 0, -// - otherwise 1 plus the sum of products of (e.extent(r) - 1) and strides[r] for all r in the range [0, e.rank()). +// - otherwise 1 plus the sum of products of (e.extent(r) - 1) and strides[r] +// for all r in the range [0, e.rank()). // constexpr index_type required_span_size() const noexcept; // @@ -26,7 +27,8 @@ #include "../llvm_test_macros.h" template -constexpr void test_required_span_size(E e, std::array strides, typename E::index_type expected_size) { +constexpr void test_required_span_size(E e, std::array strides, + typename E::index_type expected_size) { using M = std::layout_stride::mapping; const M m(e, strides); @@ -37,15 +39,22 @@ constexpr void test_required_span_size(E e, std::array strides, constexpr bool test() { constexpr size_t D = std::dynamic_extent; test_required_span_size(std::extents(), std::array{}, 1); - test_required_span_size(std::extents(0), std::array{5}, 0); - test_required_span_size(std::extents(1), std::array{5}, 1); - test_required_span_size(std::extents(7), std::array{5}, 31); - test_required_span_size(std::extents(), std::array{5}, 31); - test_required_span_size(std::extents(), std::array{20, 2}, 135); - test_required_span_size( - std::extents(7, 9, 10), std::array{1, 7, 7 * 8, 7 * 8 * 9}, 5040); - test_required_span_size(std::extents(9, 10), std::array{1, 7, 7 * 8, 7 * 8 * 9}, 5034); - test_required_span_size(std::extents(9, 10), std::array{1, 7, 7 * 8, 7 * 8 * 9}, 0); + test_required_span_size(std::extents(0), std::array{5}, + 0); + test_required_span_size(std::extents(1), std::array{5}, + 1); + test_required_span_size(std::extents(7), std::array{5}, + 31); + test_required_span_size(std::extents(), std::array{5}, + 31); + test_required_span_size(std::extents(), + std::array{20, 2}, 135); + test_required_span_size(std::extents(7, 9, 10), + std::array{1, 7, 7 * 8, 7 * 8 * 9}, 5040); + test_required_span_size(std::extents(9, 10), + std::array{1, 7, 7 * 8, 7 * 8 * 9}, 5034); + test_required_span_size(std::extents(9, 10), + std::array{1, 7, 7 * 8, 7 * 8 * 9}, 0); return true; } diff --git a/tests/libcxx-backports/layout_stride/layout_stride.static_requirements.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.static_requirements.pass.cpp index eeec3a92..e6263088 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.static_requirements.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.static_requirements.pass.cpp @@ -16,7 +16,8 @@ // - is_nothrow_move_assignable_v is true, // - is_nothrow_swappable_v is true, and // -// the following types and expressions are well-formed and have the specified semantics. +// the following types and expressions are well-formed and have the specified +// semantics. // // typename M::extents_type // Result: A type that is a specialization of extents. @@ -28,14 +29,18 @@ // Result: typename M::extents_type::rank_type. // // typename M::layout_type -// Result: A type MP that meets the layout mapping policy requirements ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is true. +// Result: A type MP that meets the layout mapping policy requirements +// ([mdspan.layout.policy.reqmts]) and for which is-mapping-of is +// true. // // m.extents() // Result: const typename M::extents_type& // // m(i...) // Result: typename M::index_type -// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to numeric_limits::max(). +// Returns: A nonnegative integer less than numeric_limits::max() and less than or equal to +// numeric_limits::max(). // // m(i...) == m(static_cast(i)...) // Result: bool @@ -43,21 +48,26 @@ // // m.required_span_size() // Result: typename M::index_type -// Returns: If the size of the multidimensional index space m.extents() is 0, then 0, else 1 plus the maximum value of m(i...) for all i. +// Returns: If the size of the multidimensional index space m.extents() is 0, +// then 0, else 1 plus the maximum value of m(i...) for all i. // // m.is_unique() // Result: bool -// Returns: true only if for every i and j where (i != j || ...) is true, m(i...) != m(j...) is true. +// Returns: true only if for every i and j where (i != j || ...) is true, +// m(i...) != m(j...) is true. // // m.is_exhaustive() // Result: bool -// Returns: true only if for all k in the range [0, m.required_span_size()) there exists an i such that m(i...) equals k. +// Returns: true only if for all k in the range [0, m.required_span_size()) +// there exists an i such that m(i...) equals k. // // m.is_strided() // Result: bool -// Returns: true only if for every rank index r of m.extents() there exists an integer -// sr such that, for all i where (i+dr) is a multidimensional index in m.extents() ([mdspan.overview]), -// m((i + dr)...) - m(i...) equals sr +// Returns: true only if for every rank index r of m.extents() there exists +// an integer +// sr such that, for all i where (i+dr) is a multidimensional index +// in m.extents() ([mdspan.overview]), m((i + dr)...) - m(i...) +// equals sr // // m.stride(r) // Preconditions: m.is_strided() is true. @@ -66,15 +76,18 @@ // // M::is_always_unique() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_unique() is true for all possible objects m of type M. +// Returns: true only if m.is_unique() is true for all possible objects m of +// type M. // // M::is_always_exhaustive() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_exhaustive() is true for all possible objects m of type M. +// Returns: true only if m.is_exhaustive() is true for all possible objects m +// of type M. // // M::is_always_strided() // Result: A constant expression ([expr.const]) of type bool. -// Returns: true only if m.is_strided() is true for all possible objects m of type M. +// Returns: true only if m.is_strided() is true for all possible objects m of +// type M. #include #include @@ -87,7 +100,7 @@ template void test_mapping_requirements(std::index_sequence) { using E = typename M::extents_type; - //static_assert(std::__mdspan_detail::impl_is_extents_v); //FIXME + // static_assert(std::__mdspan_detail::impl_is_extents_v); //FIXME static_assert(std::is_copy_constructible_v); static_assert(std::is_nothrow_move_constructible_v); static_assert(std::is_nothrow_move_assignable_v); @@ -97,14 +110,20 @@ void test_mapping_requirements(std::index_sequence) { ASSERT_SAME_TYPE(typename M::rank_type, typename E::rank_type); ASSERT_SAME_TYPE(typename M::layout_type, std::layout_stride); ASSERT_SAME_TYPE(typename M::layout_type::template mapping, M); - static_assert(std::is_same_v().extents()), const E&>); - static_assert(std::is_same_v().strides()), std::array>); - static_assert(std::is_same_v()(Idxs...)), typename M::index_type>); - static_assert(std::is_same_v().required_span_size()), typename M::index_type>); + static_assert( + std::is_same_v().extents()), const E&>); + static_assert(std::is_same_v().strides()), + std::array>); + static_assert(std::is_same_v()(Idxs...)), + typename M::index_type>); + static_assert(std::is_same_v().required_span_size()), + typename M::index_type>); static_assert(std::is_same_v().is_unique()), bool>); - static_assert(std::is_same_v().is_exhaustive()), bool>); + static_assert( + std::is_same_v().is_exhaustive()), bool>); static_assert(std::is_same_v().is_strided()), bool>); - static_assert(std::is_same_v().stride(0)), typename M::index_type>); + static_assert(std::is_same_v().stride(0)), + typename M::index_type>); static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); diff --git a/tests/libcxx-backports/layout_stride/layout_stride.stride.pass.cpp b/tests/libcxx-backports/layout_stride/layout_stride.stride.pass.cpp index 83dc2827..74649966 100644 --- a/tests/libcxx-backports/layout_stride/layout_stride.stride.pass.cpp +++ b/tests/libcxx-backports/layout_stride/layout_stride.stride.pass.cpp @@ -26,19 +26,19 @@ #include "../llvm_test_macros.h" template -constexpr void test_stride(std::array strides, Args... args) { +constexpr void test_stride( + std::array strides, Args... args) { using M = std::layout_stride::mapping; M m(E(args...), strides); ASSERT_NOEXCEPT(m.stride(0)); - for (size_t r = 0; r < E::rank(); r++) - assert(strides[r] == m.stride(r)); + for (size_t r = 0; r < E::rank(); r++) assert(strides[r] == m.stride(r)); ASSERT_NOEXCEPT(m.strides()); auto strides_out = m.strides(); - static_assert(std::is_same_v>); - for (size_t r = 0; r < E::rank(); r++) - assert(strides[r] == strides_out[r]); + static_assert(std::is_same_v>); + for (size_t r = 0; r < E::rank(); r++) assert(strides[r] == strides_out[r]); } constexpr bool test() { @@ -46,7 +46,8 @@ constexpr bool test() { test_stride>(std::array{1}, 7); test_stride>(std::array{1}); test_stride>(std::array{8, 1}); - test_stride>(std::array{720, 90, 10, 1}, 7, 9, 10); + test_stride>( + std::array{720, 90, 10, 1}, 7, 9, 10); return true; } diff --git a/tests/libcxx-backports/llvm_test_macros.h b/tests/libcxx-backports/llvm_test_macros.h index 0c706556..6337a707 100644 --- a/tests/libcxx-backports/llvm_test_macros.h +++ b/tests/libcxx-backports/llvm_test_macros.h @@ -1,15 +1,18 @@ -#define ASSERT_SAME_TYPE(...) static_assert((std::is_same_v<__VA_ARGS__>), "Types must be the same") +#define ASSERT_SAME_TYPE(...) \ + static_assert((std::is_same_v<__VA_ARGS__>), "Types must be the same") #define LIBCPP_STATIC_ASSERT(A) static_assert(A); -//#define ASSERT_NOEXCEPT(A) if consteval { static_assert(noexcept(A)); } else { assert(noexcept(A)); } -#define ASSERT_NOEXCEPT(...) static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept"); +// #define ASSERT_NOEXCEPT(A) if consteval { static_assert(noexcept(A)); } else +// { assert(noexcept(A)); } +#define ASSERT_NOEXCEPT(...) \ + static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept"); namespace std { - using Kokkos::mdspan; - using Kokkos::extents; - using Kokkos::dextents; - using Kokkos::default_accessor; - using Kokkos::layout_left; - using Kokkos::layout_right; - using Kokkos::layout_stride; -} +using Kokkos::default_accessor; +using Kokkos::dextents; +using Kokkos::extents; +using Kokkos::layout_left; +using Kokkos::layout_right; +using Kokkos::layout_stride; +using Kokkos::mdspan; +} // namespace std diff --git a/tests/libcxx-backports/mdspan/CustomTestAccessors.h b/tests/libcxx-backports/mdspan/CustomTestAccessors.h index 6856c0a5..c56652a1 100644 --- a/tests/libcxx-backports/mdspan/CustomTestAccessors.h +++ b/tests/libcxx-backports/mdspan/CustomTestAccessors.h @@ -22,8 +22,9 @@ #include #include "../llvm_test_macros.h" -// This contains a bunch of accessors and handles which have different properties -// regarding constructibility and convertibility in order to test mdspan constraints +// This contains a bunch of accessors and handles which have different +// properties regarding constructibility and convertibility in order to test +// mdspan constraints // non default constructible data handle template @@ -51,7 +52,8 @@ struct move_counted_handle { constexpr move_counted_handle(const move_counted_handle&) = default; template requires(std::is_constructible_v) - constexpr move_counted_handle(const move_counted_handle& other) : ptr(other.ptr){} + constexpr move_counted_handle(const move_counted_handle& other) + : ptr(other.ptr) {} constexpr move_counted_handle(move_counted_handle&& other) { ptr = other.ptr; #if MDSPAN_HAS_CXX_23 @@ -62,7 +64,8 @@ struct move_counted_handle { } constexpr move_counted_handle(T* ptr_) : ptr(ptr_) {} - constexpr move_counted_handle& operator=(const move_counted_handle&) = default; + constexpr move_counted_handle& operator=(const move_counted_handle&) = + default; constexpr T& operator[](size_t i) const { return ptr[i]; } @@ -84,7 +87,8 @@ struct checked_accessor { constexpr checked_accessor(size_t N_) : N(N_) {} template requires(std::is_convertible_v) - explicit constexpr checked_accessor(const checked_accessor& other) noexcept { + explicit constexpr checked_accessor( + const checked_accessor& other) noexcept { N = other.N; } @@ -92,14 +96,17 @@ struct checked_accessor { assert(i < N); return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { assert(i < N); return data_handle_type(p.ptr + i); } }; -static_assert(std::is_constructible_v, const checked_accessor&>); -static_assert(!std::is_convertible_v&, checked_accessor>); +static_assert(std::is_constructible_v, + const checked_accessor&>); +static_assert(!std::is_convertible_v&, + checked_accessor>); template <> struct checked_accessor { @@ -113,7 +120,8 @@ struct checked_accessor { template requires(std::is_convertible_v) - constexpr checked_accessor(checked_accessor&& other) noexcept { + constexpr checked_accessor( + checked_accessor&& other) noexcept { N = other.N; } @@ -121,7 +129,8 @@ struct checked_accessor { assert(i < N); return p.ptr[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { assert(i < N); return p.ptr + i; } @@ -161,7 +170,8 @@ struct checked_accessor { constexpr checked_accessor(const checked_accessor& acc) : N(acc.N) {} template - constexpr explicit(std::is_const_v) checked_accessor(OtherACC&& acc) : N(acc.N) {} + constexpr explicit(std::is_const_v) checked_accessor(OtherACC&& acc) + : N(acc.N) {} constexpr reference access(data_handle_type p, size_t i) const noexcept { assert(i < N); @@ -191,7 +201,8 @@ struct checked_accessor { assert(i < N); return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { assert(i < N); return data_handle_type(p.ptr + i); } @@ -213,7 +224,8 @@ struct checked_accessor { assert(i < N); return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { assert(i < N); return data_handle_type(p.ptr + i); } @@ -249,8 +261,13 @@ struct conv_test_accessor_nc { return conv_test_accessor_c{}; } - constexpr reference access(data_handle_type p, size_t i) const noexcept { return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { return p + i; } + constexpr reference access(data_handle_type p, size_t i) const noexcept { + return p[i]; + } + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { + return p + i; + } }; template @@ -272,7 +289,8 @@ struct conv_test_accessor_c { requires(ctor_mv) {} template - constexpr conv_test_accessor_c& operator=(const conv_test_accessor_nc&) + constexpr conv_test_accessor_c& operator=( + const conv_test_accessor_nc&) requires(assign_c) { return {}; @@ -284,8 +302,13 @@ struct conv_test_accessor_c { return {}; } - constexpr reference access(data_handle_type p, size_t i) const noexcept { return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { return p + i; } + constexpr reference access(data_handle_type p, size_t i) const noexcept { + return p[i]; + } + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { + return p + i; + } }; template @@ -300,7 +323,8 @@ struct convertible_accessor_but_not_handle { template requires(std::is_convertible_v) explicit constexpr convertible_accessor_but_not_handle( - const convertible_accessor_but_not_handle& other) noexcept { + const convertible_accessor_but_not_handle& + other) noexcept { N = other.N; } @@ -308,10 +332,11 @@ struct convertible_accessor_but_not_handle { assert(i < N); return p[i]; } - constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept { + constexpr data_handle_type offset(data_handle_type p, + size_t i) const noexcept { assert(i < N); return data_handle_type(p.ptr + i); } }; -#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_MDSPAN_CUSTOM_TEST_ACCESSORS_H +#endif // TEST_STD_CONTAINERS_VIEWS_MDSPAN_MDSPAN_CUSTOM_TEST_ACCESSORS_H diff --git a/tests/libcxx-backports/mdspan/mdspan.assign.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.assign.pass.cpp index 7dee1f99..7fbc7e59 100644 --- a/tests/libcxx-backports/mdspan/mdspan.assign.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.assign.pass.cpp @@ -24,57 +24,74 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; MDS m_org(handle, map, acc); MDS m(handle, map, acc); // The defaulted assignment operator seems to be deprecated because: - // error: definition of implicit copy assignment operator for 'checked_accessor' is deprecated - // because it has a user-provided copy constructor [-Werror,-Wdeprecated-copy-with-user-provided-copy] - if constexpr (!std::is_same_v>) - m = m_org; + // error: definition of implicit copy assignment operator for + // 'checked_accessor' is deprecated because it has a + // user-provided copy constructor + // [-Werror,-Wdeprecated-copy-with-user-provided-copy] + if constexpr (!std::is_same_v>) m = m_org; // even though the following checks out: static_assert(std::copyable>); - static_assert(std::is_assignable_v, checked_accessor>); + static_assert(std::is_assignable_v, + checked_accessor>); static_assert(noexcept(m = m_org)); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == acc); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == acc); - static_assert(std::is_trivially_assignable_v == - ((!std::is_class_v || - std::is_trivially_assignable_v)&&std::is_trivially_assignable_v && - std::is_trivially_assignable_v)); + static_assert( + std::is_trivially_assignable_v == + ((!std::is_class_v || + std::is_trivially_assignable_v< + H, const H&>)&&std::is_trivially_assignable_v && + std::is_trivially_assignable_v)); } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template constexpr void mixin_layout(const H& handle, const A& acc) { // make sure we test a trivially assignable mapping - static_assert(std::is_trivially_assignable_v>, - const typename std::layout_left::template mapping>&>); + static_assert(std::is_trivially_assignable_v< + typename std::layout_left::template mapping>, + const typename std::layout_left::template mapping< + std::extents>&>); mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); // make sure we test a not trivially assignable mapping static_assert(!std::is_trivially_assignable_v< - typename layout_wrapping_integral<4>::template mapping>, - const typename layout_wrapping_integral<4>::template mapping>&>); + typename layout_wrapping_integral<4>::template mapping< + std::extents>, + const typename layout_wrapping_integral<4>::template mapping< + std::extents>&>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -83,15 +100,18 @@ constexpr void mixin_accessor() { ElementPool elements; // make sure we test trivially constructible accessor and data_handle static_assert(std::is_trivially_copyable_v>); - static_assert(std::is_trivially_copyable_v::data_handle_type>); + static_assert(std::is_trivially_copyable_v< + typename std::default_accessor::data_handle_type>); mixin_layout(elements.get_ptr(), std::default_accessor()); // Using weird accessor/data_handle // Make sure they actually got the properties we want to test // checked_accessor is noexcept copy constructible except for const double checked_accessor acc(1024); - static_assert(noexcept(checked_accessor(acc)) != std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), acc); + static_assert(noexcept(checked_accessor(acc)) != + std::is_same_v); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), acc); } constexpr bool test() { diff --git a/tests/libcxx-backports/mdspan/mdspan.conversion.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.conversion.pass.cpp index d2f2df5c..cb47c08b 100644 --- a/tests/libcxx-backports/mdspan/mdspan.conversion.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.conversion.pass.cpp @@ -16,15 +16,20 @@ // OtherLayoutPolicy, OtherAccessor>& other); // // Constraints: -// - is_constructible_v&> is true, and +// - is_constructible_v&> is true, and // - is_constructible_v is true. // Mandates: -// - is_constructible_v is +// - is_constructible_v is // - is_constructible_v is true. // // Preconditions: -// - For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true. -// - [0, map_.required_span_size()) is an accessible range of ptr_ and acc_ for values of ptr_, map_, and acc_ after the invocation of this constructor. +// - For each rank index r of extents_type, static_extent(r) == dynamic_extent +// || static_extent(r) == other.extent(r) is true. +// - [0, map_.required_span_size()) is an accessible range of ptr_ and acc_ +// for values of ptr_, map_, and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with other.ptr_, @@ -32,7 +37,8 @@ // - direct-non-list-initializes acc_ with other.acc_. // // Remarks: The expression inside explicit is equivalent to: -// !is_convertible_v&, mapping_type> +// !is_convertible_v&, +// mapping_type> // || !is_convertible_v #include @@ -49,45 +55,64 @@ template constexpr void test_implicit_conversion(ToMDS to_mds, FromMDS from_mds) { assert(to_mds.extents() == from_mds.extents()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with< + typename ToMDS::data_handle_type, + typename FromMDS::data_handle_type>) assert(to_mds.data_handle() == from_mds.data_handle()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with) assert(to_mds.mapping() == from_mds.mapping()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with) assert(to_mds.accessor() == from_mds.accessor()); } template concept mapping_requirements = requires() { - requires(std::copyable && std::equality_comparable) && std::is_nothrow_move_constructible_v && - std::is_nothrow_move_assignable_v && std::is_nothrow_swappable_v; + requires(std::copyable && std::equality_comparable) && + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_assignable_v && + std::is_nothrow_swappable_v; }; template constexpr void test_conversion(FromMDS from_mds) { - // check some requirements, to see we didn't screw up our test layouts/accessors + // check some requirements, to see we didn't screw up our test + // layouts/accessors static_assert(mapping_requirements); static_assert(mapping_requirements); constexpr bool constructible = - std::is_constructible_v && - std::is_constructible_v; + std::is_constructible_v && + std::is_constructible_v; constexpr bool convertible = - std::is_convertible_v && - std::is_convertible_v; + std::is_convertible_v && + std::is_convertible_v; constexpr bool passes_mandates = - std::is_constructible_v && - std::is_constructible_v; + std::is_constructible_v && + std::is_constructible_v; if constexpr (constructible) { if constexpr (passes_mandates) { ToMDS to_mds(from_mds); assert(to_mds.extents() == from_mds.extents()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with< + typename ToMDS::data_handle_type, + typename FromMDS::data_handle_type>) assert(to_mds.data_handle() == from_mds.data_handle()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with< + typename ToMDS::mapping_type, + typename FromMDS::mapping_type>) assert(to_mds.mapping() == from_mds.mapping()); - if constexpr (std::equality_comparable_with) + if constexpr (std::equality_comparable_with< + typename ToMDS::accessor_type, + typename FromMDS::accessor_type>) assert(to_mds.accessor() == from_mds.accessor()); if constexpr (convertible) { test_implicit_conversion(from_mds, from_mds); @@ -100,35 +125,51 @@ constexpr void test_conversion(FromMDS from_mds) { } } -template -constexpr void construct_from_mds(const FromH& handle, const FromL& layout, const FromE& exts, const FromA& acc) { - using ToMDS = std::mdspan; - using FromMDS = std::mdspan; +template +constexpr void construct_from_mds(const FromH& handle, const FromL& layout, + const FromE& exts, const FromA& acc) { + using ToMDS = std::mdspan; + using FromMDS = + std::mdspan; test_conversion(FromMDS(handle, construct_mapping(layout, exts), acc)); } template -constexpr void mixin_extents(const FromH& handle, const FromL& layout, const FromA& acc) { +constexpr void mixin_extents(const FromH& handle, const FromL& layout, + const FromA& acc) { constexpr size_t D = std::dynamic_extent; // constructible and convertible - construct_from_mds, ToA>(handle, layout, std::dextents(), acc); - construct_from_mds, ToA>(handle, layout, std::dextents(4), acc); - construct_from_mds, ToA>(handle, layout, std::extents(), acc); - construct_from_mds, ToA>(handle, layout, std::dextents(4, 5), acc); - construct_from_mds, ToA>(handle, layout, std::dextents(4, 5), acc); - construct_from_mds, ToA>(handle, layout, std::extents(4), acc); - construct_from_mds, ToA>(handle, layout, std::extents(4), acc); - construct_from_mds, ToA>(handle, layout, std::extents(4), acc); - construct_from_mds, ToA>(handle, layout, std::extents(4, 6), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(4), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(4, 5), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(4, 5), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(4), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(4), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(4), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(4, 6), acc); // not convertible - construct_from_mds, ToA>(handle, layout, std::dextents(4), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(4), acc); construct_from_mds, ToA>( handle, layout, std::extents(4, 6, 7), acc); // not constructible - construct_from_mds, ToA>(handle, layout, std::dextents(4, 5), acc); - construct_from_mds, ToA>(handle, layout, std::extents(4, 6), acc); + construct_from_mds, ToA>( + handle, layout, std::dextents(4, 5), acc); + construct_from_mds, ToA>( + handle, layout, std::extents(4, 6), acc); } template @@ -137,58 +178,74 @@ constexpr void mixin_layout(const FromH& handle, const FromA& acc) { mixin_extents(handle, std::layout_right(), acc); // Check layout policy conversion // different layout policies, but constructible and convertible - static_assert(std::is_constructible_v>, - const std::layout_right::mapping>&>); - static_assert(std::is_convertible_v>&, - std::layout_left::mapping>>); + static_assert(std::is_constructible_v< + std::layout_left::mapping>, + const std::layout_right::mapping>&>); + static_assert(std::is_convertible_v< + const std::layout_right::mapping>&, + std::layout_left::mapping>>); // different layout policies, not constructible - static_assert(!std::is_constructible_v>, - const std::layout_right::mapping>&>); + static_assert(!std::is_constructible_v< + std::layout_left::mapping>, + const std::layout_right::mapping>&>); // different layout policies, constructible and not convertible - static_assert(std::is_constructible_v>, - const std::layout_right::mapping>&>); - static_assert(!std::is_convertible_v>&, - std::layout_left::mapping>>); + static_assert(std::is_constructible_v< + std::layout_left::mapping>, + const std::layout_right::mapping>&>); + static_assert(!std::is_convertible_v< + const std::layout_right::mapping>&, + std::layout_left::mapping>>); mixin_extents(handle, std::layout_right(), acc); - mixin_extents, ToA>(handle, layout_wrapping_integral<4>(), acc); + mixin_extents, ToA>( + handle, layout_wrapping_integral<4>(), acc); // different layout policies, constructible and not convertible - static_assert(!std::is_constructible_v::mapping>, - const layout_wrapping_integral<8>::mapping>&>); - static_assert(std::is_constructible_v::mapping>, - layout_wrapping_integral<8>::mapping>>); - mixin_extents, ToA>(handle, layout_wrapping_integral<8>(), acc); + static_assert( + !std::is_constructible_v< + layout_wrapping_integral<8>::mapping>, + const layout_wrapping_integral<8>::mapping>&>); + static_assert( + std::is_constructible_v< + layout_wrapping_integral<8>::mapping>, + layout_wrapping_integral<8>::mapping>>); + mixin_extents, ToA>( + handle, layout_wrapping_integral<8>(), acc); } -// check that we cover all corners with respect to constructibility and convertibility -template +// check that we cover all corners with respect to constructibility and +// convertibility +template constexpr bool test(FromA from_acc) { static_assert(std::copyable); static_assert(std::copyable); - static_assert(std::is_constructible_v == constructible_constref_acc); - static_assert(std::is_constructible_v == constructible_nonconst_acc); - static_assert(std::is_constructible_v == - constructible_constref_handle); - static_assert(std::is_constructible_v == + static_assert(std::is_constructible_v == + constructible_constref_acc); + static_assert(std::is_constructible_v == + constructible_nonconst_acc); + static_assert( + std::is_constructible_v == + constructible_constref_handle); + static_assert(std::is_constructible_v == constructible_nonconst_handle); - static_assert(std::is_convertible_v == convertible_constref_acc); + static_assert(std::is_convertible_v == + convertible_constref_acc); static_assert(std::is_convertible_v == convertible_nonconst_acc); - static_assert(std::is_convertible_v == + static_assert(std::is_convertible_v == convertible_constref_handle); - static_assert(std::is_convertible_v == + static_assert(std::is_convertible_v == convertible_nonconst_handle); ElementPool elements; - mixin_layout(typename FromA::data_handle_type(elements.get_ptr()), from_acc); + mixin_layout(typename FromA::data_handle_type(elements.get_ptr()), + from_acc); return true; } @@ -197,85 +254,123 @@ int main(int, char**) { constexpr bool t = true; constexpr bool o = false; - // possibility matrix for constructibility and convertibility https://godbolt.org/z/98KGo8Wbc - // you can't have convertibility without constructibility - // and if you take const T& then you also can take T - // this leaves 7 combinations - // const_ref_ctor, const_ref_conv, nonconst_ctor, nonconst_conv, tested - // o o o o X - // o o t o X - // o o t t X - // t o t o X - // t o t t X - // t t t o X - // t t t t X + // possibility matrix for constructibility and convertibility + // https://godbolt.org/z/98KGo8Wbc you can't have convertibility without + // constructibility and if you take const T& then you also can take T this + // leaves 7 combinations const_ref_ctor, const_ref_conv, nonconst_ctor, + // nonconst_conv, tested o o o o X o o t o X o o t t X t o t o X t o t t X t t + // t o X t t t t X - // checked_accessor has various weird data handles and some weird conversion properties - // conv_test_accessor_c/nc is an accessor pair which has configurable conversion properties, but plain ptr as data handle - // accessor constructible - test>(std::default_accessor()); - test>(std::default_accessor()); - test>(std::default_accessor()); + // checked_accessor has various weird data handles and some weird conversion + // properties conv_test_accessor_c/nc is an accessor pair which has + // configurable conversion properties, but plain ptr as data handle accessor + // constructible + test>( + std::default_accessor()); + test>( + std::default_accessor()); + test>( + std::default_accessor()); test>( std::default_accessor()); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(conv_test_accessor_nc()); - test>(conv_test_accessor_nc()); - // FIXME: these tests trigger what appears to be a compiler bug on MINGW32 with --target=x86_64-w64-windows-gnu - // https://godbolt.org/z/KK8aj5bs7 - // Bug report: https://github.com/llvm/llvm-project/issues/64077 - #ifndef __MINGW32__ - test>(conv_test_accessor_nc()); - test>(conv_test_accessor_nc()); - #endif + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + conv_test_accessor_nc()); + test>( + conv_test_accessor_nc()); +// FIXME: these tests trigger what appears to be a compiler bug on MINGW32 with +// --target=x86_64-w64-windows-gnu https://godbolt.org/z/KK8aj5bs7 Bug report: +// https://github.com/llvm/llvm-project/issues/64077 +#ifndef __MINGW32__ + test>( + conv_test_accessor_nc()); + test>( + conv_test_accessor_nc()); +#endif // ElementType convertible, but accessor not constructible - test>(std::default_accessor()); - test>(checked_accessor(1024)); - test>(checked_accessor(1024)); - test>(conv_test_accessor_nc()); - test>(conv_test_accessor_nc()); - test>(conv_test_accessor_nc()); + test>( + std::default_accessor()); + test>( + checked_accessor(1024)); + test>( + checked_accessor(1024)); + test>( + conv_test_accessor_nc()); + test>( + conv_test_accessor_nc()); + test>( + conv_test_accessor_nc()); - // Ran into trouble with doing it all in one static_assert: exceeding step limit for consteval - static_assert(test>(std::default_accessor())); - static_assert(test>(std::default_accessor())); - static_assert(test>( - std::default_accessor())); - static_assert(test>( + // Ran into trouble with doing it all in one static_assert: exceeding step + // limit for consteval + static_assert(test>( + std::default_accessor())); + static_assert( + test>( + std::default_accessor())); + static_assert( + test>( + std::default_accessor())); + static_assert(test>( std::default_accessor())); - static_assert(test>(checked_accessor(1024))); - static_assert(test>(checked_accessor(1024))); - static_assert(test>(checked_accessor(1024))); - static_assert(test>(checked_accessor(1024))); - static_assert(test>(checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); + static_assert( + test>( + checked_accessor(1024))); static_assert( - test>(checked_accessor(1024))); - static_assert(test>( - checked_accessor(1024))); + test>( + checked_accessor(1024))); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); static_assert( - test>(conv_test_accessor_nc())); - static_assert(test>(std::default_accessor())); - static_assert(test>(checked_accessor(1024))); - static_assert(test>(checked_accessor(1024))); + test>( + conv_test_accessor_nc())); + static_assert(test>( + std::default_accessor())); + static_assert(test>( + checked_accessor(1024))); + static_assert(test>( + checked_accessor(1024))); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); static_assert( - test>(conv_test_accessor_nc())); + test>( + conv_test_accessor_nc())); return 0; } diff --git a/tests/libcxx-backports/mdspan/mdspan.conversion.verify.cpp b/tests/libcxx-backports/mdspan/mdspan.conversion.verify.cpp index 4daeb06f..505755c5 100644 --- a/tests/libcxx-backports/mdspan/mdspan.conversion.verify.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.conversion.verify.cpp @@ -16,15 +16,20 @@ // OtherLayoutPolicy, OtherAccessor>& other); // // Constraints: -// - is_constructible_v&> is true, and +// - is_constructible_v&> is true, and // - is_constructible_v is true. // Mandates: -// - is_constructible_v is +// - is_constructible_v is // - is_constructible_v is true. // // Preconditions: -// - For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true. -// - [0, map_.required_span_size()) is an accessible range of ptr_ and acc_ for values of ptr_, map_, and acc_ after the invocation of this constructor. +// - For each rank index r of extents_type, static_extent(r) == dynamic_extent +// || static_extent(r) == other.extent(r) is true. +// - [0, map_.required_span_size()) is an accessible range of ptr_ and acc_ +// for values of ptr_, map_, and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with other.ptr_, @@ -32,7 +37,8 @@ // - direct-non-list-initializes acc_ with other.acc_. // // Remarks: The expression inside explicit is equivalent to: -// !is_convertible_v&, mapping_type> +// !is_convertible_v&, +// mapping_type> // || !is_convertible_v #include @@ -41,17 +47,24 @@ void cant_construct_data_handle_type() { int data; - std::mdspan, std::layout_right, convertible_accessor_but_not_handle> m_nc(&data); - // expected-error-re@*:* {{{{.*}}no matching constructor for initialization of {{.*}} (aka 'not_const_convertible_handle')}} - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: incompatible data_handle_type for mdspan construction}} - [[maybe_unused]] std:: - mdspan, std::layout_right, convertible_accessor_but_not_handle> - m_c(m_nc); + std::mdspan, std::layout_right, + convertible_accessor_but_not_handle> + m_nc(&data); + // expected-error-re@*:* {{{{.*}}no matching constructor for initialization of + // {{.*}} (aka 'not_const_convertible_handle')}} + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: incompatible + // data_handle_type for mdspan construction}} + [[maybe_unused]] std::mdspan, std::layout_right, + convertible_accessor_but_not_handle> + m_c(m_nc); } void mapping_constructible_despite_extents_compatibility() { int data; std::mdspan, always_convertible_layout> m(&data); - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: incompatible extents for mdspan construction}} - [[maybe_unused]] std::mdspan, always_convertible_layout> m2(m); + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: incompatible + // extents for mdspan construction}} + [[maybe_unused]] std::mdspan, + always_convertible_layout> + m2(m); } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.copy.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.copy.pass.cpp index 7b8e498f..6bbddadf 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.copy.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.copy.pass.cpp @@ -11,7 +11,8 @@ // constexpr mdspan(const mdspan&) = default; // -// A specialization of mdspan is a trivially copyable type if its accessor_type, mapping_type, and data_handle_type are trivially copyable types. +// A specialization of mdspan is a trivially copyable type if its accessor_type, +// mapping_type, and data_handle_type are trivially copyable types. #include #include @@ -26,43 +27,56 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; MDS m_org(handle, map, acc); MDS m(m_org); - static_assert(noexcept(MDS(m_org)) == (noexcept(H(handle))&& noexcept(M(map))&& noexcept(A(acc)))); - static_assert( - std::is_trivially_copyable_v == - (std::is_trivially_copyable_v && std::is_trivially_copyable_v && std::is_trivially_copyable_v)); + static_assert(noexcept(MDS(m_org)) == + (noexcept(H(handle))&& noexcept(M(map))&& noexcept(A(acc)))); + static_assert(std::is_trivially_copyable_v == + (std::is_trivially_copyable_v && + std::is_trivially_copyable_v && + std::is_trivially_copyable_v)); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == acc); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == acc); } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template constexpr void mixin_layout(const H& handle, const A& acc) { // make sure we test a trivially copyable mapping - static_assert(std::is_trivially_copyable_v>>); + static_assert( + std::is_trivially_copyable_v< + typename std::layout_left::template mapping>>); mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); // make sure we test a not trivially copyable mapping - static_assert( - !std::is_trivially_copyable_v::template mapping>>); + static_assert(!std::is_trivially_copyable_v::template mapping>>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -71,15 +85,18 @@ constexpr void mixin_accessor() { ElementPool elements; // make sure we test trivially constructible accessor and data_handle static_assert(std::is_trivially_copyable_v>); - static_assert(std::is_trivially_copyable_v::data_handle_type>); + static_assert(std::is_trivially_copyable_v< + typename std::default_accessor::data_handle_type>); mixin_layout(elements.get_ptr(), std::default_accessor()); // Using weird accessor/data_handle // Make sure they actually got the properties we want to test // checked_accessor is noexcept copy constructible except for const double checked_accessor acc(1024); - static_assert(noexcept(checked_accessor(acc)) != std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), acc); + static_assert(noexcept(checked_accessor(acc)) != + std::is_same_v); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), acc); } constexpr bool test() { diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.default.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.default.pass.cpp index 41ebfdab..5a06cc9c 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.default.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.default.pass.cpp @@ -17,7 +17,8 @@ // - is_default_constructible_v is true. // // Preconditions: [0, map_.required_span_size()) is an accessible range of ptr_ -// and acc_ for the values of map_ and acc_ after the invocation of this constructor. +// and acc_ for the values of map_ and acc_ after the invocation +// of this constructor. // // Effects: Value-initializes ptr_, map_, and acc_. @@ -34,7 +35,8 @@ template constexpr void test_mdspan_types(const H&, const M&, const A&) { - using MDS = std::mdspan; + using MDS = std::mdspan; static_assert(hc == std::is_default_constructible_v); static_assert(mc == std::is_default_constructible_v); @@ -42,14 +44,12 @@ constexpr void test_mdspan_types(const H&, const M&, const A&) { if constexpr (MDS::rank_dynamic() > 0 && hc && mc && ac) { MDS m; - static_assert(noexcept(MDS()) == (noexcept(H())&& noexcept(M())&& noexcept(A()))); + static_assert(noexcept(MDS()) == + (noexcept(H())&& noexcept(M())&& noexcept(A()))); assert(m.extents() == typename MDS::extents_type()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == H()); - if constexpr (std::equality_comparable) - assert(m.mapping() == M()); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.data_handle() == H()); + if constexpr (std::equality_comparable) assert(m.mapping() == M()); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } else { static_assert(!std::is_default_constructible_v); } @@ -58,13 +58,23 @@ constexpr void test_mdspan_types(const H&, const M&, const A&) { template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); test_mdspan_types( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(7)), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -75,7 +85,8 @@ constexpr void mixin_layout(const H& handle, const A& acc) { // Use weird layout, make sure it has the properties we want to test constexpr size_t D = std::dynamic_extent; static_assert( - !std::is_default_constructible_v< typename layout_wrapping_integral<4>::template mapping>>); + !std::is_default_constructible_v::template mapping>>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -86,13 +97,17 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); // checked_accessor's data handle type is not default constructible for double - static_assert( - std::is_default_constructible_v::data_handle_type> != std::is_same_v); + static_assert(std::is_default_constructible_v< + typename checked_accessor::data_handle_type> != + std::is_same_v); mixin_layout, std::is_same_v>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } constexpr bool test() { diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_array.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_array.pass.cpp index 3e8eb112..129e4ff4 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_array.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_array.pass.cpp @@ -15,13 +15,16 @@ // // Constraints: // - is_convertible_v is true, -// - (is_nothrow_constructible && ...) is true, +// - (is_nothrow_constructible && ...) is +// true, // - N == rank() || N == rank_dynamic() is true, // - is_constructible_v is true, and // - is_default_constructible_v is true. // -// Preconditions: [0, map_.required_span_size()) is an accessible range of p and acc_ -// for the values of map_ and acc_ after the invocation of this constructor. +// Preconditions: [0, map_.required_span_size()) is an accessible range of p and +// acc_ +// for the values of map_ and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with std::move(p), @@ -42,19 +45,24 @@ #include "CustomTestAccessors.h" template -constexpr auto array_from_extents(const Extents& exts, std::index_sequence) { - return std::array{exts.extent(Idxs)...}; +constexpr auto array_from_extents(const Extents& exts, + std::index_sequence) { + return std::array{ + exts.extent(Idxs)...}; } template -concept check_mdspan_ctor_implicit = requires(MDS m, typename MDS::data_handle_type h, const Exts& exts) { - m = {h, exts}; -}; +concept check_mdspan_ctor_implicit = + requires(MDS m, typename MDS::data_handle_type h, const Exts& exts) { + m = {h, exts}; + }; template -constexpr void -test_mdspan_ctor_array(const H& handle, const M& map, const A&, std::array exts) { - using MDS = std::mdspan; +constexpr void test_mdspan_ctor_array( + const H& handle, const M& map, const A&, + std::array exts) { + using MDS = std::mdspan; #if MDSPAN_HAS_CXX_23 if !consteval { move_counted_handle::move_counter() = 0; @@ -63,7 +71,8 @@ test_mdspan_ctor_array(const H& handle, const M& map, const A&, std::array>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } @@ -71,25 +80,25 @@ test_mdspan_ctor_array(const H& handle, const M& map, const A&, std::array == (N == MDS::rank_dynamic())); + static_assert(check_mdspan_ctor_implicit == + (N == MDS::rank_dynamic())); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } template constexpr void test_mdspan_ctor(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; static_assert(mec == std::is_constructible_v); static_assert(ac == std::is_default_constructible_v); if constexpr (mec && ac) { // test from all extents - auto exts = array_from_extents(map.extents(), std::make_index_sequence()); + auto exts = array_from_extents(map.extents(), + std::make_index_sequence()); test_mdspan_ctor_array(handle, map, acc, exts); // test from dynamic extents @@ -101,20 +110,32 @@ constexpr void test_mdspan_ctor(const H& handle, const M& map, const A& acc) { } test_mdspan_ctor_array(handle, map, acc, exts_dynamic); } else { - static_assert(!std::is_constructible_v&>); + static_assert(!std::is_constructible_v< + MDS, const H&, + const std::array&>); } } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_ctor(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(0, 3)), acc); test_mdspan_ctor( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(7)), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_ctor( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -122,17 +143,26 @@ constexpr void mixin_layout(const H& handle, const A& acc) { mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); - // Sanity check that this layouts mapping is constructible from extents (via its move constructor) - static_assert(std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + // Sanity check that this layouts mapping is constructible from extents (via + // its move constructor) + static_assert( + std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<8>(), acc); // Sanity check that this layouts mapping is not constructible from extents - static_assert(!std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + static_assert( + !std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -143,10 +173,13 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); mixin_layout>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } constexpr bool test() { @@ -169,27 +202,33 @@ constexpr bool test() { // not convertible to index_type static_assert(std::is_convertible_v); static_assert(!std::is_convertible_v); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); // index_type is not nothrow constructible using mds_uchar_t = std::mdspan>; static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); - static_assert(!std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_nothrow_constructible_v); + static_assert( + !std::is_constructible_v>); // convertible from non-const to index_type but not from const using mds_int_t = std::mdspan>; static_assert(std::is_convertible_v); static_assert(!std::is_convertible_v); static_assert(std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); - // can't test a combo where std::is_nothrow_constructible_v is true, - // but std::is_convertible_v is false + // can't test a combo where std::is_nothrow_constructible_v is true, but std::is_convertible_v is + // false // test non-constructibility from wrong handle_type - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_extents.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_extents.pass.cpp index 2a7aac22..d3cbeb44 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_extents.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_extents.pass.cpp @@ -15,8 +15,10 @@ // - is_constructible_v is true, and // - is_default_constructible_v is true. // -// Preconditions: [0, map_.required_span_size()) is an accessible range of p and acc_ -// for the values of map_ and acc_ after the invocation of this constructor. +// Preconditions: [0, map_.required_span_size()) is an accessible range of p and +// acc_ +// for the values of map_ and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with std::move(p), @@ -36,9 +38,11 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { - using MDS = std::mdspan; + using MDS = std::mdspan; - static_assert(mec == std::is_constructible_v); + static_assert(mec == + std::is_constructible_v); static_assert(ac == std::is_default_constructible_v); if constexpr (mec && ac) { #if MDSPAN_HAS_CXX_23 @@ -50,7 +54,8 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { MDS m = {handle, map.extents()}; #if MDSPAN_HAS_CXX_23 if !consteval { - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } @@ -59,25 +64,34 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { assert(m.extents() == map.extents()); if constexpr (std::equality_comparable) assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } else { - static_assert(!std::is_constructible_v); + static_assert(!std::is_constructible_v); } } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); test_mdspan_types( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(7)), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -86,17 +100,26 @@ constexpr void mixin_layout(const H& handle, const A& acc) { mixin_extents(handle, std::layout_right(), acc); // Use weird layout, make sure it has the properties we want to test - // Sanity check that this layouts mapping is constructible from extents (via its move constructor) - static_assert(std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + // Sanity check that this layouts mapping is constructible from extents (via + // its move constructor) + static_assert( + std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<8>(), acc); // Sanity check that this layouts mapping is not constructible from extents - static_assert(!std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + static_assert( + !std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -107,10 +130,13 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); mixin_layout>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } constexpr bool test() { @@ -125,16 +151,23 @@ constexpr bool test() { constexpr size_t D = std::dynamic_extent; using mds_t = std::mdspan>; // sanity check - static_assert(std::is_constructible_v>); + static_assert( + std::is_constructible_v>); // wrong size - static_assert(!std::is_constructible_v>); - static_assert(!std::is_constructible_v>); - // wrong type in general: note the extents constructor does NOT convert, since it takes by const& - static_assert(!std::is_constructible_v>); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); + // wrong type in general: note the extents constructor does NOT convert, since + // it takes by const& + static_assert( + !std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); // test non-constructibility from wrong handle_type - static_assert(!std::is_constructible_v>); + static_assert(!std::is_constructible_v>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_integers.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_integers.pass.cpp index a37b7765..7de8b0f5 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_integers.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_integers.pass.cpp @@ -21,12 +21,15 @@ // - is_constructible_v is true, and // - is_default_constructible_v is true. // -// Preconditions: [0, map_.required_span_size()) is an accessible range of p and acc_ -// for the values of map_ and acc_ after the invocation of this constructor. +// Preconditions: [0, map_.required_span_size()) is an accessible range of p and +// acc_ +// for the values of map_ and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with std::move(p), -// - direct-non-list-initializes map_ with extents_type(static_cast(std::move(exts))...), and +// - direct-non-list-initializes map_ with +// extents_type(static_cast(std::move(exts))...), and // - value-initializes acc_. #include @@ -42,11 +45,14 @@ #include "CustomTestAccessors.h" template -concept check_mdspan_ctor_implicit = requires(MDS m, Args... args) { m = {args...}; }; +concept check_mdspan_ctor_implicit = + requires(MDS m, Args... args) { m = {args...}; }; template -constexpr void test_mdspan_types(const H& handle, const M& map, const A&, Idxs... idxs) { - using MDS = std::mdspan; +constexpr void test_mdspan_types(const H& handle, const M& map, const A&, + Idxs... idxs) { + using MDS = std::mdspan; static_assert(mec == std::is_constructible_v); static_assert(ac == std::is_default_constructible_v); @@ -60,26 +66,27 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&, Idxs.. MDS m(handle, idxs...); #if MDSPAN_HAS_CXX_23 if !consteval { - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } #endif // sanity check that concept works - static_assert(check_mdspan_ctor_implicit>); + static_assert( + check_mdspan_ctor_implicit< + MDS, H, std::array>); // check that the constructor from integral is explicit static_assert(!check_mdspan_ctor_implicit); assert(m.extents() == map.extents()); if constexpr (std::equality_comparable) assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } else { - static_assert(!std::is_constructible_v); + static_assert(!std::is_constructible_v); } } @@ -87,20 +94,38 @@ template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; // construct from just dynamic extents - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc, 7); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc, 2, 3); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc, 0, 3); test_mdspan_types( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc, 1, 2, 3, 2); + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(7)), acc, 7); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc, 2, 3); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), acc, + 0, 3); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc, 1, 2, 3, 2); // construct from all extents - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc, 7); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc, 2, 4, 3); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc, 0, 7, 3); test_mdspan_types( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc, 1, 7, 2, 4, 3, 2); + handle, construct_mapping(layout, std::extents()), acc, 7); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc, 2, 4, 3); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), acc, + 0, 7, 3); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc, 1, 7, 2, 4, 3, 2); } template @@ -109,17 +134,26 @@ constexpr void mixin_layout(const H& handle, const A& acc) { mixin_extents(handle, std::layout_right(), acc); // Use weird layout, make sure it has the properties we want to test - // Sanity check that this layouts mapping is constructible from extents (via its move constructor) - static_assert(std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + // Sanity check that this layouts mapping is constructible from extents (via + // its move constructor) + static_assert( + std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<8>(), acc); // Sanity check that this layouts mapping is not constructible from extents - static_assert(!std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + static_assert( + !std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -130,10 +164,13 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); mixin_layout>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } constexpr bool test() { @@ -154,7 +191,8 @@ constexpr bool test() { static_assert(!std::is_constructible_v); static_assert(!std::is_constructible_v); // not convertible to int - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); // test non-constructibility from wrong handle_type static_assert(!std::is_constructible_v); diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map.pass.cpp index 99b95a63..5c7b08b2 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map.pass.cpp @@ -13,8 +13,10 @@ // // Constraints: is_default_constructible_v is true. // -// Preconditions: [0, m.required_span_size()) is an accessible range of p and acc_ -// for the value of acc_ after the invocation of this constructor. +// Preconditions: [0, m.required_span_size()) is an accessible range of p and +// acc_ +// for the value of acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with std::move(p), @@ -34,7 +36,8 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { - using MDS = std::mdspan; + using MDS = std::mdspan; static_assert(ac == std::is_default_constructible_v); if constexpr (ac) { @@ -47,7 +50,8 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { MDS m = {handle, map}; #if MDSPAN_HAS_CXX_23 if !consteval { - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } @@ -56,10 +60,8 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { assert(m.extents() == map.extents()); if constexpr (std::equality_comparable) assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } else { static_assert(!std::is_constructible_v); } @@ -68,12 +70,23 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) { template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(7)), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -90,10 +103,13 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); mixin_layout>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } template @@ -111,18 +127,29 @@ constexpr bool test() { using mds_t = std::mdspan>; // sanity check - static_assert(std::is_constructible_v>>); + static_assert(std::is_constructible_v>>); // test non-constructibility from wrong mapping type // wrong rank - static_assert(!std::is_constructible_v>>); - static_assert(!std::is_constructible_v>>); - // wrong type in general: note the map constructor does NOT convert, since it takes by const& - static_assert(!std::is_constructible_v>>); - static_assert(!std::is_constructible_v>>); + static_assert(!std::is_constructible_v>>); + static_assert( + !std::is_constructible_v>>); + // wrong type in general: note the map constructor does NOT convert, since it + // takes by const& + static_assert( + !std::is_constructible_v>>); + static_assert( + !std::is_constructible_v>>); // test non-constructibility from wrong handle_type - static_assert(!std::is_constructible_v>>); + static_assert( + !std::is_constructible_v>>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map_acc.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map_acc.pass.cpp index bd0006cc..e4579471 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map_acc.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_map_acc.pass.cpp @@ -9,7 +9,8 @@ // -// constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); +// constexpr mdspan(data_handle_type p, const mapping_type& m, const +// accessor_type& a); // // Preconditions: [0, m.required_span_size()) is an accessible range of p and a. // @@ -31,7 +32,8 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; #if MDSPAN_HAS_CXX_23 if !consteval { @@ -42,30 +44,39 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { MDS m = {handle, map, acc}; #if MDSPAN_HAS_CXX_23 if !consteval { - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } #endif static_assert(!noexcept(MDS(handle, map, acc))); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == acc); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == acc); } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -82,12 +93,17 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); // checked_accessor's data handle type is not default constructible for double - static_assert( - std::is_default_constructible_v::data_handle_type> != std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + static_assert(std::is_default_constructible_v< + typename checked_accessor::data_handle_type> != + std::is_same_v); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } template @@ -107,23 +123,36 @@ constexpr bool test() { using acc_t = std::default_accessor; // sanity check - static_assert(std::is_constructible_v>, acc_t>); + static_assert( + std::is_constructible_v>, acc_t>); // test non-constructibility from wrong accessor - static_assert( - !std:: - is_constructible_v>, std::default_accessor>); + static_assert(!std::is_constructible_v>, + std::default_accessor>); // test non-constructibility from wrong mapping type // wrong rank - static_assert(!std::is_constructible_v>, acc_t>); - static_assert(!std::is_constructible_v>, acc_t>); - // wrong type in general: note the map constructor does NOT convert, since it takes by const& - static_assert(!std::is_constructible_v>, acc_t>); - static_assert(!std::is_constructible_v>, acc_t>); + static_assert( + !std::is_constructible_v>, acc_t>); + static_assert( + !std::is_constructible_v< + mds_t, float*, mapping_t>, acc_t>); + // wrong type in general: note the map constructor does NOT convert, since it + // takes by const& + static_assert( + !std::is_constructible_v>, acc_t>); + static_assert( + !std::is_constructible_v< + mds_t, float*, mapping_t>, acc_t>); // test non-constructibility from wrong handle_type - static_assert(!std::is_constructible_v>, acc_t>); + static_assert( + !std::is_constructible_v>, acc_t>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_span.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_span.pass.cpp index 1de91a11..2bc5a80e 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.dh_span.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.dh_span.pass.cpp @@ -15,13 +15,16 @@ // // Constraints: // - is_convertible_v is true, -// - (is_nothrow_constructible && ...) is true, +// - (is_nothrow_constructible && ...) is +// true, // - N == rank() || N == rank_dynamic() is true, // - is_constructible_v is true, and // - is_default_constructible_v is true. // -// Preconditions: [0, map_.required_span_size()) is an accessible range of p and acc_ -// for the values of map_ and acc_ after the invocation of this constructor. +// Preconditions: [0, map_.required_span_size()) is an accessible range of p and +// acc_ +// for the values of map_ and acc_ after the invocation of this +// constructor. // // Effects: // - Direct-non-list-initializes ptr_ with std::move(p), @@ -42,19 +45,24 @@ #include "CustomTestAccessors.h" template -constexpr auto array_from_extents(const Extents& exts, std::index_sequence) { - return std::array{exts.extent(Idxs)...}; +constexpr auto array_from_extents(const Extents& exts, + std::index_sequence) { + return std::array{ + exts.extent(Idxs)...}; } template -concept check_mdspan_ctor_implicit = requires(MDS m, typename MDS::data_handle_type h, const Exts& exts) { - m = {h, exts}; -}; +concept check_mdspan_ctor_implicit = + requires(MDS m, typename MDS::data_handle_type h, const Exts& exts) { + m = {h, exts}; + }; template -constexpr void -test_mdspan_ctor_span(const H& handle, const M& map, const A&, std::span exts) { - using MDS = std::mdspan; +constexpr void test_mdspan_ctor_span( + const H& handle, const M& map, const A&, + std::span exts) { + using MDS = std::mdspan; #if MDSPAN_HAS_CXX_23 if !consteval { move_counted_handle::move_counter() = 0; @@ -63,7 +71,8 @@ test_mdspan_ctor_span(const H& handle, const M& map, const A&, std::span>) { + if constexpr (std::is_same_v< + H, move_counted_handle>) { assert((H::move_counter() == 1)); } } @@ -71,25 +80,25 @@ test_mdspan_ctor_span(const H& handle, const M& map, const A&, std::span == (N == MDS::rank_dynamic())); + static_assert(check_mdspan_ctor_implicit == + (N == MDS::rank_dynamic())); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == A()); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == A()); } template constexpr void test_mdspan_ctor(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; static_assert(mec == std::is_constructible_v); static_assert(ac == std::is_default_constructible_v); if constexpr (mec && ac) { // test from all extents - auto exts = array_from_extents(map.extents(), std::make_index_sequence()); + auto exts = array_from_extents(map.extents(), + std::make_index_sequence()); test_mdspan_ctor_span(handle, map, acc, std::span(exts)); // test from dynamic extents @@ -101,20 +110,32 @@ constexpr void test_mdspan_ctor(const H& handle, const M& map, const A& acc) { } test_mdspan_ctor_span(handle, map, acc, std::span(exts_dynamic)); } else { - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v< + MDS, const H&, std::span>); } } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_ctor(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_ctor(handle, construct_mapping(layout, std::extents(0, 3)), acc); test_mdspan_ctor( - handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(7)), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_ctor( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_ctor( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template @@ -122,17 +143,26 @@ constexpr void mixin_layout(const H& handle, const A& acc) { mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); - // Sanity check that this layouts mapping is constructible from extents (via its move constructor) - static_assert(std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + // Sanity check that this layouts mapping is constructible from extents (via + // its move constructor) + static_assert( + std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<8>(), acc); // Sanity check that this layouts mapping is not constructible from extents - static_assert(!std::is_constructible_v::template mapping>, - std::extents>); - static_assert(!std::is_constructible_v::template mapping>, - const std::extents&>); + static_assert( + !std::is_constructible_v::template mapping>, + std::extents>); + static_assert( + !std::is_constructible_v::template mapping>, + const std::extents&>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -143,10 +173,13 @@ constexpr void mixin_accessor() { // Using weird accessor/data_handle // Make sure they actually got the properties we want to test - // checked_accessor is not default constructible except for const double, where it is not noexcept - static_assert(std::is_default_constructible_v> == std::is_same_v); + // checked_accessor is not default constructible except for const double, + // where it is not noexcept + static_assert(std::is_default_constructible_v> == + std::is_same_v); mixin_layout>( - typename checked_accessor::data_handle_type(elements.get_ptr()), checked_accessor(1024)); + typename checked_accessor::data_handle_type(elements.get_ptr()), + checked_accessor(1024)); } constexpr bool test() { @@ -175,21 +208,26 @@ constexpr bool test() { using mds_uchar_t = std::mdspan>; static_assert(std::is_convertible_v); static_assert(std::is_convertible_v); - static_assert(!std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_nothrow_constructible_v); + static_assert( + !std::is_constructible_v>); // convertible from non-const to index_type but not from const using mds_int_t = std::mdspan>; static_assert(std::is_convertible_v); static_assert(!std::is_convertible_v); static_assert(std::is_nothrow_constructible_v); - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); - // can't test a combo where std::is_nothrow_constructible_v is true, - // but std::is_convertible_v is false + // can't test a combo where std::is_nothrow_constructible_v is true, but std::is_convertible_v is + // false // test non-constructibility from wrong handle_type - static_assert(!std::is_constructible_v>); + static_assert( + !std::is_constructible_v>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.ctor.move.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.ctor.move.pass.cpp index 4db5bdaf..c7b52f97 100644 --- a/tests/libcxx-backports/mdspan/mdspan.ctor.move.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.ctor.move.pass.cpp @@ -11,7 +11,8 @@ // constexpr mdspan(mdspan&&) = default; // -// A specialization of mdspan is a trivially copyable type if its accessor_type, mapping_type, and data_handle_type are trivially copyable types. +// A specialization of mdspan is a trivially copyable type if its accessor_type, +// mapping_type, and data_handle_type are trivially copyable types. #include #include @@ -26,42 +27,55 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; MDS m_org(handle, map, acc); MDS m(std::move(m_org)); static_assert(std::is_trivially_move_constructible_v == - (std::is_trivially_move_constructible_v && std::is_trivially_move_constructible_v && + (std::is_trivially_move_constructible_v && + std::is_trivially_move_constructible_v && std::is_trivially_move_constructible_v)); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == acc); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == acc); } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template constexpr void mixin_layout(const H& handle, const A& acc) { // make sure we test a trivially copyable mapping - static_assert(std::is_trivially_move_constructible_v>>); + static_assert( + std::is_trivially_move_constructible_v< + typename std::layout_left::template mapping>>); mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); // make sure we test a not trivially copyable mapping - static_assert(!std::is_trivially_move_constructible_v< - typename layout_wrapping_integral<4>::template mapping>>); + static_assert( + !std::is_trivially_move_constructible_v::template mapping>>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -69,17 +83,21 @@ template constexpr void mixin_accessor() { ElementPool elements; // make sure we test trivially constructible accessor and data_handle - static_assert(std::is_trivially_move_constructible_v>); - static_assert(std::is_trivially_move_constructible_v::data_handle_type>); + static_assert( + std::is_trivially_move_constructible_v>); + static_assert(std::is_trivially_move_constructible_v< + typename std::default_accessor::data_handle_type>); mixin_layout(elements.get_ptr(), std::default_accessor()); // Using weird accessor/data_handle // Make sure they actually got the properties we want to test // checked_accessor is noexcept copy constructible except for const double checked_accessor acc(1024); - static_assert(std::is_trivially_move_constructible_v::data_handle_type> == + static_assert(std::is_trivially_move_constructible_v< + typename checked_accessor::data_handle_type> == std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), acc); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), acc); } constexpr bool test() { diff --git a/tests/libcxx-backports/mdspan/mdspan.deduction.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.deduction.pass.cpp index 1f2362e2..6a6cc43f 100644 --- a/tests/libcxx-backports/mdspan/mdspan.deduction.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.deduction.pass.cpp @@ -12,16 +12,18 @@ // template // requires(is_array_v && rank_v == 1) // mdspan(CArray&) -// -> mdspan, extents>>; +// -> mdspan, extents>>; // // template // requires(is_pointer_v>) // mdspan(Pointer&&) -// -> mdspan>, extents>; +// -> mdspan>, +// extents>; // // template -// requires((is_convertible_v && ...) && sizeof...(Integrals) > 0) -// explicit mdspan(ElementType*, Integrals...) +// requires((is_convertible_v && ...) && +// sizeof...(Integrals) > 0) explicit mdspan(ElementType*, Integrals...) // -> mdspan>; // // template @@ -44,7 +46,8 @@ // template // mdspan(const typename AccessorType::data_handle_type&, const MappingType&, // const AccessorType&) -// -> mdspan mdspan; #include @@ -60,12 +63,15 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; - // deduction from data_handle_type (including non-pointer), mapping and accessor + // deduction from data_handle_type (including non-pointer), mapping and + // accessor ASSERT_SAME_TYPE(decltype(std::mdspan(handle, map, acc)), MDS); - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v< + A, std::default_accessor>) { // deduction from pointer and mapping // non-pointer data-handle-types have other accessor ASSERT_SAME_TYPE(decltype(std::mdspan(handle, map)), MDS); @@ -79,12 +85,23 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } struct SizeTIntType { @@ -98,15 +115,19 @@ template constexpr bool test_no_layout_deduction_guides(const H& handle, const A&) { using T = typename A::element_type; // deduction from pointer alone - ASSERT_SAME_TYPE(decltype(std::mdspan(handle)), std::mdspan>); + ASSERT_SAME_TYPE(decltype(std::mdspan(handle)), + std::mdspan>); // deduction from pointer and integral like - ASSERT_SAME_TYPE(decltype(std::mdspan(handle, 5, SizeTIntType(6))), std::mdspan>); + ASSERT_SAME_TYPE(decltype(std::mdspan(handle, 5, SizeTIntType(6))), + std::mdspan>); std::array exts; // deduction from pointer and array - ASSERT_SAME_TYPE(decltype(std::mdspan(handle, exts)), std::mdspan>); + ASSERT_SAME_TYPE(decltype(std::mdspan(handle, exts)), + std::mdspan>); // deduction from pointer and span - ASSERT_SAME_TYPE(decltype(std::mdspan(handle, std::span(exts))), std::mdspan>); + ASSERT_SAME_TYPE(decltype(std::mdspan(handle, std::span(exts))), + std::mdspan>); return true; } @@ -122,7 +143,8 @@ constexpr void mixin_layout(const H& handle, const A& acc) { mixin_extents(handle, layout_wrapping_integral<4>(), acc); // checking that there is no deduction happen for non-pointer handle type - assert((test_no_layout_deduction_guides(handle, acc) == std::is_same_v)); + assert((test_no_layout_deduction_guides(handle, acc) == + std::is_same_v)); } template @@ -134,8 +156,10 @@ constexpr void mixin_accessor() { // Make sure they actually got the properties we want to test // checked_accessor is noexcept copy constructible except for const double checked_accessor acc(1024); - static_assert(noexcept(checked_accessor(acc)) != std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), acc); + static_assert(noexcept(checked_accessor(acc)) != + std::is_same_v); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), acc); } constexpr bool test() { @@ -148,7 +172,8 @@ constexpr bool test() { // deduction from array alone float a[12]; - ASSERT_SAME_TYPE(decltype(std::mdspan(a)), std::mdspan>); + ASSERT_SAME_TYPE(decltype(std::mdspan(a)), + std::mdspan>); return true; } diff --git a/tests/libcxx-backports/mdspan/mdspan.element_type.verify.cpp b/tests/libcxx-backports/mdspan/mdspan.element_type.verify.cpp index a3e7ecb2..a59a6469 100644 --- a/tests/libcxx-backports/mdspan/mdspan.element_type.verify.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.element_type.verify.cpp @@ -9,31 +9,37 @@ // -// template -// class mdspan; +// template class mdspan; // // Mandates: -// - ElementType is a complete object type that is neither an abstract class type nor an array type. +// - ElementType is a complete object type that is neither an abstract class +// type nor an array type. // - is_same_v is true. #include class AbstractClass { -public: + public: virtual void method() = 0; }; void not_abstract_class() { - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType template parameter may not be an abstract class}} + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType + // template parameter may not be an abstract class}} [[maybe_unused]] std::mdspan> m; } void not_array_type() { - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType template parameter may not be an array type}} + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType + // template parameter may not be an array type}} [[maybe_unused]] std::mdspan> m; } void element_type_mismatch() { - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType template parameter must match AccessorPolicy::element_type}} - [[maybe_unused]] std::mdspan, std::layout_right, std::default_accessor> m; + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: ElementType + // template parameter must match AccessorPolicy::element_type}} + [[maybe_unused]] std::mdspan, std::layout_right, + std::default_accessor> + m; } diff --git a/tests/libcxx-backports/mdspan/mdspan.extents.verify.cpp b/tests/libcxx-backports/mdspan/mdspan.extents.verify.cpp index 1ee6f733..3c385158 100644 --- a/tests/libcxx-backports/mdspan/mdspan.extents.verify.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.extents.verify.cpp @@ -9,8 +9,8 @@ // -// template -// class mdspan; +// template class mdspan; // // Mandates: // - Extents is a specialization of extents @@ -18,6 +18,7 @@ #include void not_extents() { - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: Extents template parameter must be a specialization of extents.}} + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: Extents + // template parameter must be a specialization of extents.}} [[maybe_unused]] std::mdspan m; } diff --git a/tests/libcxx-backports/mdspan/mdspan.index_operator.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.index_operator.pass.cpp index 5cca1d80..c1dbc731 100644 --- a/tests/libcxx-backports/mdspan/mdspan.index_operator.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.index_operator.pass.cpp @@ -25,8 +25,8 @@ // GCC warns about comma operator changing its meaning inside [] in C++23 #if defined(__GNUC__) && !defined(__clang_major__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcomma-subscript" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcomma-subscript" #endif #include @@ -38,7 +38,8 @@ #include "../ConvertibleToIntegral.h" #include "../CustomTestLayouts.h" -// This test uses the bracket operator, but its not something we have at configure time +// This test uses the bracket operator, but its not something we have at +// configure time #if MDSPAN_USE_BRACKET_OPERATOR // Clang 16 does not support argument packs as input to operator [] @@ -60,7 +61,8 @@ constexpr auto& access(MDS mds, int64_t i0, int64_t i1, int64_t i2) { return mds[i0, i1, i2]; } template -constexpr auto& access(MDS mds, int64_t i0, int64_t i1, int64_t i2, int64_t i3) { +constexpr auto& access(MDS mds, int64_t i0, int64_t i1, int64_t i2, + int64_t i3) { return mds[i0, i1, i2, i3]; } #endif @@ -84,17 +86,20 @@ constexpr bool check_operator_constraints(MDS, Indices...) { template constexpr void iterate(MDS mds, Args... args) { - constexpr int r = static_cast(MDS::extents_type::rank()) - 1 - static_cast(sizeof...(Args)); + constexpr int r = static_cast(MDS::extents_type::rank()) - 1 - + static_cast(sizeof...(Args)); if constexpr (-1 == r) { #if defined(__clang_major__) && __clang_major__ < 17 int* ptr1 = &access(mds, args...); #else int* ptr1 = &mds[args...]; #endif - int* ptr2 = &(mds.accessor().access(mds.data_handle(), mds.mapping()(args...))); + int* ptr2 = + &(mds.accessor().access(mds.data_handle(), mds.mapping()(args...))); assert(ptr1 == ptr2); - std::array args_arr{static_cast(args)...}; + std::array args_arr{ + static_cast(args)...}; int* ptr3 = &mds[args_arr]; assert(ptr3 == ptr2); int* ptr4 = &mds[std::span(args_arr)]; @@ -109,7 +114,8 @@ constexpr void iterate(MDS mds, Args... args) { template constexpr void test_iteration(Mapping m) { std::array data; - using MDS = std::mdspan; + using MDS = std::mdspan; MDS mds(data.data(), m); iterate(mds); @@ -123,100 +129,142 @@ constexpr void test_layout() { test_iteration(construct_mapping(Layout(), std::extents(7))); test_iteration(construct_mapping(Layout(), std::extents())); test_iteration(construct_mapping(Layout(), std::extents())); - test_iteration(construct_mapping(Layout(), std::extents(1, 1, 1, 1))); + test_iteration( + construct_mapping(Layout(), std::extents(1, 1, 1, 1))); -// TODO enable for GCC 13, when the CI pipeline is switched, doesn't work with GCC 12 +// TODO enable for GCC 13, when the CI pipeline is switched, doesn't work with +// GCC 12 #if defined(__clang_major__) && __clang_major__ >= 17 int data[1]; // Check operator constraint for number of arguments - static_assert(check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), 0)); - static_assert( - !check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), 0, 0)); + static_assert(check_operator_constraints( + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + 0)); + static_assert(!check_operator_constraints( + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + 0, 0)); // Check operator constraint for convertibility of arguments to index_type - static_assert( - check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), IntType(0))); + static_assert(check_operator_constraints( + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + IntType(0))); static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), IntType(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + IntType(0))); - // Check operator constraint for no-throw-constructibility of index_type from arguments + // Check operator constraint for no-throw-constructibility of index_type from + // arguments static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), IntType(0))); + std::mdspan( + data, construct_mapping(Layout(), std::extents(1))), + IntType(0))); - // Check that mixed integrals work: note the second one tests that mdspan casts: layout_wrapping_integral does not accept IntType + // Check that mixed integrals work: note the second one tests that mdspan + // casts: layout_wrapping_integral does not accept IntType static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), int(0), size_t(0))); + std::mdspan(data, construct_mapping( + Layout(), std::extents(1, 1))), + int(0), size_t(0))); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), unsigned(0), IntType(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntType(0))); constexpr bool t = true; constexpr bool o = false; static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), - unsigned(0), - IntConfig(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntConfig(0))); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), - unsigned(0), - IntConfig(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntConfig(0))); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), - unsigned(0), - IntConfig(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntConfig(0))); static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), - unsigned(0), - IntConfig(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntConfig(0))); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1, 1))), - unsigned(0), - IntConfig(0))); + std::mdspan(data, + construct_mapping(Layout(), std::extents(1, 1))), + unsigned(0), IntConfig(0))); // layout_wrapped wouldn't quite work here the way we wrote the check - // IntConfig has configurable conversion properties: convert from const&, convert from non-const, no-throw-ctor from const&, no-throw-ctor from non-const + // IntConfig has configurable conversion properties: convert from const&, + // convert from non-const, no-throw-ctor from const&, no-throw-ctor from + // non-const if constexpr (std::is_same_v) { static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); static_assert(!check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); static_assert(check_operator_constraints( - std::mdspan(data, construct_mapping(Layout(), std::extents(1))), std::array{IntConfig(0)})); + std::mdspan(data, construct_mapping(Layout(), std::extents(1))), + std::array{IntConfig(0)})); { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } { std::array idx{IntConfig(0)}; std::span s(idx); - assert(!check_operator_constraints(std::mdspan(data, construct_mapping(Layout(), std::extents(1))), s)); + assert(!check_operator_constraints( + std::mdspan(data, + construct_mapping(Layout(), std::extents(1))), + s)); } } #endif @@ -225,12 +273,15 @@ constexpr void test_layout() { template constexpr void test_layout_large() { constexpr size_t D = std::dynamic_extent; - test_iteration(construct_mapping(Layout(), std::extents(3, 5, 6))); - test_iteration(construct_mapping(Layout(), std::extents(3, 6))); + test_iteration( + construct_mapping(Layout(), std::extents(3, 5, 6))); + test_iteration( + construct_mapping(Layout(), std::extents(3, 6))); } // mdspan::operator[] casts to index_type before calling mapping -// mapping requirements only require the index operator to mixed integer types not anything convertible to index_type +// mapping requirements only require the index operator to mixed integer types +// not anything convertible to index_type constexpr void test_index_cast_happens() {} constexpr bool test() { @@ -258,8 +309,8 @@ int main(int, char**) { return 0; } -#endif // MDSPAN_USE_BRACKET_OPERATOR +#endif // MDSPAN_USE_BRACKET_OPERATOR #if defined(__GNUC__) && !defined(__clang_major__) -# pragma GCC diagnostic pop +#pragma GCC diagnostic pop #endif diff --git a/tests/libcxx-backports/mdspan/mdspan.mapping.verify.cpp b/tests/libcxx-backports/mdspan/mdspan.mapping.verify.cpp index 581add96..6c7a42d5 100644 --- a/tests/libcxx-backports/mdspan/mdspan.mapping.verify.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.mapping.verify.cpp @@ -9,15 +9,21 @@ // -// template -// class mdspan; +// template class mdspan; // // Mandates: -// - LayoutPolicy shall meet the layout mapping policy requirements ([mdspan.layout.policy.reqmts]) +// - LayoutPolicy shall meet the layout mapping policy requirements +// ([mdspan.layout.policy.reqmts]) #include void not_layout_policy() { - // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: LayoutPolicy template parameter is invalid. A common mistake is to pass a layout mapping instead of a layout policy}} - [[maybe_unused]] std::mdspan, std::layout_left::template mapping>> m; + // expected-error-re@*:* {{static assertion failed {{.*}}mdspan: LayoutPolicy + // template parameter is invalid. A common mistake is to pass a layout mapping + // instead of a layout policy}} + [[maybe_unused]] std::mdspan< + int, std::extents, + std::layout_left::template mapping>> + m; } diff --git a/tests/libcxx-backports/mdspan/mdspan.move.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.move.pass.cpp index 0bc4be36..d0578443 100644 --- a/tests/libcxx-backports/mdspan/mdspan.move.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.move.pass.cpp @@ -11,7 +11,8 @@ // constexpr mdspan& operator=(mdspan&&) = default; // -// A specialization of mdspan is a trivially copyable type if its accessor_type, mapping_type, and data_handle_type are trivially copyable types. +// A specialization of mdspan is a trivially copyable type if its accessor_type, +// mapping_type, and data_handle_type are trivially copyable types. #include #include @@ -26,45 +27,58 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; MDS m_org(handle, map, acc); MDS m_copy(m_org); MDS m(std::move(m_copy)); assert(m.extents() == map.extents()); - if constexpr (std::equality_comparable) - assert(m.data_handle() == handle); - if constexpr (std::equality_comparable) - assert(m.mapping() == map); - if constexpr (std::equality_comparable) - assert(m.accessor() == acc); + if constexpr (std::equality_comparable) assert(m.data_handle() == handle); + if constexpr (std::equality_comparable) assert(m.mapping() == map); + if constexpr (std::equality_comparable) assert(m.accessor() == acc); static_assert(std::is_trivially_move_assignable_v == - (std::is_trivially_move_assignable_v && std::is_trivially_move_assignable_v && + (std::is_trivially_move_assignable_v && + std::is_trivially_move_assignable_v && std::is_trivially_move_assignable_v)); } template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template constexpr void mixin_layout(const H& handle, const A& acc) { // make sure we test a trivially copyable mapping - static_assert(std::is_trivially_move_assignable_v>>); + static_assert( + std::is_trivially_move_assignable_v< + typename std::layout_left::template mapping>>); mixin_extents(handle, std::layout_left(), acc); mixin_extents(handle, std::layout_right(), acc); // make sure we test a not trivially copyable mapping static_assert( - !std::is_trivially_move_assignable_v::template mapping>>); + !std::is_trivially_move_assignable_v::template mapping>>); mixin_extents(handle, layout_wrapping_integral<4>(), acc); } @@ -73,15 +87,18 @@ constexpr void mixin_accessor() { ElementPool elements; // make sure we test trivially constructible accessor and data_handle static_assert(std::is_trivially_copyable_v>); - static_assert(std::is_trivially_copyable_v::data_handle_type>); + static_assert(std::is_trivially_copyable_v< + typename std::default_accessor::data_handle_type>); mixin_layout(elements.get_ptr(), std::default_accessor()); // Using weird accessor/data_handle // Make sure they actually got the properties we want to test // checked_accessor is noexcept copy constructible except for const double checked_accessor acc(1024); - static_assert(noexcept(checked_accessor(acc)) != std::is_same_v); - mixin_layout(typename checked_accessor::data_handle_type(elements.get_ptr()), acc); + static_assert(noexcept(checked_accessor(acc)) != + std::is_same_v); + mixin_layout( + typename checked_accessor::data_handle_type(elements.get_ptr()), acc); } constexpr bool test() { diff --git a/tests/libcxx-backports/mdspan/mdspan.properties.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.properties.pass.cpp index dab43a13..a047ce98 100644 --- a/tests/libcxx-backports/mdspan/mdspan.properties.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.properties.pass.cpp @@ -13,21 +13,23 @@ // class AccessorPolicy = default_accessor> // class mdspan { // public: -// static constexpr rank_type rank() noexcept { return extents_type::rank(); } -// static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } -// static constexpr size_t static_extent(rank_type r) noexcept +// static constexpr rank_type rank() noexcept { return extents_type::rank(); +// } static constexpr rank_type rank_dynamic() noexcept { return +// extents_type::rank_dynamic(); } static constexpr size_t +// static_extent(rank_type r) noexcept // { return extents_type::static_extent(r); } -// constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } +// constexpr index_type extent(rank_type r) const noexcept { return +// extents().extent(r); } // // constexpr size_type size() const noexcept; // [[nodiscard]] constexpr bool empty() const noexcept; // // -// constexpr const extents_type& extents() const noexcept { return map_.extents(); } -// constexpr const data_handle_type& data_handle() const noexcept { return ptr_; } -// constexpr const mapping_type& mapping() const noexcept { return map_; } -// constexpr const accessor_type& accessor() const noexcept { return acc_; } -// static constexpr bool is_always_unique() +// constexpr const extents_type& extents() const noexcept { return +// map_.extents(); } constexpr const data_handle_type& data_handle() const +// noexcept { return ptr_; } constexpr const mapping_type& mapping() const +// noexcept { return map_; } constexpr const accessor_type& accessor() const +// noexcept { return acc_; } static constexpr bool is_always_unique() // { return mapping_type::is_always_unique(); } // static constexpr bool is_always_exhaustive() // { return mapping_type::is_always_exhaustive(); } @@ -48,7 +50,8 @@ // - is_nothrow_move_constructible_v is true, // - is_nothrow_move_assignable_v is true, and // - is_nothrow_swappable_v is true. -// A specialization of mdspan is a trivially copyable type if its accessor_type, mapping_type, and data_handle_type are trivially copyable types. +// A specialization of mdspan is a trivially copyable type if its accessor_type, +// mapping_type, and data_handle_type are trivially copyable types. #include #include @@ -62,7 +65,8 @@ template constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { - using MDS = std::mdspan; + using MDS = std::mdspan; MDS m(handle, map, acc); // ===================================== @@ -177,12 +181,23 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) { template constexpr void mixin_extents(const H& handle, const L& layout, const A& acc) { constexpr size_t D = std::dynamic_extent; - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents()), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(2, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(0, 3)), acc); - test_mdspan_types(handle, construct_mapping(layout, std::extents(1, 2, 3, 2)), acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents()), + acc); + test_mdspan_types(handle, construct_mapping(layout, std::extents(7)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents()), acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(2, 3)), + acc); + test_mdspan_types( + handle, construct_mapping(layout, std::extents(0, 3)), + acc); + test_mdspan_types( + handle, + construct_mapping(layout, + std::extents(1, 2, 3, 2)), + acc); } template diff --git a/tests/libcxx-backports/mdspan/mdspan.swap.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.swap.pass.cpp index 079fb9ef..43fe5018 100644 --- a/tests/libcxx-backports/mdspan/mdspan.swap.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.swap.pass.cpp @@ -41,15 +41,16 @@ constexpr void test_swap(MDS a, MDS b) { assert(a.data_handle() == org_b.data_handle()); assert(b.data_handle() == org_a.data_handle()); } - // This check uses a side effect of layout_wrapping_integral::swap to make sure - // mdspan calls the underlying components' swap via ADL - #if MDSPAN_HAS_CXX23 +// This check uses a side effect of layout_wrapping_integral::swap to make sure +// mdspan calls the underlying components' swap via ADL +#if MDSPAN_HAS_CXX23 if !consteval { - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v>) { assert(MDS::mapping_type::swap_counter() > 0); } } - #endif +#endif } constexpr bool test() { @@ -62,7 +63,8 @@ constexpr bool test() { test_swap(a, b); } { - layout_wrapping_integral<4>::template mapping map_a(extents_t(12), not_extents_constructible_tag()), + layout_wrapping_integral<4>::template mapping map_a( + extents_t(12), not_extents_constructible_tag()), map_b(extents_t(5), not_extents_constructible_tag()); std::mdspan a(data_a, map_a); std::mdspan b(data_b, map_b); diff --git a/tests/libcxx-backports/mdspan/mdspan.types.pass.cpp b/tests/libcxx-backports/mdspan/mdspan.types.pass.cpp index f4cea447..a7c2c1a3 100644 --- a/tests/libcxx-backports/mdspan/mdspan.types.pass.cpp +++ b/tests/libcxx-backports/mdspan/mdspan.types.pass.cpp @@ -9,7 +9,8 @@ // // -// template> // class mdspan { // public: @@ -40,29 +41,33 @@ // Calculated expected size of an mdspan // Note this expectes that only default_accessor is empty -template +template constexpr size_t expected_size() { size_t sizeof_dht = sizeof(typename MDS::data_handle_type); - size_t result = sizeof_dht; - if(MDS::rank_dynamic() > 0) { + size_t result = sizeof_dht; + if (MDS::rank_dynamic() > 0) { size_t alignof_idx = alignof(typename MDS::index_type); - size_t sizeof_idx = sizeof(typename MDS::index_type); + size_t sizeof_idx = sizeof(typename MDS::index_type); // add alignment if necessary - result += sizeof_dht%alignof_idx == 0?0:alignof_idx - (sizeof_dht%alignof_idx); + result += sizeof_dht % alignof_idx == 0 + ? 0 + : alignof_idx - (sizeof_dht % alignof_idx); // add sizeof stored extents result += MDS::rank_dynamic() * sizeof_idx; } using A = typename MDS::accessor_type; - if(!std::is_same_v>) { + if (!std::is_same_v>) { size_t alignof_acc = alignof(A); - size_t sizeof_acc = sizeof(A); + size_t sizeof_acc = sizeof(A); // add alignment if necessary - result += result%alignof_acc == 0?0:alignof_acc - (result%alignof_acc); + result += + result % alignof_acc == 0 ? 0 : alignof_acc - (result % alignof_acc); // add sizeof stored accessor result += sizeof_acc; } // add alignment of the mdspan itself - result += result%alignof(MDS) == 0?0:alignof(MDS) - (result%alignof(MDS)); + result += + result % alignof(MDS) == 0 ? 0 : alignof(MDS) - (result % alignof(MDS)); return result; } @@ -80,7 +85,8 @@ constexpr bool trv_cp_asgn = std::is_trivially_copy_assignable_v; template constexpr bool trv_mv_asgn = std::is_trivially_move_assignable_v; -template +template void check_triviality() { static_assert(trv_df_ctor == default_ctor); static_assert(trv_cp_ctor == copy_ctor); @@ -103,28 +109,33 @@ void test_mdspan_types() { ASSERT_SAME_TYPE(typename MDS::index_type, typename E::index_type); ASSERT_SAME_TYPE(typename MDS::size_type, typename E::size_type); ASSERT_SAME_TYPE(typename MDS::rank_type, typename E::rank_type); - ASSERT_SAME_TYPE(typename MDS::data_handle_type, typename A::data_handle_type); + ASSERT_SAME_TYPE(typename MDS::data_handle_type, + typename A::data_handle_type); ASSERT_SAME_TYPE(typename MDS::reference, typename A::reference); // This miserably failed with clang-cl - likely because it doesn't honor/enable // no-unique-address fully by default #ifndef _WIN32 // check the size of mdspan - if constexpr (std::is_same_v || std::is_same_v) { + if constexpr (std::is_same_v || + std::is_same_v) { LIBCPP_STATIC_ASSERT(sizeof(MDS) == expected_size()); } #endif // check default template parameters: - ASSERT_SAME_TYPE(std::mdspan, std::mdspan>); - ASSERT_SAME_TYPE(std::mdspan, std::mdspan>); + ASSERT_SAME_TYPE( + std::mdspan, + std::mdspan>); + ASSERT_SAME_TYPE(std::mdspan, + std::mdspan>); // check triviality using DH = typename MDS::data_handle_type; using MP = typename MDS::mapping_type; check_triviality && trv_cp_ctor && trv_cp_ctor, trv_mv_ctor && trv_mv_ctor && trv_mv_ctor, trv_dstruct && trv_dstruct && trv_dstruct, @@ -167,14 +178,12 @@ int main(int, char**) { mixin_accessor(); // sanity checks for triviality - check_triviality>, false, true, true, true, true, true>(); - check_triviality>, false, true, true, true, true, true>(); - check_triviality, std::layout_right, checked_accessor>, - false, - true, - false, - true, - true, - true>(); + check_triviality>, false, true, true, true, + true, true>(); + check_triviality>, false, true, true, + true, true, true>(); + check_triviality, std::layout_right, + checked_accessor>, + false, true, false, true, true, true>(); return 0; } diff --git a/tests/offload_utils.hpp b/tests/offload_utils.hpp index 3422d2d9..114fa471 100644 --- a/tests/offload_utils.hpp +++ b/tests/offload_utils.hpp @@ -23,158 +23,160 @@ #include #endif -#include +#include namespace { bool dispatch_host = true; #ifdef MDSPAN_IMPL_HAS_SYCL -#define MDSPAN_IMPL_DEVICE_ASSERT_EQ(LHS, RHS) \ -if (!(LHS == RHS)) { \ - sycl::ext::oneapi::experimental::printf("expected equality of %s and %s\n", #LHS, #RHS); \ - errors[0]++; \ -} +#define MDSPAN_IMPL_DEVICE_ASSERT_EQ(LHS, RHS) \ + if (!(LHS == RHS)) { \ + sycl::ext::oneapi::experimental::printf( \ + "expected equality of %s and %s\n", #LHS, #RHS); \ + errors[0]++; \ + } #else - #define MDSPAN_IMPL_DEVICE_ASSERT_EQ(LHS, RHS) \ - if (!(LHS == RHS)) { \ - printf("expected equality of %s and %s\n", #LHS, #RHS); \ - errors[0]++; \ -} +#define MDSPAN_IMPL_DEVICE_ASSERT_EQ(LHS, RHS) \ + if (!(LHS == RHS)) { \ + printf("expected equality of %s and %s\n", #LHS, #RHS); \ + errors[0]++; \ + } #endif #if defined(MDSPAN_IMPL_HAS_CUDA) || defined(MDSPAN_IMPL_HAS_HIP) #if defined(MDSPAN_IMPL_HAS_CUDA) -void deviceSynchronize() { (void) cudaDeviceSynchronize(); } -template -void mallocManaged(T** ptr, size_t size) { (void) cudaMallocManaged(ptr, size); } -template -void freeManaged(T* ptr) { (void) cudaFree(ptr); } +void deviceSynchronize() { (void)cudaDeviceSynchronize(); } +template +void mallocManaged(T** ptr, size_t size) { + (void)cudaMallocManaged(ptr, size); +} +template +void freeManaged(T* ptr) { + (void)cudaFree(ptr); +} #endif #if defined(MDSPAN_IMPL_HAS_HIP) -void deviceSynchronize() { (void) hipDeviceSynchronize(); } -template -void mallocManaged(T** ptr, size_t size) { (void) hipMallocManaged(ptr, size); } -template -void freeManaged(T* ptr) { (void) hipFree(ptr); } +void deviceSynchronize() { (void)hipDeviceSynchronize(); } +template +void mallocManaged(T** ptr, size_t size) { + (void)hipMallocManaged(ptr, size); +} +template +void freeManaged(T* ptr) { + (void)hipFree(ptr); +} #endif -template +template __global__ void dispatch_kernel(const LAMBDA f) { f(); } -template +template void dispatch(LAMBDA&& f) { - if(dispatch_host) { + if (dispatch_host) { static_cast(f)(); } else { - dispatch_kernel<<<1,1>>>(static_cast(f)); + dispatch_kernel<<<1, 1>>>(static_cast(f)); deviceSynchronize(); } } -template +template T* allocate_array(size_t size) { T* ptr = nullptr; - if(dispatch_host == true) + if (dispatch_host == true) ptr = new T[size]; else - mallocManaged(&ptr, sizeof(T)*size); + mallocManaged(&ptr, sizeof(T) * size); return ptr; } -template +template void free_array(T* ptr) { - if(dispatch_host == true) - delete [] ptr; + if (dispatch_host == true) + delete[] ptr; else freeManaged(ptr); } #define MDSPAN_IMPL_TESTS_RUN_TEST(A) \ - dispatch_host = true; \ - A; \ - dispatch_host = false; \ - A; + dispatch_host = true; \ + A; \ + dispatch_host = false; \ + A; #define MDSPAN_IMPL_TESTS_DISPATCH_DEFINED -#endif // MDSPAN_IMPL_HAS_CUDA +#endif // MDSPAN_IMPL_HAS_CUDA #ifdef MDSPAN_IMPL_HAS_SYCL -sycl::queue get_test_queue() -{ +sycl::queue get_test_queue() { static sycl::queue q; return q; } -template +template void dispatch(LAMBDA&& f) { - if(dispatch_host) { + if (dispatch_host) { static_cast(f)(); } else { sycl::queue q = get_test_queue(); - q.submit([&](sycl::handler &cgh) { - cgh.single_task([=]() { - f(); - }); - }); + q.submit([&](sycl::handler& cgh) { cgh.single_task([=]() { f(); }); }); q.wait_and_throw(); } } -template +template T* allocate_array(size_t size) { - if(dispatch_host == true) + if (dispatch_host == true) return new T[size]; - else - { + else { sycl::queue q = get_test_queue(); return sycl::malloc_shared(size, q); } } -template +template void free_array(T* ptr) { - if(dispatch_host == true) - delete [] ptr; - else - { + if (dispatch_host == true) + delete[] ptr; + else { sycl::queue q = get_test_queue(); sycl::free(ptr, q); } } #define MDSPAN_IMPL_TESTS_RUN_TEST(A) \ - dispatch_host = true; \ - A; \ - dispatch_host = false; \ - A; + dispatch_host = true; \ + A; \ + dispatch_host = false; \ + A; #define MDSPAN_IMPL_TESTS_DISPATCH_DEFINED -#endif // MDSPAN_IMPL_HAS_SYCL +#endif // MDSPAN_IMPL_HAS_SYCL #ifndef MDSPAN_IMPL_TESTS_DISPATCH_DEFINED -template +template void dispatch(LAMBDA&& f) { static_cast(f)(); } -template +template T* allocate_array(size_t size) { T* ptr = nullptr; - ptr = new T[size]; + ptr = new T[size]; return ptr; } -template +template void free_array(T* ptr) { - delete [] ptr; + delete[] ptr; } #define MDSPAN_IMPL_TESTS_RUN_TEST(A) \ - dispatch_host = true; \ - A; + dispatch_host = true; \ + A; #endif -} // namespace +} // namespace diff --git a/tests/test_alternate_precondition_violation_handler.cpp b/tests/test_alternate_precondition_violation_handler.cpp index 1cc3998b..71a2d8b5 100644 --- a/tests/test_alternate_precondition_violation_handler.cpp +++ b/tests/test_alternate_precondition_violation_handler.cpp @@ -1,24 +1,20 @@ #include #define MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line) \ - do { \ - throw std::logic_error{"precondition failure"}; \ + do { \ + throw std::logic_error{"precondition failure"}; \ } while (0); #include #include -TEST(mdspan_macros, alternate_precondition_violation_handler) -{ +TEST(mdspan_macros, alternate_precondition_violation_handler) { ASSERT_THROW(MDSPAN_IMPL_PRECONDITION(false), std::logic_error); } -TEST(mdspan_macros, alternate_precondition_check_constexpr_invocable) -{ - struct fn - { - constexpr auto operator()() const - { +TEST(mdspan_macros, alternate_precondition_check_constexpr_invocable) { + struct fn { + constexpr auto operator()() const { MDSPAN_IMPL_PRECONDITION(1 + 1 == 2); return 42; } diff --git a/tests/test_dims.cpp b/tests/test_dims.cpp index 7ceb6f35..826f2be6 100644 --- a/tests/test_dims.cpp +++ b/tests/test_dims.cpp @@ -20,36 +20,40 @@ namespace test { -template +template static constexpr bool is_extents_v = false; -template +template static constexpr bool is_extents_v< - MDSPAN_IMPL_STANDARD_NAMESPACE :: extents -> = true; + MDSPAN_IMPL_STANDARD_NAMESPACE ::extents > = true; -template -void test_dims_with_one_template_argument() -{ - using d = MDSPAN_IMPL_STANDARD_NAMESPACE :: MDSPAN_IMPL_PROPOSED_NAMESPACE :: dims; - static_assert(test::is_extents_v, "dims is not an extents specialization"); - static_assert(std::is_same::value, "dims::index_type is wrong"); +template +void test_dims_with_one_template_argument() { + using d = + MDSPAN_IMPL_STANDARD_NAMESPACE ::MDSPAN_IMPL_PROPOSED_NAMESPACE ::dims< + Rank>; + static_assert(test::is_extents_v, + "dims is not an extents specialization"); + static_assert(std::is_same::value, + "dims::index_type is wrong"); static_assert(d::rank() == Rank, "dims::rank() is wrong"); } -template -void test_dims_with_two_template_arguments() -{ - using d = MDSPAN_IMPL_STANDARD_NAMESPACE :: MDSPAN_IMPL_PROPOSED_NAMESPACE :: dims; - static_assert(test::is_extents_v, "dims is not an extents specialization"); - static_assert(std::is_same::value, "dims::index_type is wrong"); +template +void test_dims_with_two_template_arguments() { + using d = + MDSPAN_IMPL_STANDARD_NAMESPACE ::MDSPAN_IMPL_PROPOSED_NAMESPACE ::dims< + Rank, ExpectedIndexType>; + static_assert(test::is_extents_v, + "dims is not an extents specialization"); + static_assert(std::is_same::value, + "dims::index_type is wrong"); static_assert(d::rank() == Rank, "dims::rank() is wrong"); } - -} // namespace test -TEST(TestDims, Test0) -{ +} // namespace test + +TEST(TestDims, Test0) { using test::test_dims_with_one_template_argument; using test::test_dims_with_two_template_arguments; diff --git a/tests/test_element_access.cpp b/tests/test_element_access.cpp index 3c3e46b0..1ce9c461 100644 --- a/tests/test_element_access.cpp +++ b/tests/test_element_access.cpp @@ -18,11 +18,10 @@ #include - TEST(TestElementAccess, element_access_with_std_array) { - std::array a{}; - Kokkos::mdspan> s(a.data()); - ASSERT_EQ(MDSPAN_IMPL_OP(s, (std::array{1, 2})), 0); - MDSPAN_IMPL_OP(s, (std::array{0, 1})) = 3.14; - ASSERT_EQ(MDSPAN_IMPL_OP(s, (std::array{0, 1})), 3.14); + std::array a{}; + Kokkos::mdspan> s(a.data()); + ASSERT_EQ(MDSPAN_IMPL_OP(s, (std::array{1, 2})), 0); + MDSPAN_IMPL_OP(s, (std::array{0, 1})) = 3.14; + ASSERT_EQ(MDSPAN_IMPL_OP(s, (std::array{0, 1})), 3.14); } diff --git a/tests/test_exhaustive_layouts.cpp b/tests/test_exhaustive_layouts.cpp index f6481087..fce3126e 100644 --- a/tests/test_exhaustive_layouts.cpp +++ b/tests/test_exhaustive_layouts.cpp @@ -24,42 +24,36 @@ MDSPAN_IMPL_INLINE_VARIABLE constexpr auto dyn = Kokkos::dynamic_extent; template size_t get_expected_mapping( - typename Kokkos::layout_left::template mapping const& map, - size_t i, size_t j, size_t k -) -{ + typename Kokkos::layout_left::template mapping const& map, + size_t i, size_t j, size_t k) { auto const& extents = map.extents(); - return i + j*extents.extent(0) + k*extents.extent(0)*extents.extent(1); + return i + j * extents.extent(0) + k * extents.extent(0) * extents.extent(1); } template size_t get_expected_mapping( - typename Kokkos::layout_right::template mapping const& map, - size_t i, size_t j, size_t k -) -{ + typename Kokkos::layout_right::template mapping const& map, + size_t i, size_t j, size_t k) { auto const& extents = map.extents(); - return k + j*extents.extent(2) + i*extents.extent(1)*extents.extent(2); + return k + j * extents.extent(2) + i * extents.extent(1) * extents.extent(2); } -template struct TestLayout; +template +struct TestLayout; template -struct TestLayout ->> : public ::testing::Test -{ +struct TestLayout< + std::tuple>> + : public ::testing::Test { Mapping map; void initialize_mapping() { - using extents_type = std::remove_cv_t>; + using extents_type = + std::remove_cv_t>; map = Mapping(extents_type(DynamicSizes...)); } - void SetUp() override { - initialize_mapping(); - } + void SetUp() override { initialize_mapping(); } template size_t expected_mapping(Index... idxs) const { @@ -68,263 +62,468 @@ struct TestLayout -using test_3d_left_types = std::tuple< - typename Kokkos::layout_left::template mapping, - std::integer_sequence ->; +using test_3d_left_types = + std::tuple, + std::integer_sequence>; template -using test_3d_right_types = std::tuple< - typename Kokkos::layout_right::template mapping, - std::integer_sequence ->; - -using layout_test_types_3d = - ::testing::Types< - test_3d_left_types>, - test_3d_left_types>, - test_3d_left_types, 5>, - test_3d_left_types, 3>, - test_3d_left_types, 4>, - test_3d_left_types, 4>, - test_3d_left_types, 3>, - test_3d_left_types, 5>, - test_3d_left_types, 3, 4>, - test_3d_left_types, 5, 4>, - test_3d_left_types, 3, 5>, - test_3d_left_types, 5, 3>, - test_3d_left_types, 4, 5>, - test_3d_left_types, 4, 3>, - test_3d_left_types, 3, 4, 5>, - test_3d_left_types, 5, 4, 3>, - test_3d_right_types>, - test_3d_right_types>, - test_3d_right_types, 5>, - test_3d_right_types, 3>, - test_3d_right_types, 4>, - test_3d_right_types, 4>, - test_3d_right_types, 3>, - test_3d_right_types, 5>, - test_3d_right_types, 3, 4>, - test_3d_right_types, 5, 4>, - test_3d_right_types, 3, 5>, - test_3d_right_types, 5, 3>, - test_3d_right_types, 4, 5>, - test_3d_right_types, 4, 3>, - test_3d_right_types, 3, 4, 5>, - test_3d_right_types, 5, 4, 3> - >; - -template struct TestLayout3D : TestLayout { }; +using test_3d_right_types = + std::tuple, + std::integer_sequence>; + +using layout_test_types_3d = ::testing::Types< + test_3d_left_types>, + test_3d_left_types>, + test_3d_left_types, 5>, + test_3d_left_types, 3>, + test_3d_left_types, 4>, + test_3d_left_types, 4>, + test_3d_left_types, 3>, + test_3d_left_types, 5>, + test_3d_left_types, 3, 4>, + test_3d_left_types, 5, 4>, + test_3d_left_types, 3, 5>, + test_3d_left_types, 5, 3>, + test_3d_left_types, 4, 5>, + test_3d_left_types, 4, 3>, + test_3d_left_types, 3, 4, 5>, + test_3d_left_types, 5, 4, 3>, + test_3d_right_types>, + test_3d_right_types>, + test_3d_right_types, 5>, + test_3d_right_types, 3>, + test_3d_right_types, 4>, + test_3d_right_types, 4>, + test_3d_right_types, 3>, + test_3d_right_types, 5>, + test_3d_right_types, 3, 4>, + test_3d_right_types, 5, 4>, + test_3d_right_types, 3, 5>, + test_3d_right_types, 5, 3>, + test_3d_right_types, 4, 5>, + test_3d_right_types, 4, 3>, + test_3d_right_types, 3, 4, 5>, + test_3d_right_types, 5, 4, 3>>; + +template +struct TestLayout3D : TestLayout {}; TYPED_TEST_SUITE(TestLayout3D, layout_test_types_3d); TYPED_TEST(TestLayout3D, mapping_works) { - for(size_t i = 0; i < this->map.extents().extent(0); ++i) { - for(size_t j = 0; j < this->map.extents().extent(1); ++j) { - for(size_t k = 0; k < this->map.extents().extent(2); ++k) { + for (size_t i = 0; i < this->map.extents().extent(0); ++i) { + for (size_t j = 0; j < this->map.extents().extent(1); ++j) { + for (size_t k = 0; k < this->map.extents().extent(2); ++k) { EXPECT_EQ(this->map(i, j, k), this->expected_mapping(i, j, k)) - << "Incorrect mapping for index " << i << ", " << j << ", " << k - << " with extents " - << this->map.extents().extent(0) << ", " - << this->map.extents().extent(1) << ", " - << this->map.extents().extent(2) << "."; + << "Incorrect mapping for index " << i << ", " << j << ", " << k + << " with extents " << this->map.extents().extent(0) << ", " + << this->map.extents().extent(1) << ", " + << this->map.extents().extent(2) << "."; } } } } TYPED_TEST(TestLayout3D, required_span_size_works) { - ASSERT_EQ(this->map.required_span_size(), 3*4*5); + ASSERT_EQ(this->map.required_span_size(), 3 * 4 * 5); } -template +template using test_layout_conversion = - std::tuple, - std::integral_constant>; + std::tuple, + std::integral_constant>; // We separate layout_conversion_test_types into multiple type lists // in order to avoid an nvc++ compiler error (recursion too deep). // Left <=> Left conversion -using layout_conversion_test_types_left_to_left = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,0> // intentional 0 here to test degenerated - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_left_to_left = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, + 0> // intentional 0 here to test degenerated + , + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, 5, + 10, 15, 20, 25>>; // Right <=> Right conversion -using layout_conversion_test_types_right_to_right = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_right_to_right = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, 5, + 10, 15, 20, 25>>; // Stride <=> Stride conversion -using layout_conversion_test_types_stride_to_stride = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_stride_to_stride = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, 5, + 10, 15, 20, 25>>; // Right => Stride conversion -using layout_conversion_test_types_right_to_stride = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_right_to_stride = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, 5, + 10, 15, 20, 25>>; // Left => Stride conversion -using layout_conversion_test_types_left_to_stride = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, true, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, true, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_left_to_stride = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, true, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, true, 5, + 10, 15, 20, 25>>; // Stride => Left conversion -using layout_conversion_test_types_stride_to_left = - ::testing::Types< - test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_stride_to_left = ::testing::Types< + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, 5, + 10, 15, 20, 25>>; // Stride => Right conversion -using layout_conversion_test_types_stride_to_right = - ::testing::Types< - test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,0> //intentional 0 to test degenerate - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5,10> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - ,test_layout_conversion, Kokkos::extents, false, 5, 10, 15, 20, 25> - >; +using layout_conversion_test_types_stride_to_right = ::testing::Types< + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, + 0> // intentional 0 to test degenerate + , + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, 5, 10>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, + 5, 10, 15, 20, 25>, + test_layout_conversion, + Kokkos::extents, false, 5, + 10, 15, 20, 25>>; // Left <=> Right conversion -using layout_conversion_test_types_left_to_right = - ::testing::Types< - test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true, 5> - ,test_layout_conversion, Kokkos::extents, false, 5> - ,test_layout_conversion, Kokkos::extents, true> - ,test_layout_conversion, Kokkos::extents, true> - >; - -template struct TestLayoutConversion; - -template +using layout_conversion_test_types_left_to_right = ::testing::Types< + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, + Kokkos::extents, true, 5>, + test_layout_conversion, + Kokkos::extents, false, 5>, + test_layout_conversion, Kokkos::extents, + true>, + test_layout_conversion, Kokkos::extents, + true>>; + +template +struct TestLayoutConversion; + +template struct TestLayoutConversion< - std::tuple, - std::integral_constant>> : public ::testing::Test { + std::tuple, + std::integral_constant>> + : public ::testing::Test { static constexpr bool implicit = Implicit; - using layout_1_t = Layout1; - using exts_1_t = Extents1; - using map_1_t = typename Layout1::template mapping; - using layout_2_t = Layout2; - using exts_2_t = Extents2; - using map_2_t = typename Layout2::template mapping; - exts_1_t exts1 { AllSizes... }; - exts_2_t exts2 { AllSizes... }; - - map_1_t implicit_conv(map_1_t map) const { - return map; - } - - template + using layout_1_t = Layout1; + using exts_1_t = Extents1; + using map_1_t = typename Layout1::template mapping; + using layout_2_t = Layout2; + using exts_2_t = Extents2; + using map_2_t = typename Layout2::template mapping; + exts_1_t exts1{AllSizes...}; + exts_2_t exts2{AllSizes...}; + + map_1_t implicit_conv(map_1_t map) const { return map; } + + template static constexpr std::enable_if_t< - std::is_same::value && - !std::is_same::value && - std::is_same::value, - map_2_t> create_map2(Extents exts) { - return map_2_t(map_1_t(Extents1(exts))); + std::is_same::value && + !std::is_same::value && + std::is_same::value, + map_2_t> + create_map2(Extents exts) { + return map_2_t(map_1_t(Extents1(exts))); } - template + template static constexpr std::enable_if_t< - std::is_same::value && - std::is_same::value && - std::is_same::value, - map_2_t> create_map2(Extents exts) { - return map_2_t(typename Kokkos::layout_left::template mapping(exts)); + std::is_same::value && + std::is_same::value && + std::is_same::value, + map_2_t> + create_map2(Extents exts) { + return map_2_t( + typename Kokkos::layout_left::template mapping(exts)); } - template + template static constexpr std::enable_if_t< - std::is_same::value && - !std::is_same::value, - map_2_t> create_map2(Extents exts) { - return map_2_t(exts); + std::is_same::value && + !std::is_same::value, + map_2_t> + create_map2(Extents exts) { + return map_2_t(exts); } }; @@ -332,68 +531,77 @@ struct TestLayoutConversion< // because this results in duplicate test names. // However, creating an alias for each suite works around this. -TYPED_TEST_SUITE(TestLayoutConversion, layout_conversion_test_types_left_to_left); +TYPED_TEST_SUITE(TestLayoutConversion, + layout_conversion_test_types_left_to_left); -template +template using TestLayoutConversion_R2R = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_R2R, layout_conversion_test_types_right_to_right); +TYPED_TEST_SUITE(TestLayoutConversion_R2R, + layout_conversion_test_types_right_to_right); -template +template using TestLayoutConversion_S2S = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_S2S, layout_conversion_test_types_stride_to_stride); +TYPED_TEST_SUITE(TestLayoutConversion_S2S, + layout_conversion_test_types_stride_to_stride); -template +template using TestLayoutConversion_R2S = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_R2S, layout_conversion_test_types_right_to_stride); +TYPED_TEST_SUITE(TestLayoutConversion_R2S, + layout_conversion_test_types_right_to_stride); -template +template using TestLayoutConversion_L2S = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_L2S, layout_conversion_test_types_left_to_stride); +TYPED_TEST_SUITE(TestLayoutConversion_L2S, + layout_conversion_test_types_left_to_stride); -template +template using TestLayoutConversion_S2L = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_S2L, layout_conversion_test_types_stride_to_left); +TYPED_TEST_SUITE(TestLayoutConversion_S2L, + layout_conversion_test_types_stride_to_left); -template +template using TestLayoutConversion_S2R = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_S2R, layout_conversion_test_types_stride_to_right); +TYPED_TEST_SUITE(TestLayoutConversion_S2R, + layout_conversion_test_types_stride_to_right); -template +template using TestLayoutConversion_L2R = TestLayoutConversion; -TYPED_TEST_SUITE(TestLayoutConversion_L2R, layout_conversion_test_types_left_to_right); +TYPED_TEST_SUITE(TestLayoutConversion_L2R, + layout_conversion_test_types_left_to_right); TYPED_TEST(TestLayoutConversion, implicit_conversion) { typename TestFixture::map_2_t map2 = this->create_map2(this->exts2); typename TestFixture::map_1_t map1; - #if MDSPAN_HAS_CXX_20 && !defined(MDSPAN_IMPL_COMPILER_MSVC) +#if MDSPAN_HAS_CXX_20 && !defined(MDSPAN_IMPL_COMPILER_MSVC) static_assert(TestFixture::implicit == - ( - ( - !std::is_same::value && - std::is_convertible::value - ) || ( - std::is_same::value && - std::is_same::value && - std::is_convertible::value - )|| ( - std::is_same::value && - !std::is_same::value && - TestFixture::exts_2_t::rank()==0 - ) - ) - ); - static_assert(std::is_convertible::value == + ((!std::is_same::value && + std::is_convertible::value) || + (std::is_same::value && + std::is_same::value && + std::is_convertible::value) || + (std::is_same::value && + !std::is_same::value && + TestFixture::exts_2_t::rank() == 0))); + static_assert(std::is_convertible::value == TestFixture::implicit); - if constexpr(TestFixture::implicit) + if constexpr (TestFixture::implicit) map1 = this->implicit_conv(map2); else - #endif +#endif map1 = typename TestFixture::map_1_t(map2); #if MDSPAN_HAS_CXX_20 if constexpr (TestFixture::exts_1_t::rank() > 0) { #endif - for(size_t r=0; r != this->exts1.rank(); ++r) { + for (size_t r = 0; r != this->exts1.rank(); ++r) { ASSERT_EQ(map1.extents().extent(r), map2.extents().extent(r)); ASSERT_EQ(map1.stride(r), map2.stride(r)); } diff --git a/tests/test_extents.cpp b/tests/test_extents.cpp index 718fc4a4..1bd65af2 100644 --- a/tests/test_extents.cpp +++ b/tests/test_extents.cpp @@ -18,41 +18,42 @@ #include "offload_utils.hpp" #include - // Making actual test implementations part of the class, -// can't create CUDA lambdas in the primary test functions, since they are private -// making a non-member function would require replicating all the type info +// can't create CUDA lambdas in the primary test functions, since they are +// private making a non-member function would require replicating all the type +// info -template struct TestExtents; +template +struct TestExtents; template -struct TestExtents< - std::tuple< - Kokkos::extents, - std::integer_sequence - > -> : public ::testing::Test { - using extents_type = Kokkos::extents; +struct TestExtents, + std::integer_sequence>> + : public ::testing::Test { + using extents_type = Kokkos::extents; // Double Braces here to make it work with GCC 5 - // Otherwise: "error: array must be initialized with a brace-enclosed initializer" - const std::array static_sizes {{ Extents... }}; - const std::array dyn_sizes {{ DynamicSizes... }}; - extents_type exts { DynamicSizes... }; - using Fixture = TestExtents< std::tuple< - Kokkos::extents, - std::integer_sequence - >>; + // Otherwise: "error: array must be initialized with a brace-enclosed + // initializer" + const std::array static_sizes{{Extents...}}; + const std::array dyn_sizes{ + {DynamicSizes...}}; + extents_type exts{DynamicSizes...}; + using Fixture = + TestExtents, + std::integer_sequence>>; void test_rank() { size_t* result = allocate_array(2); - dispatch([=] MDSPAN_IMPL_HOST_DEVICE () { + dispatch([=] MDSPAN_IMPL_HOST_DEVICE() { extents_type exts(DynamicSizes...); // Silencing an unused warning in nvc++ the condition will never be true - size_t dyn_val = exts.rank()>0?static_cast(exts.extent(0)):1; + size_t dyn_val = + exts.rank() > 0 ? static_cast(exts.extent(0)) : 1; result[0] = dyn_val > 1e9 ? dyn_val : exts.rank(); result[1] = exts.rank_dynamic(); - // Some compilers warn about unused exts since the functions are all static constexpr - (void) exts; + // Some compilers warn about unused exts since the functions are all + // static constexpr + (void)exts; }); EXPECT_EQ(result[0], static_sizes.size()); EXPECT_EQ(result[1], dyn_sizes.size()); @@ -63,17 +64,18 @@ struct TestExtents< void test_static_extent() { size_t* result = allocate_array(extents_type::rank()); - dispatch([=] MDSPAN_IMPL_HOST_DEVICE () { + dispatch([=] MDSPAN_IMPL_HOST_DEVICE() { extents_type exts(DynamicSizes...); - for(size_t r=0; r(exts.extent(r)); - result[r] = dyn_val > 1e9 ? dyn_val : exts.static_extent(r); + result[r] = dyn_val > 1e9 ? dyn_val : exts.static_extent(r); } - // Some compilers warn about unused exts since the functions are all static constexpr - (void) exts; + // Some compilers warn about unused exts since the functions are all + // static constexpr + (void)exts; }); - for(size_t r=0; r(extents_type::rank()); - dispatch([=] MDSPAN_IMPL_HOST_DEVICE () { + dispatch([=] MDSPAN_IMPL_HOST_DEVICE() { extents_type exts(DynamicSizes...); - for(size_t r=0; r using sizes = std::integer_sequence; template -using exts = Kokkos::extents; +using exts = Kokkos::extents; -using extents_test_types = - ::testing::Types< +using extents_test_types = ::testing::Types< std::tuple, sizes<>>, std::tuple, sizes<10>>, std::tuple, sizes<>>, std::tuple, sizes<10>>, std::tuple, sizes<3>>, - std::tuple, sizes<10, 3>> - >; + std::tuple, + sizes<10, 3>>>; TYPED_TEST_SUITE(TestExtents, extents_test_types); -TYPED_TEST(TestExtents, rank) { - MDSPAN_IMPL_TESTS_RUN_TEST(this->test_rank()) -} +TYPED_TEST(TestExtents, rank){MDSPAN_IMPL_TESTS_RUN_TEST(this->test_rank())} -TYPED_TEST(TestExtents, static_extent) { - MDSPAN_IMPL_TESTS_RUN_TEST(this->test_static_extent()) -} +TYPED_TEST(TestExtents, static_extent){ + MDSPAN_IMPL_TESTS_RUN_TEST(this->test_static_extent())} -TYPED_TEST(TestExtents, extent) { - MDSPAN_IMPL_TESTS_RUN_TEST(this->test_extent()) -} +TYPED_TEST(TestExtents, extent){MDSPAN_IMPL_TESTS_RUN_TEST(this->test_extent())} TYPED_TEST(TestExtents, default_ctor) { - auto e = typename TestFixture::extents_type(); + auto e = typename TestFixture::extents_type(); auto e2 = typename TestFixture::extents_type{}; EXPECT_EQ(e, e2); for (size_t r = 0; r < e.rank(); ++r) { @@ -146,7 +142,7 @@ TYPED_TEST(TestExtents, array_ctor) { } TYPED_TEST(TestExtents, copy_ctor) { - typename TestFixture::extents_type e { this->exts }; + typename TestFixture::extents_type e{this->exts}; EXPECT_EQ(e, this->exts); } @@ -158,94 +154,117 @@ TYPED_TEST(TestExtents, copy_assign) { // Only types can be part of the gtest type iteration // so i need this wrapper to wrap around true/false values -template +template struct BoolPairDeducer { static constexpr bool val1 = Val1; static constexpr bool val2 = Val2; }; - -template struct TestExtentsCompatCtors; -template -struct TestExtentsCompatCtors, - std::integer_sequence, - Kokkos::extents, - std::integer_sequence, - BoolPairDeducer ->> : public ::testing::Test { - using extents_type1 = Kokkos::extents; - using extents_type2 = Kokkos::extents; - extents_type1 exts1 { DynamicSizes... }; - extents_type2 exts2 { DynamicSizes2... }; +template +struct TestExtentsCompatCtors; +template +struct TestExtentsCompatCtors< + std::tuple, + std::integer_sequence, + Kokkos::extents, + std::integer_sequence, + BoolPairDeducer>> + : public ::testing::Test { + using extents_type1 = Kokkos::extents; + using extents_type2 = Kokkos::extents; + extents_type1 exts1{DynamicSizes...}; + extents_type2 exts2{DynamicSizes2...}; static constexpr bool implicit_exts1_to_exts2 = ImplicitExts1ToExts2; static constexpr bool implicit_exts2_to_exts1 = ImplicitExts2ToExts1; // Idx starts at rank() - template + template struct make_extents; // Construct all extents - doesn't matter if idx is static or not - template - struct make_extents - { - template - static Exts construct(SizeTypes...sizes) { - return make_extents::construct(Idx*5, sizes...); + template + struct make_extents { + template + static Exts construct(SizeTypes... sizes) { + return make_extents::construct(Idx * 5, + sizes...); } }; - // Construct dynamic extents - opnly add a parameter if the current index is not static - template - struct make_extents - { - template - static Exts construct(SizeTypes...sizes) { - return make_extents1?Exts::static_extent(Idx-2)!=Kokkos::dynamic_extent:true)>::construct(Idx*5, sizes...); + // Construct dynamic extents - opnly add a parameter if the current index is + // not static + template + struct make_extents { + template + static Exts construct(SizeTypes... sizes) { + return make_extents 1 ? Exts::static_extent(Idx - 2) != + Kokkos::dynamic_extent + : true)>::construct(Idx * 5, sizes...); } }; - template - struct make_extents - { - template - static Exts construct(SizeTypes...sizes) { - return make_extents1?Exts::static_extent(Idx-2)!=Kokkos::dynamic_extent:true)>::construct(sizes...); + template + struct make_extents { + template + static Exts construct(SizeTypes... sizes) { + return make_extents 1 ? Exts::static_extent(Idx - 2) != + Kokkos::dynamic_extent + : true)>::construct(sizes...); } }; // End case - template - struct make_extents { - template - static Exts construct(SizeTypes...sizes) { - return Exts{sizes...}; + template + struct make_extents { + template + static Exts construct(SizeTypes... sizes) { + return Exts{sizes...}; } }; - template - struct make_extents { - template - static Exts construct(SizeTypes...sizes) { - return Exts{sizes...}; + template + struct make_extents { + template + static Exts construct(SizeTypes... sizes) { + return Exts{sizes...}; } }; }; -using compatible_extents_test_types = - ::testing::Types< - std::tuple, sizes<5>, exts<5>, sizes<>, BoolPairDeducer>, - std::tuple, sizes<>, exts, sizes<5>, BoolPairDeducer>, +using compatible_extents_test_types = ::testing::Types< + std::tuple, sizes<5>, exts<5>, sizes<>, + BoolPairDeducer>, + std::tuple, sizes<>, exts, sizes<5>, + BoolPairDeducer>, //-------------------- - std::tuple, sizes<5>, exts<5, Kokkos::dynamic_extent>, sizes<10>, BoolPairDeducer>, - std::tuple, sizes<5, 10>, exts<5, Kokkos::dynamic_extent>, sizes<10>, BoolPairDeducer>, - std::tuple, sizes<5, 10>, exts, sizes<5>, BoolPairDeducer>, - std::tuple, sizes<5, 10>, exts<5, 10>, sizes<>, BoolPairDeducer>, - std::tuple, sizes<>, exts<5, Kokkos::dynamic_extent>, sizes<10>, BoolPairDeducer>, - std::tuple, sizes<>, exts, sizes<5>, BoolPairDeducer>, + std::tuple, sizes<5>, + exts<5, Kokkos::dynamic_extent>, sizes<10>, + BoolPairDeducer>, + std::tuple, + sizes<5, 10>, exts<5, Kokkos::dynamic_extent>, sizes<10>, + BoolPairDeducer>, + std::tuple, + sizes<5, 10>, exts, sizes<5>, + BoolPairDeducer>, + std::tuple, + sizes<5, 10>, exts<5, 10>, sizes<>, + BoolPairDeducer>, + std::tuple, sizes<>, exts<5, Kokkos::dynamic_extent>, sizes<10>, + BoolPairDeducer>, + std::tuple, sizes<>, exts, sizes<5>, + BoolPairDeducer>, //-------------------- - std::tuple, sizes<5, 10>, exts<5, Kokkos::dynamic_extent, 15>, sizes<10>, BoolPairDeducer>, - std::tuple, sizes<>, exts<5, Kokkos::dynamic_extent, 15>, sizes<10>, BoolPairDeducer>, - std::tuple, sizes<>, exts, sizes<5, 10, 15>, BoolPairDeducer> - >; + std::tuple, + sizes<5, 10>, exts<5, Kokkos::dynamic_extent, 15>, sizes<10>, + BoolPairDeducer>, + std::tuple, sizes<>, exts<5, Kokkos::dynamic_extent, 15>, + sizes<10>, BoolPairDeducer>, + std::tuple, sizes<>, + exts, + sizes<5, 10, 15>, BoolPairDeducer>>; TYPED_TEST_SUITE(TestExtentsCompatCtors, compatible_extents_test_types); @@ -261,8 +280,8 @@ TYPED_TEST(TestExtentsCompatCtors, compatible_construct_2) { TYPED_TEST(TestExtentsCompatCtors, compatible_assign_1) { #if MDSPAN_HAS_CXX_17 - if constexpr(std::is_convertible_v) { + if constexpr (std::is_convertible_v) { this->exts1 = this->exts2; } else { this->exts1 = typename TestFixture::extents_type1(this->exts2); @@ -271,13 +290,12 @@ TYPED_TEST(TestExtentsCompatCtors, compatible_assign_1) { this->exts1 = typename TestFixture::extents_type1(this->exts2); #endif EXPECT_EQ(this->exts1, this->exts2); - } TYPED_TEST(TestExtentsCompatCtors, compatible_assign_2) { #if MDSPAN_HAS_CXX_17 - if constexpr(std::is_convertible_v) { + if constexpr (std::is_convertible_v) { this->exts2 = this->exts1; } else { this->exts2 = typename TestFixture::extents_type2(this->exts1); @@ -288,51 +306,48 @@ TYPED_TEST(TestExtentsCompatCtors, compatible_assign_2) { EXPECT_EQ(this->exts1, this->exts2); } - -template +template struct ImplicitConversionToExts; -template -struct ImplicitConversionToExts { - static bool convert(Extents) { - return true; - } +template +struct ImplicitConversionToExts { + static bool convert(Extents) { return true; } }; -template -struct ImplicitConversionToExts { - template - static bool convert(E) { +template +struct ImplicitConversionToExts { + template + static bool convert(E) { return false; } }; - #if MDSPAN_HAS_CXX_20 TYPED_TEST(TestExtentsCompatCtors, implicit_construct_1) { bool exts1_convertible_exts2 = - std::is_convertible::value; + std::is_convertible::value; bool exts2_convertible_exts1 = - std::is_convertible::value; + std::is_convertible::value; bool exts1_implicit_exts2 = ImplicitConversionToExts< - typename TestFixture::extents_type2, - TestFixture::implicit_exts1_to_exts2>::convert(this->exts1); + typename TestFixture::extents_type2, + TestFixture::implicit_exts1_to_exts2>::convert(this->exts1); bool exts2_implicit_exts1 = ImplicitConversionToExts< - typename TestFixture::extents_type1, - TestFixture::implicit_exts2_to_exts1>::convert(this->exts2); + typename TestFixture::extents_type1, + TestFixture::implicit_exts2_to_exts1>::convert(this->exts2); - EXPECT_EQ(exts1_convertible_exts2,exts1_implicit_exts2); - EXPECT_EQ(exts2_convertible_exts1,exts2_implicit_exts1); - EXPECT_EQ(exts1_convertible_exts2,TestFixture::implicit_exts1_to_exts2); - EXPECT_EQ(exts2_convertible_exts1,TestFixture::implicit_exts2_to_exts1); + EXPECT_EQ(exts1_convertible_exts2, exts1_implicit_exts2); + EXPECT_EQ(exts2_convertible_exts1, exts2_implicit_exts1); + EXPECT_EQ(exts1_convertible_exts2, TestFixture::implicit_exts1_to_exts2); + EXPECT_EQ(exts2_convertible_exts1, TestFixture::implicit_exts2_to_exts1); } #endif -TEST(TestExtentsCtorStdArrayConvertibleToSizeT, test_extents_ctor_std_array_convertible_to_size_t) { +TEST(TestExtentsCtorStdArrayConvertibleToSizeT, + test_extents_ctor_std_array_convertible_to_size_t) { std::array i{2, 2}; - Kokkos::dextents e{i}; + Kokkos::dextents e{i}; ASSERT_EQ(e.rank(), 2); ASSERT_EQ(e.rank_dynamic(), 2); ASSERT_EQ(e.extent(0), 2); @@ -340,10 +355,11 @@ TEST(TestExtentsCtorStdArrayConvertibleToSizeT, test_extents_ctor_std_array_conv } #ifdef __cpp_lib_span -TEST(TestExtentsCtorStdArrayConvertibleToSizeT, test_extents_ctor_std_span_convertible_to_size_t) { +TEST(TestExtentsCtorStdArrayConvertibleToSizeT, + test_extents_ctor_std_span_convertible_to_size_t) { std::array i{2, 2}; - std::span s(i.data(),2); - Kokkos::dextents e{s}; + std::span s(i.data(), 2); + Kokkos::dextents e{s}; ASSERT_EQ(e.rank(), 2); ASSERT_EQ(e.rank_dynamic(), 2); ASSERT_EQ(e.extent(0), 2); @@ -353,28 +369,34 @@ TEST(TestExtentsCtorStdArrayConvertibleToSizeT, test_extents_ctor_std_span_conve TYPED_TEST(TestExtentsCompatCtors, construct_from_dynamic_sizes) { using e1_t = typename TestFixture::extents_type1; - constexpr bool e1_last_ext_static = e1_t::rank()>0?e1_t::static_extent(e1_t::rank()-1)!=Kokkos::dynamic_extent:true; - e1_t e1 = TestFixture::template make_extents::construct(); - for(size_t r=0; r 0 + ? e1_t::static_extent(e1_t::rank() - 1) != Kokkos::dynamic_extent + : true; + e1_t e1 = TestFixture::template make_extents::construct(); + for (size_t r = 0; r < e1.rank(); r++) ASSERT_EQ(e1.extent(r), (r + 1) * 5); using e2_t = typename TestFixture::extents_type2; - constexpr bool e2_last_ext_static = e2_t::rank()>0?e2_t::static_extent(e2_t::rank()-1)!=Kokkos::dynamic_extent:true; - e2_t e2 = TestFixture::template make_extents::construct(); - for(size_t r=0; r 0 + ? e2_t::static_extent(e2_t::rank() - 1) != Kokkos::dynamic_extent + : true; + e2_t e2 = TestFixture::template make_extents::construct(); + for (size_t r = 0; r < e2.rank(); r++) ASSERT_EQ(e2.extent(r), (r + 1) * 5); } TYPED_TEST(TestExtentsCompatCtors, construct_from_all_sizes) { using e1_t = typename TestFixture::extents_type1; - e1_t e1 = TestFixture::template make_extents::construct(); - for(size_t r=0; r::construct(); + for (size_t r = 0; r < e1.rank(); r++) ASSERT_EQ(e1.extent(r), (r + 1) * 5); using e2_t = typename TestFixture::extents_type2; - e2_t e2 = TestFixture::template make_extents::construct(); - for(size_t r=0; r::construct(); + for (size_t r = 0; r < e2.rank(); r++) ASSERT_EQ(e2.extent(r), (r + 1) * 5); } TYPED_TEST(TestExtentsCompatCtors, construct_from_dynamic_array) { @@ -382,47 +404,45 @@ TYPED_TEST(TestExtentsCompatCtors, construct_from_dynamic_array) { std::array ext1_array_dynamic; int dyn_idx = 0; - for(size_t r=0; r((r+1)*5); + for (size_t r = 0; r < e1_t::rank(); r++) { + if (e1_t::static_extent(r) == Kokkos::dynamic_extent) { + ext1_array_dynamic[dyn_idx] = static_cast((r + 1) * 5); dyn_idx++; } } e1_t e1(ext1_array_dynamic); - for(size_t r=0; r ext2_array_dynamic; dyn_idx = 0; - for(size_t r=0; r((r+1)*5); + for (size_t r = 0; r < e2_t::rank(); r++) { + if (e2_t::static_extent(r) == Kokkos::dynamic_extent) { + ext2_array_dynamic[dyn_idx] = static_cast((r + 1) * 5); dyn_idx++; } } e2_t e2(ext2_array_dynamic); - for(size_t r=0; r ext1_array_all; - for(size_t r=0; r((r+1)*5); + for (size_t r = 0; r < e1_t::rank(); r++) + ext1_array_all[r] = static_cast((r + 1) * 5); e1_t e1(ext1_array_all); - for(size_t r=0; r ext2_array_all; - for(size_t r=0; r((r+1)*5); + for (size_t r = 0; r < e2_t::rank(); r++) + ext2_array_all[r] = static_cast((r + 1) * 5); e2_t e2(ext2_array_all); - for(size_t r=0; r struct TestLayoutCtors; +template +struct TestLayoutCtors; template -struct TestLayoutCtors ->> : public ::testing::Test { +struct TestLayoutCtors< + std::tuple>> + : public ::testing::Test { using mapping_type = Mapping; using extents_type = typename mapping_type::extents_type; - Mapping map = { extents_type{ DynamicSizes... } }; + Mapping map = {extents_type{DynamicSizes...}}; }; template -using test_left_type = std::tuple< - typename Kokkos::layout_left::template mapping, - std::integer_sequence ->; +using test_left_type = + std::tuple, + std::integer_sequence>; template -using test_right_type = std::tuple< - typename Kokkos::layout_right::template mapping, - std::integer_sequence ->; +using test_right_type = + std::tuple, + std::integer_sequence>; using layout_test_types = - ::testing::Types< - test_left_type>, - test_right_type>, - //---------- - test_left_type, 10>, - test_right_type, 10>, - //---------- - test_left_type, 5>, - test_left_type, 10>, - test_left_type>, - test_right_type, 5>, - test_right_type, 10>, - test_right_type> - >; + ::testing::Types>, + test_right_type>, + //---------- + test_left_type, 10>, + test_right_type, 10>, + //---------- + test_left_type, 5>, + test_left_type, 10>, + test_left_type>, + test_right_type, 5>, + test_right_type, 10>, + test_right_type>>; TYPED_TEST_SUITE(TestLayoutCtors, layout_test_types); @@ -70,40 +66,39 @@ TYPED_TEST(TestLayoutCtors, default_ctor) { ASSERT_FALSE(m != m2); } -template struct TestLayoutCompatCtors; -template -struct TestLayoutCompatCtors, - Mapping2, - std::integer_sequence ->> : public ::testing::Test { +template +struct TestLayoutCompatCtors; +template +struct TestLayoutCompatCtors< + std::tuple, + Mapping2, std::integer_sequence>> + : public ::testing::Test { using mapping_type1 = Mapping; using mapping_type2 = Mapping2; - using extents_type1 = std::remove_reference_t().extents())>; - using extents_type2 = std::remove_reference_t().extents())>; - Mapping map1 = { extents_type1{ DynamicSizes... } }; - Mapping2 map2 = { extents_type2{ DynamicSizes2... } }; + using extents_type1 = std::remove_reference_t< + decltype(std::declval().extents())>; + using extents_type2 = std::remove_reference_t< + decltype(std::declval().extents())>; + Mapping map1 = {extents_type1{DynamicSizes...}}; + Mapping2 map2 = {extents_type2{DynamicSizes2...}}; }; template -using test_left_type_compatible = std::tuple< - typename Kokkos::layout_left::template mapping, S1, - typename Kokkos::layout_left::template mapping, S2 ->; +using test_left_type_compatible = + std::tuple, S1, + typename Kokkos::layout_left::template mapping, S2>; template -using test_right_type_compatible = std::tuple< - typename Kokkos::layout_right::template mapping, S1, - typename Kokkos::layout_right::template mapping, S2 ->; +using test_right_type_compatible = + std::tuple, S1, + typename Kokkos::layout_right::template mapping, S2>; template using sizes = std::integer_sequence; template -using exts = Kokkos::extents; +using exts = Kokkos::extents; template