1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11// <mdspan>
12
13// template<class OtherExtents>
14// constexpr explicit(extents_type::rank() > 0)
15// mapping(const layout_stride::mapping<OtherExtents>& other);
16//
17// Constraints: is_constructible_v<extents_type, OtherExtents> is true.
18//
19// Preconditions:
20// - If extents_type::rank() > 0 is true, then for all r in the range [0, extents_type::rank()),
21// other.stride(r) equals other.extents().fwd-prod-of-extents(r), and
22// - other.required_span_size() is representable as a value of type index_type ([basic.fundamental]).
23//
24// Effects: Direct-non-list-initializes extents_ with other.extents().
25
26#include <array>
27#include <cassert>
28#include <cstddef>
29#include <mdspan>
30#include <type_traits>
31
32#include "test_macros.h"
33
34template <bool implicit, class ToE, class FromE>
35constexpr void test_conversion(FromE src_exts) {
36 using To = std::layout_left::mapping<ToE>;
37 using From = std::layout_stride::mapping<FromE>;
38 std::array<typename FromE::index_type, FromE::rank()> strides;
39 if constexpr (FromE::rank() > 0) {
40 strides[0] = 1;
41 for (size_t r = 1; r < FromE::rank(); r++)
42 strides[r] = src_exts.extent(r - 1) * strides[r - 1];
43 }
44 From src(src_exts, strides);
45
46 ASSERT_NOEXCEPT(To(src));
47 To dest(src);
48 assert(dest == src);
49
50 if constexpr (implicit) {
51 To dest_implicit = src;
52 assert(dest_implicit == src);
53 } else {
54 assert((!std::is_convertible_v<From, To>));
55 }
56}
57
58template <class T1, class T2>
59constexpr void test_conversion() {
60 constexpr size_t D = std::dynamic_extent;
61
62 // clang-format off
63 test_conversion<true, std::extents<T1>>(std::extents<T2>());
64 test_conversion<false, std::extents<T1, D>>(std::extents<T2, D>(5));
65 test_conversion<false, std::extents<T1, 5>>(std::extents<T2, D>(5));
66 test_conversion<false, std::extents<T1, 5>>(std::extents<T2, 5>());
67 test_conversion<false, std::extents<T1, 5, D>>(std::extents<T2, D, D>(5, 5));
68 test_conversion<false, std::extents<T1, D, D>>(std::extents<T2, D, D>(5, 5));
69 test_conversion<false, std::extents<T1, D, D>>(std::extents<T2, D, 7>(5));
70 test_conversion<false, std::extents<T1, 5, 7>>(std::extents<T2, 5, 7>());
71 test_conversion<false, std::extents<T1, 5, D, 8, D, D>>(std::extents<T2, D, D, 8, 9, 1>(5, 7));
72 test_conversion<false, std::extents<T1, D, D, D, D, D>>(
73 std::extents<T2, D, D, D, D, D>(5, 7, 8, 9, 1));
74 test_conversion<false, std::extents<T1, D, D, 8, 9, D>>(std::extents<T2, D, 7, 8, 9, 1>(5));
75 test_conversion<false, std::extents<T1, 5, 7, 8, 9, 1>>(std::extents<T2, 5, 7, 8, 9, 1>());
76 // clang-format on
77}
78
79template <class IdxT, size_t... Extents>
80using lr_mapping_t = std::layout_right::mapping<std::extents<IdxT, Extents...>>;
81template <class IdxT, size_t... Extents>
82using ls_mapping_t = std::layout_stride::mapping<std::extents<IdxT, Extents...>>;
83
84constexpr void test_rank_mismatch() {
85 constexpr size_t D = std::dynamic_extent;
86
87 static_assert(!std::is_constructible_v<lr_mapping_t<int, D>, ls_mapping_t<int>>);
88 static_assert(!std::is_constructible_v<lr_mapping_t<int>, ls_mapping_t<int, D, D>>);
89 static_assert(!std::is_constructible_v<lr_mapping_t<int, D>, ls_mapping_t<int, D, D>>);
90 static_assert(!std::is_constructible_v<lr_mapping_t<int, D, D, D>, ls_mapping_t<int, D, D>>);
91}
92
93constexpr void test_static_extent_mismatch() {
94 constexpr size_t D = std::dynamic_extent;
95
96 static_assert(!std::is_constructible_v<lr_mapping_t<int, D, 5>, ls_mapping_t<int, D, 4>>);
97 static_assert(!std::is_constructible_v<lr_mapping_t<int, 5>, ls_mapping_t<int, 4>>);
98 static_assert(!std::is_constructible_v<lr_mapping_t<int, 5, D>, ls_mapping_t<int, 4, D>>);
99}
100
101constexpr bool test() {
102 test_conversion<int, int>();
103 test_conversion<int, size_t>();
104 test_conversion<size_t, int>();
105 test_conversion<size_t, long>();
106 test_rank_mismatch();
107 test_static_extent_mismatch();
108 return true;
109}
110
111int main(int, char**) {
112 test();
113 static_assert(test());
114 return 0;
115}
116

source code of libcxx/test/std/containers/views/mdspan/layout_right/ctor.layout_stride.pass.cpp