xref: /llvm-project/libcxx/test/std/containers/views/mdspan/layout_right/static_requirements.pass.cpp (revision e99c4906e44ae3f921fa05356909d006cda8d954)
1cfa096d9SChristian Trott //===----------------------------------------------------------------------===//
2cfa096d9SChristian Trott //
3cfa096d9SChristian Trott // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cfa096d9SChristian Trott // See https://llvm.org/LICENSE.txt for license information.
5cfa096d9SChristian Trott // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cfa096d9SChristian Trott //
7cfa096d9SChristian Trott //===----------------------------------------------------------------------===//
8cfa096d9SChristian Trott 
9cfa096d9SChristian Trott // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10cfa096d9SChristian Trott 
11cfa096d9SChristian Trott // <mdspan>
12cfa096d9SChristian Trott 
13cfa096d9SChristian Trott // A type M meets the layout mapping requirements if
14cfa096d9SChristian Trott //    - M models copyable and equality_comparable,
15cfa096d9SChristian Trott //    - is_nothrow_move_constructible_v<M> is true,
16cfa096d9SChristian Trott //    - is_nothrow_move_assignable_v<M> is true,
17cfa096d9SChristian Trott //    - is_nothrow_swappable_v<M> is true, and
18cfa096d9SChristian Trott //
19cfa096d9SChristian Trott // the following types and expressions are well-formed and have the specified semantics.
20cfa096d9SChristian Trott //
21cfa096d9SChristian Trott //  typename M::extents_type
22cfa096d9SChristian Trott //    Result: A type that is a specialization of extents.
23cfa096d9SChristian Trott //
24cfa096d9SChristian Trott //  typename M::index_type
25cfa096d9SChristian Trott //    Result: typename M::extents_type::index_type.
26cfa096d9SChristian Trott //
27cfa096d9SChristian Trott //  typename M::rank_type
28cfa096d9SChristian Trott //    Result: typename M::extents_type::rank_type.
29cfa096d9SChristian Trott //
30cfa096d9SChristian Trott //  typename M::layout_type
31cfa096d9SChristian 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.
32cfa096d9SChristian Trott //
33cfa096d9SChristian Trott //  m.extents()
34cfa096d9SChristian Trott //    Result: const typename M::extents_type&
35cfa096d9SChristian Trott //
36cfa096d9SChristian Trott //  m(i...)
37cfa096d9SChristian Trott //    Result: typename M::index_type
38cfa096d9SChristian 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().
39cfa096d9SChristian Trott //
40cfa096d9SChristian Trott //  m(i...) == m(static_cast<typename M::index_type>(i)...)
41cfa096d9SChristian Trott //    Result: bool
42cfa096d9SChristian Trott //    Returns: true
43cfa096d9SChristian Trott //
44cfa096d9SChristian Trott //  m.required_span_size()
45cfa096d9SChristian Trott //    Result: typename M::index_type
46cfa096d9SChristian 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.
47cfa096d9SChristian Trott //
48cfa096d9SChristian Trott //  m.is_unique()
49cfa096d9SChristian Trott //    Result: bool
50cfa096d9SChristian Trott //    Returns: true only if for every i and j where (i != j || ...) is true, m(i...) != m(j...) is true.
51cfa096d9SChristian Trott //
52cfa096d9SChristian Trott //  m.is_exhaustive()
53cfa096d9SChristian Trott //    Result: bool
54cfa096d9SChristian 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.
55cfa096d9SChristian Trott //
56cfa096d9SChristian Trott //  m.is_strided()
57cfa096d9SChristian Trott //    Result: bool
58cfa096d9SChristian Trott //    Returns: true only if for every rank index r of m.extents() there exists an integer
59cfa096d9SChristian Trott //             sr such that, for all i where (i+dr) is a multidimensional index in m.extents() ([mdspan.overview]),
60cfa096d9SChristian Trott //             m((i + dr)...) - m(i...) equals sr
61cfa096d9SChristian Trott //
62cfa096d9SChristian Trott //  m.stride(r)
63cfa096d9SChristian Trott //    Preconditions: m.is_strided() is true.
64cfa096d9SChristian Trott //    Result: typename M::index_type
65cfa096d9SChristian Trott //    Returns: sr as defined in m.is_strided() above.
66cfa096d9SChristian Trott //
67cfa096d9SChristian Trott //  M::is_always_unique()
68cfa096d9SChristian Trott //    Result: A constant expression ([expr.const]) of type bool.
69cfa096d9SChristian Trott //    Returns: true only if m.is_unique() is true for all possible objects m of type M.
70cfa096d9SChristian Trott //
71cfa096d9SChristian Trott //  M::is_always_exhaustive()
72cfa096d9SChristian Trott //    Result: A constant expression ([expr.const]) of type bool.
73cfa096d9SChristian Trott //    Returns: true only if m.is_exhaustive() is true for all possible objects m of type M.
74cfa096d9SChristian Trott //
75cfa096d9SChristian Trott //  M::is_always_strided()
76cfa096d9SChristian Trott //    Result: A constant expression ([expr.const]) of type bool.
77cfa096d9SChristian Trott //    Returns: true only if m.is_strided() is true for all possible objects m of type M.
78cfa096d9SChristian Trott 
79cfa096d9SChristian 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>
85cfa096d9SChristian Trott 
86cfa096d9SChristian Trott #include "test_macros.h"
87cfa096d9SChristian Trott 
88cfa096d9SChristian Trott // Common requirements of all layout mappings
89cfa096d9SChristian Trott template <class M, size_t... Idxs>
90cfa096d9SChristian Trott void test_mapping_requirements(std::index_sequence<Idxs...>) {
91cfa096d9SChristian Trott   using E = typename M::extents_type;
92b84cb9c2SStephan T. Lavavej   LIBCPP_STATIC_ASSERT(std::__mdspan_detail::__is_extents_v<E>);
93cfa096d9SChristian Trott   static_assert(std::is_copy_constructible_v<M>);
94cfa096d9SChristian Trott   static_assert(std::is_nothrow_move_constructible_v<M>);
95cfa096d9SChristian Trott   static_assert(std::is_nothrow_move_assignable_v<M>);
96cfa096d9SChristian Trott   static_assert(std::is_nothrow_swappable_v<M>);
97cfa096d9SChristian Trott   ASSERT_SAME_TYPE(typename M::index_type, typename E::index_type);
98cfa096d9SChristian Trott   ASSERT_SAME_TYPE(typename M::size_type, typename E::size_type);
99cfa096d9SChristian Trott   ASSERT_SAME_TYPE(typename M::rank_type, typename E::rank_type);
100cfa096d9SChristian Trott   ASSERT_SAME_TYPE(typename M::layout_type, std::layout_right);
101cfa096d9SChristian Trott   ASSERT_SAME_TYPE(typename M::layout_type::template mapping<E>, M);
102cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>().extents()), const E&>);
103cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>()(Idxs...)), typename M::index_type>);
104cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>().required_span_size()), typename M::index_type>);
105cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>().is_unique()), bool>);
106cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>().is_exhaustive()), bool>);
107cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(std::declval<M>().is_strided()), bool>);
108cfa096d9SChristian Trott   if constexpr (E::rank() > 0)
109cfa096d9SChristian Trott     static_assert(std::is_same_v<decltype(std::declval<M>().stride(0)), typename M::index_type>);
110cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(M::is_always_unique()), bool>);
111cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(M::is_always_exhaustive()), bool>);
112cfa096d9SChristian Trott   static_assert(std::is_same_v<decltype(M::is_always_strided()), bool>);
113cfa096d9SChristian Trott }
114cfa096d9SChristian Trott 
115cfa096d9SChristian Trott template <class L, class E>
116cfa096d9SChristian Trott void test_layout_mapping_requirements() {
117cfa096d9SChristian Trott   using M = typename L::template mapping<E>;
118cfa096d9SChristian Trott   test_mapping_requirements<M>(std::make_index_sequence<E::rank()>());
119cfa096d9SChristian Trott }
120cfa096d9SChristian Trott 
121cfa096d9SChristian Trott template <class E>
122cfa096d9SChristian Trott void test_layout_mapping_right() {
123cfa096d9SChristian Trott   test_layout_mapping_requirements<std::layout_right, E>();
124cfa096d9SChristian Trott }
125cfa096d9SChristian Trott 
126cfa096d9SChristian Trott int main(int, char**) {
127cfa096d9SChristian Trott   constexpr size_t D = std::dynamic_extent;
128cfa096d9SChristian Trott   test_layout_mapping_right<std::extents<int>>();
129ab562686SStephan T. Lavavej   test_layout_mapping_right<std::extents<signed char, 4, 5>>();
130cfa096d9SChristian Trott   test_layout_mapping_right<std::extents<unsigned, D, 4>>();
131cfa096d9SChristian Trott   test_layout_mapping_right<std::extents<size_t, D, D, D, D>>();
132cfa096d9SChristian Trott   return 0;
133cfa096d9SChristian Trott }
134