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