xref: /llvm-project/libcxx/test/std/containers/views/views.span/span.cons/array.pass.cpp (revision a8cf78c73914f614d4ec339f7bd5bba8b20c3c29)
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
9 
10 // <span>
11 
12 // template<size_t N>
13 //     constexpr span(element_type (&arr)[N]) noexcept;
14 //
15 // Remarks: These constructors shall not participate in overload resolution unless:
16 //   — extent == dynamic_extent || N == extent is true, and
17 //   — remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
18 //
19 
20 
21 #include <span>
22 #include <cassert>
23 #include <string>
24 
25 #include "test_macros.h"
26 
27 
28 void checkCV()
29 {
30                    int   arr[] = {1,2,3};
31     const          int  carr[] = {4,5,6};
32           volatile int  varr[] = {7,8,9};
33     const volatile int cvarr[] = {1,3,5};
34 
35 //  Types the same (dynamic sized)
36     {
37     std::span<               int> s1{  arr};    // a span<               int> pointing at int.
38     std::span<const          int> s2{ carr};    // a span<const          int> pointing at const int.
39     std::span<      volatile int> s3{ varr};    // a span<      volatile int> pointing at volatile int.
40     std::span<const volatile int> s4{cvarr};    // a span<const volatile int> pointing at const volatile int.
41     assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
42     }
43 
44 //  Types the same (static sized)
45     {
46     std::span<               int,3> s1{  arr};  // a span<               int> pointing at int.
47     std::span<const          int,3> s2{ carr};  // a span<const          int> pointing at const int.
48     std::span<      volatile int,3> s3{ varr};  // a span<      volatile int> pointing at volatile int.
49     std::span<const volatile int,3> s4{cvarr};  // a span<const volatile int> pointing at const volatile int.
50     assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
51     }
52 
53 
54 //  types different (dynamic sized)
55     {
56     std::span<const          int> s1{ arr};     // a span<const          int> pointing at int.
57     std::span<      volatile int> s2{ arr};     // a span<      volatile int> pointing at int.
58     std::span<      volatile int> s3{ arr};     // a span<      volatile int> pointing at const int.
59     std::span<const volatile int> s4{ arr};     // a span<const volatile int> pointing at int.
60     std::span<const volatile int> s5{carr};     // a span<const volatile int> pointing at const int.
61     std::span<const volatile int> s6{varr};     // a span<const volatile int> pointing at volatile int.
62     assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
63     }
64 
65 //  types different (static sized)
66     {
67     std::span<const          int,3> s1{ arr};   // a span<const          int> pointing at int.
68     std::span<      volatile int,3> s2{ arr};   // a span<      volatile int> pointing at int.
69     std::span<      volatile int,3> s3{ arr};   // a span<      volatile int> pointing at const int.
70     std::span<const volatile int,3> s4{ arr};   // a span<const volatile int> pointing at int.
71     std::span<const volatile int,3> s5{carr};   // a span<const volatile int> pointing at const int.
72     std::span<const volatile int,3> s6{varr};   // a span<const volatile int> pointing at volatile int.
73     assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
74     }
75 }
76 
77 template<class T>
78 constexpr bool testSpan()
79 {
80     T val[2] = {};
81 
82     ASSERT_NOEXCEPT(std::span<T>{val});
83     ASSERT_NOEXCEPT(std::span<T, 2>{val});
84     ASSERT_NOEXCEPT(std::span<const T>{val});
85     ASSERT_NOEXCEPT(std::span<const T, 2>{val});
86 
87     std::span<T> s1 = val;
88     std::span<T, 2> s2 = val;
89     std::span<const T> s3 = val;
90     std::span<const T, 2> s4 = val;
91     assert(s1.data() == val && s1.size() == 2);
92     assert(s2.data() == val && s2.size() == 2);
93     assert(s3.data() == val && s3.size() == 2);
94     assert(s4.data() == val && s4.size() == 2);
95 
96     std::span<const int> s5 = {{1,2}};
97     std::span<const int, 2> s6 = {{1,2}};
98     assert(s5.size() == 2);  // and it dangles
99     assert(s6.size() == 2);  // and it dangles
100 
101     return true;
102 }
103 
104 
105 struct A {};
106 
107 int main(int, char**)
108 {
109     testSpan<int>();
110     testSpan<double>();
111     testSpan<A>();
112     testSpan<std::string>();
113 
114     static_assert(testSpan<int>());
115     static_assert(testSpan<double>());
116     static_assert(testSpan<A>());
117 
118     checkCV();
119 
120     return 0;
121 }
122