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