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 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 9 10 // <mdspan> 11 12 #include <array> 13 #include <cassert> 14 #include <cstddef> 15 #include <mdspan> 16 #include <span> 17 18 #include "../ConvertibleToIntegral.h" 19 #include "test_macros.h" 20 21 // Helper file to implement combinatorial testing of extents constructor 22 // 23 // std::extents can be constructed from just indices, a std::array, or a std::span 24 // In each of those cases one can either provide all extents, or just the dynamic ones 25 // If constructed from std::span, the span needs to have a static extent 26 // Furthermore, the indices/array/span can have integer types other than index_type 27 28 template <class E, class AllExtents> 29 constexpr void test_runtime_observers(E ext, AllExtents expected) { 30 for (typename E::rank_type r = 0; r < ext.rank(); r++) { 31 ASSERT_SAME_TYPE(decltype(ext.extent(0)), typename E::index_type); 32 ASSERT_NOEXCEPT(ext.extent(0)); 33 assert(ext.extent(r) == static_cast<typename E::index_type>(expected[r])); 34 } 35 } 36 37 template <class E, class AllExtents> 38 constexpr void test_implicit_construction_call(E e, AllExtents all_ext) { 39 test_runtime_observers(e, all_ext); 40 } 41 42 template <class E, class Test, class AllExtents> 43 constexpr void test_construction(AllExtents all_ext) { 44 // test construction from all extents 45 Test::template test_construction<E>(all_ext, all_ext, std::make_index_sequence<E::rank()>()); 46 47 // test construction from just dynamic extents 48 // create an array of just the extents corresponding to dynamic values 49 std::array<typename AllExtents::value_type, E::rank_dynamic()> dyn_ext{}; 50 size_t dynamic_idx = 0; 51 for (size_t r = 0; r < E::rank(); r++) { 52 if (E::static_extent(r) == std::dynamic_extent) { 53 dyn_ext[dynamic_idx] = all_ext[r]; 54 dynamic_idx++; 55 } 56 } 57 Test::template test_construction<E>(all_ext, dyn_ext, std::make_index_sequence<E::rank_dynamic()>()); 58 } 59 60 template <class T, class TArg, class Test> 61 constexpr void test() { 62 constexpr size_t D = std::dynamic_extent; 63 64 test_construction<std::extents<T>, Test>(std::array<TArg, 0>{}); 65 66 test_construction<std::extents<T, 3>, Test>(std::array<TArg, 1>{3}); 67 test_construction<std::extents<T, D>, Test>(std::array<TArg, 1>{3}); 68 69 test_construction<std::extents<T, 3, 7>, Test>(std::array<TArg, 2>{3, 7}); 70 test_construction<std::extents<T, 3, D>, Test>(std::array<TArg, 2>{3, 7}); 71 test_construction<std::extents<T, D, 7>, Test>(std::array<TArg, 2>{3, 7}); 72 test_construction<std::extents<T, D, D>, Test>(std::array<TArg, 2>{3, 7}); 73 74 test_construction<std::extents<T, 3, 7, 9>, Test>(std::array<TArg, 3>{3, 7, 9}); 75 test_construction<std::extents<T, 3, 7, D>, Test>(std::array<TArg, 3>{3, 7, 9}); 76 test_construction<std::extents<T, 3, D, D>, Test>(std::array<TArg, 3>{3, 7, 9}); 77 test_construction<std::extents<T, D, 7, D>, Test>(std::array<TArg, 3>{3, 7, 9}); 78 test_construction<std::extents<T, D, D, D>, Test>(std::array<TArg, 3>{3, 7, 9}); 79 test_construction<std::extents<T, 3, D, 9>, Test>(std::array<TArg, 3>{3, 7, 9}); 80 test_construction<std::extents<T, D, D, 9>, Test>(std::array<TArg, 3>{3, 7, 9}); 81 test_construction<std::extents<T, D, 7, 9>, Test>(std::array<TArg, 3>{3, 7, 9}); 82 83 test_construction<std::extents<T, 1, 2, 3, 4, 5, 6, 7, 8, 9>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9}); 84 test_construction<std::extents<T, D, 2, 3, D, 5, D, 7, D, 9>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9}); 85 test_construction<std::extents<T, D, D, D, D, D, D, D, D, D>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9}); 86 } 87 88 template <class Test> 89 constexpr bool test_index_type_combo() { 90 test<int, int, Test>(); 91 test<int, size_t, Test>(); 92 test<unsigned, int, Test>(); 93 test<signed char, size_t, Test>(); 94 test<long long, unsigned, Test>(); 95 test<size_t, int, Test>(); 96 test<size_t, size_t, Test>(); 97 test<int, IntType, Test>(); 98 test<signed char, IntType, Test>(); 99 return true; 100 } 101