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