• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===------------------------------ span ---------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===---------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
11 
12 // <span>
13 
14 // template<class OtherElementType, ptrdiff_t OtherExtent>
15 //    constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
16 //
17 //  Remarks: This constructor shall not participate in overload resolution unless:
18 //      Extent == dynamic_extent || Extent == OtherExtent is true, and
19 //      OtherElementType(*)[] is convertible to ElementType(*)[].
20 
21 
22 #include <span>
23 #include <cassert>
24 #include <string>
25 
26 #include "test_macros.h"
27 
checkCV()28 void checkCV()
29 {
30     std::span<               int>   sp;
31 //  std::span<const          int>  csp;
32     std::span<      volatile int>  vsp;
33 //  std::span<const volatile int> cvsp;
34 
35     std::span<               int, 0>   sp0;
36 //  std::span<const          int, 0>  csp0;
37     std::span<      volatile int, 0>  vsp0;
38 //  std::span<const volatile int, 0> cvsp0;
39 
40 //  dynamic -> dynamic
41     {
42         std::span<const          int> s1{  sp}; // a span<const          int> pointing at int.
43         std::span<      volatile int> s2{  sp}; // a span<      volatile int> pointing at int.
44         std::span<const volatile int> s3{  sp}; // a span<const volatile int> pointing at int.
45         std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int.
46         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
47     }
48 
49 //  static -> static
50     {
51         std::span<const          int, 0> s1{  sp0}; // a span<const          int> pointing at int.
52         std::span<      volatile int, 0> s2{  sp0}; // a span<      volatile int> pointing at int.
53         std::span<const volatile int, 0> s3{  sp0}; // a span<const volatile int> pointing at int.
54         std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
55         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
56     }
57 
58 //  static -> dynamic
59     {
60         std::span<const          int> s1{  sp0};    // a span<const          int> pointing at int.
61         std::span<      volatile int> s2{  sp0};    // a span<      volatile int> pointing at int.
62         std::span<const volatile int> s3{  sp0};    // a span<const volatile int> pointing at int.
63         std::span<const volatile int> s4{ vsp0};    // a span<const volatile int> pointing at volatile int.
64         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
65     }
66 
67 //  dynamic -> static
68     {
69         std::span<const          int, 0> s1{  sp};  // a span<const          int> pointing at int.
70         std::span<      volatile int, 0> s2{  sp};  // a span<      volatile int> pointing at int.
71         std::span<const volatile int, 0> s3{  sp};  // a span<const volatile int> pointing at int.
72         std::span<const volatile int, 0> s4{ vsp};  // a span<const volatile int> pointing at volatile int.
73         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
74     }
75 }
76 
77 
78 template <typename T>
testConstexprSpan()79 constexpr bool testConstexprSpan()
80 {
81     std::span<T>    s0{};
82     std::span<T, 0> s1(s0); // dynamic -> static
83     std::span<T>    s2(s1); // static -> dynamic
84     ASSERT_NOEXCEPT(std::span<T>   {s0});
85     ASSERT_NOEXCEPT(std::span<T, 0>{s1});
86     ASSERT_NOEXCEPT(std::span<T>   {s1});
87     ASSERT_NOEXCEPT(std::span<T, 0>{s0});
88 
89     return
90         s1.data() == nullptr && s1.size() == 0
91     &&  s2.data() == nullptr && s2.size() == 0;
92 }
93 
94 
95 template <typename T>
testRuntimeSpan()96 void testRuntimeSpan()
97 {
98     std::span<T>    s0{};
99     std::span<T, 0> s1(s0); // dynamic -> static
100     std::span<T>    s2(s1); // static -> dynamic
101     ASSERT_NOEXCEPT(std::span<T>   {s0});
102     ASSERT_NOEXCEPT(std::span<T, 0>{s1});
103     ASSERT_NOEXCEPT(std::span<T>   {s1});
104     ASSERT_NOEXCEPT(std::span<T, 0>{s0});
105 
106     assert(s1.data() == nullptr && s1.size() == 0);
107     assert(s2.data() == nullptr && s2.size() == 0);
108 }
109 
110 
111 template <typename Dest, typename Src>
testConversionSpan()112 bool testConversionSpan()
113 {
114     static_assert(std::is_convertible_v<Src(*)[], Dest(*)[]>, "Bad input types to 'testConversionSpan");
115     std::span<Src>    s0d{};
116     std::span<Src>    s0s{};
117     std::span<Dest, 0> s1(s0d); // dynamic -> static
118     std::span<Dest>    s2(s0s); // static -> dynamic
119         s1.data() == nullptr && s1.size() == 0
120     &&  s2.data() == nullptr && s2.size() == 0;
121 }
122 
123 struct A{};
124 
main()125 int main ()
126 {
127     static_assert(testConstexprSpan<int>(),    "");
128     static_assert(testConstexprSpan<long>(),   "");
129     static_assert(testConstexprSpan<double>(), "");
130     static_assert(testConstexprSpan<A>(),      "");
131 
132     testRuntimeSpan<int>();
133     testRuntimeSpan<long>();
134     testRuntimeSpan<double>();
135     testRuntimeSpan<std::string>();
136     testRuntimeSpan<A>();
137 
138 //  TODO: Add some conversion tests here that aren't "X --> const X"
139 //  assert((testConversionSpan<unsigned char, char>()));
140 
141     checkCV();
142 }
143