blob: 012fc2b5fb4433967683e3cb6fb4f12c2a39d178 [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<ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
15// constexpr span<element_type, see below> subspan() const;
16//
17// constexpr span<element_type, dynamic_extent> subspan(
18// index_type offset, index_type count = dynamic_extent) const;
19//
20// Requires: (0 <= Offset && Offset <= size())
21// && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size())
22
23#include <span>
24#include <cassert>
25#include <algorithm>
26#include <string>
27
28#include "test_macros.h"
29
30template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
31constexpr bool testConstexprSpan(Span sp)
32{
33 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
34 LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
35 auto s1 = sp.template subspan<Offset, Count>();
36 auto s2 = sp.subspan(Offset, Count);
37 using S1 = decltype(s1);
38 using S2 = decltype(s2);
39 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
40 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
41 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
42 static_assert(S2::extent == std::dynamic_extent, "");
43 return
44 s1.data() == s2.data()
45 && s1.size() == s2.size()
46 && std::equal(s1.begin(), s1.end(), sp.begin() + Offset);
47}
48
49template <typename Span, ptrdiff_t Offset>
50constexpr bool testConstexprSpan(Span sp)
51{
52 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
53 LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
54 auto s1 = sp.template subspan<Offset>();
55 auto s2 = sp.subspan(Offset);
56 using S1 = decltype(s1);
57 using S2 = decltype(s2);
58 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
59 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
60 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
61 static_assert(S2::extent == std::dynamic_extent, "");
62 return
63 s1.data() == s2.data()
64 && s1.size() == s2.size()
65 && std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end());
66}
67
68
69template <typename Span, ptrdiff_t Offset, ptrdiff_t Count>
70void testRuntimeSpan(Span sp)
71{
72 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
73 LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
74 auto s1 = sp.template subspan<Offset, Count>();
75 auto s2 = sp.subspan(Offset, Count);
76 using S1 = decltype(s1);
77 using S2 = decltype(s2);
78 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
79 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
80 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
81 static_assert(S2::extent == std::dynamic_extent, "");
82 assert(s1.data() == s2.data());
83 assert(s1.size() == s2.size());
84 assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset));
85}
86
87
88template <typename Span, ptrdiff_t Offset>
89void testRuntimeSpan(Span sp)
90{
91 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
92 LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
93 auto s1 = sp.template subspan<Offset>();
94 auto s2 = sp.subspan(Offset);
95 using S1 = decltype(s1);
96 using S2 = decltype(s2);
97 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
98 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
99 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
100 static_assert(S2::extent == std::dynamic_extent, "");
101 assert(s1.data() == s2.data());
102 assert(s1.size() == s2.size());
103 assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()));
104}
105
106
107constexpr int carr1[] = {1,2,3,4};
108 int arr1[] = {5,6,7};
109
110int main ()
111{
112 {
113 using Sp = std::span<const int>;
114 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
115
116 static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
117 static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
118 static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
119 static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
120 static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
121
122 static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
123 static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
124 static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
125 static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
126 }
127
128 {
129 using Sp = std::span<const int, 4>;
130
131 static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
132 static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
133 static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
134 static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
135 static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
136
137 static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
138 static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
139 static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
140 static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
141 }
142
143 {
144 using Sp = std::span<const int>;
145 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
146
147 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
148 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
149 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
150 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
151 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
152 }
153
154 {
155 using Sp = std::span<const int, 4>;
156
157 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
158
159 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
160 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
161 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
162 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
163 }
164
165 {
166 using Sp = std::span<int>;
167 testRuntimeSpan<Sp, 0>(Sp{});
168
169 testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
170 testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
171 testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
172 testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
173
174 testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
175 testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
176 testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
177 }
178
179 {
180 using Sp = std::span<int, 3>;
181
182 testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
183 testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
184 testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
185 testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
186
187 testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
188 testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
189 testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
190 }
191
192 {
193 using Sp = std::span<int>;
194 testRuntimeSpan<Sp, 0>(Sp{});
195
196 testRuntimeSpan<Sp, 0>(Sp{arr1});
197 testRuntimeSpan<Sp, 1>(Sp{arr1});
198 testRuntimeSpan<Sp, 2>(Sp{arr1});
199 testRuntimeSpan<Sp, 3>(Sp{arr1});
200 }
201
202 {
203 using Sp = std::span<int, 3>;
204
205 testRuntimeSpan<Sp, 0>(Sp{arr1});
206 testRuntimeSpan<Sp, 1>(Sp{arr1});
207 testRuntimeSpan<Sp, 2>(Sp{arr1});
208 testRuntimeSpan<Sp, 3>(Sp{arr1});
209 }
210}