1639a0986SChristian Trott //===----------------------------------------------------------------------===// 2639a0986SChristian Trott // 3639a0986SChristian Trott // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4639a0986SChristian Trott // See https://llvm.org/LICENSE.txt for license information. 5639a0986SChristian Trott // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6639a0986SChristian Trott // 7639a0986SChristian Trott //===----------------------------------------------------------------------===// 8639a0986SChristian Trott 9639a0986SChristian Trott // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 10639a0986SChristian Trott 11639a0986SChristian Trott // <mdspan> 12639a0986SChristian Trott 13639a0986SChristian Trott // A type M meets the layout mapping requirements if 14639a0986SChristian Trott // - M models copyable and equality_comparable, 15639a0986SChristian Trott // - is_nothrow_move_constructible_v<M> is true, 16639a0986SChristian Trott // - is_nothrow_move_assignable_v<M> is true, 17639a0986SChristian Trott // - is_nothrow_swappable_v<M> is true, and 18639a0986SChristian Trott // 19639a0986SChristian Trott // the following types and expressions are well-formed and have the specified semantics. 20639a0986SChristian Trott // 21639a0986SChristian Trott // typename M::extents_type 22639a0986SChristian Trott // Result: A type that is a specialization of extents. 23639a0986SChristian Trott // 24639a0986SChristian Trott // typename M::index_type 25639a0986SChristian Trott // Result: typename M::extents_type::index_type. 26639a0986SChristian Trott // 27639a0986SChristian Trott // typename M::rank_type 28639a0986SChristian Trott // Result: typename M::extents_type::rank_type. 29639a0986SChristian Trott // 30639a0986SChristian Trott // typename M::layout_type 31639a0986SChristian Trott // Result: A type MP that meets the layout mapping policy requirements ([mdspan.layout.policy.reqmts]) and for which is-mapping-of<MP, M> is true. 32639a0986SChristian Trott // 33639a0986SChristian Trott // m.extents() 34639a0986SChristian Trott // Result: const typename M::extents_type& 35639a0986SChristian Trott // 36639a0986SChristian Trott // m(i...) 37639a0986SChristian Trott // Result: typename M::index_type 38639a0986SChristian Trott // Returns: A nonnegative integer less than numeric_limits<typename M::index_type>::max() and less than or equal to numeric_limits<size_t>::max(). 39639a0986SChristian Trott // 40639a0986SChristian Trott // m(i...) == m(static_cast<typename M::index_type>(i)...) 41639a0986SChristian Trott // Result: bool 42639a0986SChristian Trott // Returns: true 43639a0986SChristian Trott // 44639a0986SChristian Trott // m.required_span_size() 45639a0986SChristian Trott // Result: typename M::index_type 46639a0986SChristian Trott // 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. 47639a0986SChristian Trott // 48639a0986SChristian Trott // m.is_unique() 49639a0986SChristian Trott // Result: bool 50639a0986SChristian Trott // Returns: true only if for every i and j where (i != j || ...) is true, m(i...) != m(j...) is true. 51639a0986SChristian Trott // 52639a0986SChristian Trott // m.is_exhaustive() 53639a0986SChristian Trott // Result: bool 54639a0986SChristian Trott // 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. 55639a0986SChristian Trott // 56639a0986SChristian Trott // m.is_strided() 57639a0986SChristian Trott // Result: bool 58639a0986SChristian Trott // Returns: true only if for every rank index r of m.extents() there exists an integer 59639a0986SChristian Trott // sr such that, for all i where (i+dr) is a multidimensional index in m.extents() ([mdspan.overview]), 60639a0986SChristian Trott // m((i + dr)...) - m(i...) equals sr 61639a0986SChristian Trott // 62639a0986SChristian Trott // m.stride(r) 63639a0986SChristian Trott // Preconditions: m.is_strided() is true. 64639a0986SChristian Trott // Result: typename M::index_type 65639a0986SChristian Trott // Returns: sr as defined in m.is_strided() above. 66639a0986SChristian Trott // 67639a0986SChristian Trott // M::is_always_unique() 68639a0986SChristian Trott // Result: A constant expression ([expr.const]) of type bool. 69639a0986SChristian Trott // Returns: true only if m.is_unique() is true for all possible objects m of type M. 70639a0986SChristian Trott // 71639a0986SChristian Trott // M::is_always_exhaustive() 72639a0986SChristian Trott // Result: A constant expression ([expr.const]) of type bool. 73639a0986SChristian Trott // Returns: true only if m.is_exhaustive() is true for all possible objects m of type M. 74639a0986SChristian Trott // 75639a0986SChristian Trott // M::is_always_strided() 76639a0986SChristian Trott // Result: A constant expression ([expr.const]) of type bool. 77639a0986SChristian Trott // Returns: true only if m.is_strided() is true for all possible objects m of type M. 78639a0986SChristian Trott 79639a0986SChristian Trott #include <cassert> 80*e99c4906SNikolas Klauser #include <cstddef> 81*e99c4906SNikolas Klauser #include <mdspan> 825e19fd17SLouis Dionne #include <span> // dynamic_extent 835e19fd17SLouis Dionne #include <type_traits> 845e19fd17SLouis Dionne #include <utility> 85639a0986SChristian Trott 86639a0986SChristian Trott #include "test_macros.h" 87639a0986SChristian Trott 88639a0986SChristian Trott // Common requirements of all layout mappings 89639a0986SChristian Trott template <class M, size_t... Idxs> 90639a0986SChristian Trott void test_mapping_requirements(std::index_sequence<Idxs...>) { 91639a0986SChristian Trott using E = typename M::extents_type; 92b84cb9c2SStephan T. Lavavej LIBCPP_STATIC_ASSERT(std::__mdspan_detail::__is_extents_v<E>); 93639a0986SChristian Trott static_assert(std::is_copy_constructible_v<M>); 94639a0986SChristian Trott static_assert(std::is_nothrow_move_constructible_v<M>); 95639a0986SChristian Trott static_assert(std::is_nothrow_move_assignable_v<M>); 96639a0986SChristian Trott static_assert(std::is_nothrow_swappable_v<M>); 97639a0986SChristian Trott ASSERT_SAME_TYPE(typename M::index_type, typename E::index_type); 98639a0986SChristian Trott ASSERT_SAME_TYPE(typename M::size_type, typename E::size_type); 99639a0986SChristian Trott ASSERT_SAME_TYPE(typename M::rank_type, typename E::rank_type); 100639a0986SChristian Trott ASSERT_SAME_TYPE(typename M::layout_type, std::layout_stride); 101639a0986SChristian Trott ASSERT_SAME_TYPE(typename M::layout_type::template mapping<E>, M); 102639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().extents()), const E&>); 103639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().strides()), std::array<typename M::index_type, E::rank()>>); 104639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>()(Idxs...)), typename M::index_type>); 105639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().required_span_size()), typename M::index_type>); 106639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().is_unique()), bool>); 107639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().is_exhaustive()), bool>); 108639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().is_strided()), bool>); 109639a0986SChristian Trott static_assert(std::is_same_v<decltype(std::declval<M>().stride(0)), typename M::index_type>); 110639a0986SChristian Trott static_assert(std::is_same_v<decltype(M::is_always_unique()), bool>); 111639a0986SChristian Trott static_assert(std::is_same_v<decltype(M::is_always_exhaustive()), bool>); 112639a0986SChristian Trott static_assert(std::is_same_v<decltype(M::is_always_strided()), bool>); 113639a0986SChristian Trott } 114639a0986SChristian Trott 115639a0986SChristian Trott template <class L, class E> 116639a0986SChristian Trott void test_layout_mapping_requirements() { 117639a0986SChristian Trott using M = typename L::template mapping<E>; 118639a0986SChristian Trott test_mapping_requirements<M>(std::make_index_sequence<E::rank()>()); 119639a0986SChristian Trott } 120639a0986SChristian Trott 121639a0986SChristian Trott template <class E> 122639a0986SChristian Trott void test_layout_mapping_stride() { 123639a0986SChristian Trott test_layout_mapping_requirements<std::layout_stride, E>(); 124639a0986SChristian Trott } 125639a0986SChristian Trott 126639a0986SChristian Trott int main(int, char**) { 127639a0986SChristian Trott constexpr size_t D = std::dynamic_extent; 128639a0986SChristian Trott test_layout_mapping_stride<std::extents<int>>(); 129ab562686SStephan T. Lavavej test_layout_mapping_stride<std::extents<signed char, 4, 5>>(); 130639a0986SChristian Trott test_layout_mapping_stride<std::extents<unsigned, D, 4>>(); 131639a0986SChristian Trott test_layout_mapping_stride<std::extents<size_t, D, D, D, D>>(); 132639a0986SChristian Trott return 0; 133639a0986SChristian Trott } 134