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