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 <span> // dynamic_extent 31 #include <type_traits> 32 33 #include "test_macros.h" 34 35 template <bool implicit, class ToE, class FromE> 36 constexpr void test_conversion(FromE src_exts) { 37 using To = std::layout_left::mapping<ToE>; 38 using From = std::layout_stride::mapping<FromE>; 39 std::array<typename FromE::index_type, FromE::rank()> strides; 40 if constexpr (FromE::rank() > 0) { 41 strides[0] = 1; 42 for (size_t r = 1; r < FromE::rank(); r++) 43 strides[r] = src_exts.extent(r - 1) * strides[r - 1]; 44 } 45 From src(src_exts, strides); 46 47 ASSERT_NOEXCEPT(To(src)); 48 To dest(src); 49 assert(dest == src); 50 51 if constexpr (implicit) { 52 To dest_implicit = src; 53 assert(dest_implicit == src); 54 } else { 55 assert((!std::is_convertible_v<From, To>)); 56 } 57 } 58 59 template <class T1, class T2> 60 constexpr void test_conversion() { 61 constexpr size_t D = std::dynamic_extent; 62 63 // clang-format off 64 test_conversion<true, std::extents<T1>>(std::extents<T2>()); 65 test_conversion<false, std::extents<T1, D>>(std::extents<T2, D>(5)); 66 test_conversion<false, std::extents<T1, 5>>(std::extents<T2, D>(5)); 67 test_conversion<false, std::extents<T1, 5>>(std::extents<T2, 5>()); 68 test_conversion<false, std::extents<T1, 5, D>>(std::extents<T2, D, D>(5, 5)); 69 test_conversion<false, std::extents<T1, D, D>>(std::extents<T2, D, D>(5, 5)); 70 test_conversion<false, std::extents<T1, D, D>>(std::extents<T2, D, 7>(5)); 71 test_conversion<false, std::extents<T1, 5, 7>>(std::extents<T2, 5, 7>()); 72 test_conversion<false, std::extents<T1, 5, D, 8, D, D>>(std::extents<T2, D, D, 8, 9, 1>(5, 7)); 73 test_conversion<false, std::extents<T1, D, D, D, D, D>>( 74 std::extents<T2, D, D, D, D, D>(5, 7, 8, 9, 1)); 75 test_conversion<false, std::extents<T1, D, D, 8, 9, D>>(std::extents<T2, D, 7, 8, 9, 1>(5)); 76 test_conversion<false, std::extents<T1, 5, 7, 8, 9, 1>>(std::extents<T2, 5, 7, 8, 9, 1>()); 77 // clang-format on 78 } 79 80 template <class IdxT, size_t... Extents> 81 using lr_mapping_t = std::layout_right::mapping<std::extents<IdxT, Extents...>>; 82 template <class IdxT, size_t... Extents> 83 using ls_mapping_t = std::layout_stride::mapping<std::extents<IdxT, Extents...>>; 84 85 constexpr void test_rank_mismatch() { 86 constexpr size_t D = std::dynamic_extent; 87 88 static_assert(!std::is_constructible_v<lr_mapping_t<int, D>, ls_mapping_t<int>>); 89 static_assert(!std::is_constructible_v<lr_mapping_t<int>, ls_mapping_t<int, D, D>>); 90 static_assert(!std::is_constructible_v<lr_mapping_t<int, D>, ls_mapping_t<int, D, D>>); 91 static_assert(!std::is_constructible_v<lr_mapping_t<int, D, D, D>, ls_mapping_t<int, D, D>>); 92 } 93 94 constexpr void test_static_extent_mismatch() { 95 constexpr size_t D = std::dynamic_extent; 96 97 static_assert(!std::is_constructible_v<lr_mapping_t<int, D, 5>, ls_mapping_t<int, D, 4>>); 98 static_assert(!std::is_constructible_v<lr_mapping_t<int, 5>, ls_mapping_t<int, 4>>); 99 static_assert(!std::is_constructible_v<lr_mapping_t<int, 5, D>, ls_mapping_t<int, 4, D>>); 100 } 101 102 constexpr bool test() { 103 test_conversion<int, int>(); 104 test_conversion<int, size_t>(); 105 test_conversion<size_t, int>(); 106 test_conversion<size_t, long>(); 107 test_rank_mismatch(); 108 test_static_extent_mismatch(); 109 return true; 110 } 111 112 int main(int, char**) { 113 test(); 114 static_assert(test()); 115 return 0; 116 } 117