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