xref: /llvm-project/libcxx/test/std/containers/views/views.span/span.cons/span.pass.cpp (revision 38bf6840e8589ebe22e8157aee79a57d9db9393d)
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 #include <span>
20 #include <cassert>
21 #include <string>
22 
23 #include "test_macros.h"
24 
25 template <class T, class From>
check()26 TEST_CONSTEXPR_CXX20 void check() {
27   // dynamic -> dynamic
28   {
29     {
30       std::span<From> from;
31       std::span<T> span{from};
32       ASSERT_NOEXCEPT(std::span<T>(from));
33       assert(span.data() == nullptr);
34       assert(span.size() == 0);
35     }
36     {
37       From array[3] = {};
38       std::span<From> from(array);
39       std::span<T> span{from};
40       ASSERT_NOEXCEPT(std::span<T>(from));
41       assert(span.data() == array);
42       assert(span.size() == 3);
43     }
44   }
45 
46   // static -> static
47   {
48     {
49       std::span<From, 0> from;
50       std::span<T, 0> span{from};
51       ASSERT_NOEXCEPT(std::span<T, 0>(from));
52       assert(span.data() == nullptr);
53       assert(span.size() == 0);
54     }
55 
56     {
57       From array[3] = {};
58       std::span<From, 3> from(array);
59       std::span<T, 3> span{from};
60       ASSERT_NOEXCEPT(std::span<T, 3>(from));
61       assert(span.data() == array);
62       assert(span.size() == 3);
63     }
64   }
65 
66   // static -> dynamic
67   {
68     {
69       std::span<From, 0> from;
70       std::span<T> span{from};
71       ASSERT_NOEXCEPT(std::span<T>(from));
72       assert(span.data() == nullptr);
73       assert(span.size() == 0);
74     }
75 
76     {
77       From array[3] = {};
78       std::span<From, 3> from(array);
79       std::span<T> span{from};
80       ASSERT_NOEXCEPT(std::span<T>(from));
81       assert(span.data() == array);
82       assert(span.size() == 3);
83     }
84   }
85 
86   // dynamic -> static (not allowed)
87 }
88 
89 template <class T>
check_cvs()90 TEST_CONSTEXPR_CXX20 void check_cvs() {
91   check<T, T>();
92 
93   check<T const, T>();
94   check<T const, T const>();
95 
96   check<T volatile, T>();
97   check<T volatile, T volatile>();
98 
99   check<T const volatile, T>();
100   check<T const volatile, T const>();
101   check<T const volatile, T volatile>();
102   check<T const volatile, T const volatile>();
103 }
104 
105 struct A {};
106 
test()107 TEST_CONSTEXPR_CXX20 bool test() {
108   check_cvs<int>();
109   check_cvs<long>();
110   check_cvs<double>();
111   check_cvs<std::string>();
112   check_cvs<A>();
113   return true;
114 }
115 
main(int,char **)116 int main(int, char**) {
117   static_assert(test());
118   test();
119 
120   return 0;
121 }
122