blob: 5fdbab22755a6e0c4d5cb9f03900de7c1ce8ab6c [file] [log] [blame]
Marshall Clow8a0794b2018-07-24 03:01:02 +00001// -*- 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//===---------------------------------------------------------------------===//
Stephan T. Lavavejdec89052018-11-14 03:06:06 +000010// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
Marshall Clow8a0794b2018-07-24 03:01:02 +000011
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
28void 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
78template <typename T>
79constexpr 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
95template <typename T>
96void 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
111template <typename Dest, typename Src>
112bool 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
123struct A{};
124
125int 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}