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