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