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