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 // constexpr span(pointer first, pointer last);
14 // Requires: [first, last) shall be a valid range.
15 //   If extent is not equal to dynamic_extent, then last - first shall be equal to extent.
16 //
17 
18 #include <span>
19 #include <cassert>
20 #include <string>
21 
22 #include "test_macros.h"
23 
checkCV()24 void checkCV()
25 {
26                    int   arr[] = {1,2,3};
27     const          int  carr[] = {4,5,6};
28           volatile int  varr[] = {7,8,9};
29     const volatile int cvarr[] = {1,3,5};
30 
31 //  Types the same (dynamic sized)
32     {
33     std::span<               int> s1{  arr,   arr + 3}; // a span<               int> pointing at int.
34     std::span<const          int> s2{ carr,  carr + 3}; // a span<const          int> pointing at const int.
35     std::span<      volatile int> s3{ varr,  varr + 3}; // a span<      volatile int> pointing at volatile int.
36     std::span<const volatile int> s4{cvarr, cvarr + 3}; // a span<const volatile int> pointing at const volatile int.
37     assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
38     }
39 
40 //  Types the same (static sized)
41     {
42     std::span<               int,3> s1{  arr,   arr + 3};   // a span<               int> pointing at int.
43     std::span<const          int,3> s2{ carr,  carr + 3};   // a span<const          int> pointing at const int.
44     std::span<      volatile int,3> s3{ varr,  varr + 3};   // a span<      volatile int> pointing at volatile int.
45     std::span<const volatile int,3> s4{cvarr, cvarr + 3};   // a span<const volatile int> pointing at const volatile int.
46     assert(s1.size() + s2.size() + s3.size() + s4.size() == 12);
47     }
48 
49 
50 //  types different (dynamic sized)
51     {
52     std::span<const          int> s1{ arr,  arr + 3};       // a span<const          int> pointing at int.
53     std::span<      volatile int> s2{ arr,  arr + 3};       // a span<      volatile int> pointing at int.
54     std::span<      volatile int> s3{ arr,  arr + 3};       // a span<      volatile int> pointing at const int.
55     std::span<const volatile int> s4{ arr,  arr + 3};       // a span<const volatile int> pointing at int.
56     std::span<const volatile int> s5{carr, carr + 3};       // a span<const volatile int> pointing at const int.
57     std::span<const volatile int> s6{varr, varr + 3};       // a span<const volatile int> pointing at volatile int.
58     assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
59     }
60 
61 //  types different (static sized)
62     {
63     std::span<const          int,3> s1{ arr,  arr + 3}; // a span<const          int> pointing at int.
64     std::span<      volatile int,3> s2{ arr,  arr + 3}; // a span<      volatile int> pointing at int.
65     std::span<      volatile int,3> s3{ arr,  arr + 3}; // a span<      volatile int> pointing at const int.
66     std::span<const volatile int,3> s4{ arr,  arr + 3}; // a span<const volatile int> pointing at int.
67     std::span<const volatile int,3> s5{carr, carr + 3}; // a span<const volatile int> pointing at const int.
68     std::span<const volatile int,3> s6{varr, varr + 3}; // a span<const volatile int> pointing at volatile int.
69     assert(s1.size() + s2.size() + s3.size() + s4.size() + s5.size() + s6.size() == 18);
70     }
71 }
72 
73 
74 template <typename T>
testConstexprSpan()75 constexpr bool testConstexprSpan()
76 {
77     constexpr T val[2] = {};
78     std::span<const T>   s1{val, val+2};
79     std::span<const T,2> s2{val, val+2};
80     return
81         s1.data() == &val[0] && s1.size() == 2
82     &&  s2.data() == &val[0] && s2.size() == 2;
83 }
84 
85 
86 template <typename T>
testRuntimeSpan()87 void testRuntimeSpan()
88 {
89     T val[2] = {};
90     std::span<T>   s1{val, val+2};
91     std::span<T,2> s2{val, val+2};
92     assert(s1.data() == &val[0] && s1.size() == 2);
93     assert(s2.data() == &val[0] && s2.size() == 2);
94 }
95 
96 struct A{};
97 
main(int,char **)98 int main(int, char**)
99 {
100     static_assert(testConstexprSpan<int>(),    "");
101     static_assert(testConstexprSpan<long>(),   "");
102     static_assert(testConstexprSpan<double>(), "");
103     static_assert(testConstexprSpan<A>(),      "");
104 
105     testRuntimeSpan<int>();
106     testRuntimeSpan<long>();
107     testRuntimeSpan<double>();
108     testRuntimeSpan<std::string>();
109     testRuntimeSpan<A>();
110 
111     checkCV();
112 
113   return 0;
114 }
115