1 //===--- span_test.cpp - Tests for the span class -------------------------===//
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
9 #include "span.h"
10
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13
14 #include <array>
15 #include <vector>
16
17 namespace {
18
arraySize(T (&)[N])19 template <typename T, size_t N> size_t arraySize(T (&)[N]) { return N; }
20
TEST(Span,NullConstruction)21 TEST(Span, NullConstruction) {
22 acxxel::Span<int> Span0;
23 EXPECT_EQ(nullptr, Span0.data());
24 EXPECT_EQ(0, Span0.size());
25
26 acxxel::Span<int> Span1(nullptr);
27 EXPECT_EQ(nullptr, Span1.data());
28 EXPECT_EQ(0, Span1.size());
29 }
30
TEST(Span,PtrSizeConstruction)31 TEST(Span, PtrSizeConstruction) {
32 int ZeroSize = 0;
33 acxxel::Span<int> Span0(nullptr, ZeroSize);
34 EXPECT_EQ(Span0.data(), nullptr);
35 EXPECT_EQ(Span0.size(), 0);
36
37 int Values[] = {0, 1, 2};
38 acxxel::Span<int> Span1(Values, arraySize(Values));
39 EXPECT_EQ(Span1.data(), Values);
40 EXPECT_EQ(static_cast<size_t>(Span1.size()), arraySize(Values));
41
42 acxxel::Span<int> Span2(Values, ZeroSize);
43 EXPECT_EQ(Span2.data(), Values);
44 EXPECT_EQ(Span2.size(), 0);
45 }
46
TEST(Span,PtrSizeConstruction_NegativeCount)47 TEST(Span, PtrSizeConstruction_NegativeCount) {
48 int Values[] = {0, 1, 2};
49 EXPECT_DEATH(acxxel::Span<int> Span0(Values, -1), "terminate");
50 }
51
TEST(Span,PtrSizeConstruction_NullptrNonzeroSize)52 TEST(Span, PtrSizeConstruction_NullptrNonzeroSize) {
53 EXPECT_DEATH(acxxel::Span<int> Span0(nullptr, 1), "terminate");
54 }
55
TEST(Span,FirstLastConstruction)56 TEST(Span, FirstLastConstruction) {
57 int Values[] = {0, 1, 2};
58
59 acxxel::Span<int> Span0(Values, Values);
60 EXPECT_EQ(Span0.data(), Values);
61 EXPECT_EQ(Span0.size(), 0);
62
63 acxxel::Span<int> Span(Values, Values + 2);
64 EXPECT_EQ(Span.data(), Values);
65 EXPECT_EQ(Span.size(), 2);
66 }
67
TEST(Span,FirstLastConstruction_LastBeforeFirst)68 TEST(Span, FirstLastConstruction_LastBeforeFirst) {
69 int Values[] = {0, 1, 2};
70 EXPECT_DEATH(acxxel::Span<int> Span(Values + 2, Values), "terminate");
71 }
72
TEST(Span,ArrayConstruction)73 TEST(Span, ArrayConstruction) {
74 int Array[] = {0, 1, 2};
75 acxxel::Span<int> Span(Array);
76 EXPECT_EQ(Span.data(), Array);
77 EXPECT_EQ(Span.size(), 3);
78 }
79
TEST(Span,StdArrayConstruction)80 TEST(Span, StdArrayConstruction) {
81 std::array<int, 3> Array{{0, 1, 2}};
82 acxxel::Span<int> Span(Array);
83 EXPECT_EQ(Span.data(), Array.data());
84 EXPECT_EQ(static_cast<size_t>(Span.size()), Array.size());
85
86 std::array<const int, 3> ConstArray{{0, 1, 2}};
87 acxxel::Span<const int> ConstSpan(ConstArray);
88 EXPECT_EQ(ConstSpan.data(), ConstArray.data());
89 EXPECT_EQ(static_cast<size_t>(ConstSpan.size()), ConstArray.size());
90 }
91
TEST(Span,ContainerConstruction)92 TEST(Span, ContainerConstruction) {
93 std::vector<int> Vector = {0, 1, 2};
94 acxxel::Span<int> Span(Vector);
95 EXPECT_EQ(Span.data(), &Vector[0]);
96 EXPECT_EQ(static_cast<size_t>(Span.size()), Vector.size());
97 }
98
TEST(Span,CopyConstruction)99 TEST(Span, CopyConstruction) {
100 int Values[] = {0, 1, 2};
101 acxxel::Span<int> Span0(Values);
102 acxxel::Span<int> Span1(Span0);
103 EXPECT_EQ(Span1.data(), Values);
104 EXPECT_EQ(static_cast<size_t>(Span1.size()), arraySize(Values));
105 }
106
TEST(Span,CopyAssignment)107 TEST(Span, CopyAssignment) {
108 int Values[] = {0, 1, 2};
109 acxxel::Span<int> Span0(Values);
110 acxxel::Span<int> Span1;
111 Span1 = Span0;
112 EXPECT_EQ(Span1.data(), Values);
113 EXPECT_EQ(static_cast<size_t>(Span1.size()), arraySize(Values));
114 }
115
TEST(Span,CopyConstFromNonConst)116 TEST(Span, CopyConstFromNonConst) {
117 int Values[] = {0, 1, 2};
118 acxxel::Span<int> Span0(Values);
119 acxxel::Span<const int> Span1(Span0);
120 EXPECT_EQ(Span1.data(), Values);
121 EXPECT_EQ(static_cast<size_t>(Span1.size()), arraySize(Values));
122 }
123
TEST(Span,FirstMethod)124 TEST(Span, FirstMethod) {
125 int Values[] = {0, 1, 2};
126 acxxel::Span<int> Span(Values);
127 acxxel::Span<int> Span0 = Span.first(0);
128 acxxel::Span<int> Span1 = Span.first(1);
129 acxxel::Span<int> Span2 = Span.first(2);
130 acxxel::Span<int> Span3 = Span.first(3);
131
132 EXPECT_EQ(Span0.data(), Values);
133 EXPECT_EQ(Span1.data(), Values);
134 EXPECT_EQ(Span2.data(), Values);
135 EXPECT_EQ(Span3.data(), Values);
136
137 EXPECT_TRUE(Span0.empty());
138
139 EXPECT_THAT(Span1, ::testing::ElementsAre(0));
140 EXPECT_THAT(Span2, ::testing::ElementsAre(0, 1));
141 EXPECT_THAT(Span3, ::testing::ElementsAre(0, 1, 2));
142 }
143
TEST(Span,FirstMethod_IllegalArguments)144 TEST(Span, FirstMethod_IllegalArguments) {
145 int Values[] = {0, 1, 2};
146 acxxel::Span<int> Span(Values);
147
148 EXPECT_DEATH(Span.first(-1), "terminate");
149 EXPECT_DEATH(Span.first(4), "terminate");
150 }
151
TEST(Span,LastMethod)152 TEST(Span, LastMethod) {
153 int Values[] = {0, 1, 2};
154 acxxel::Span<int> Span(Values);
155 acxxel::Span<int> Span0 = Span.last(0);
156 acxxel::Span<int> Span1 = Span.last(1);
157 acxxel::Span<int> Span2 = Span.last(2);
158 acxxel::Span<int> Span3 = Span.last(3);
159
160 EXPECT_EQ(Span0.data(), Values);
161 EXPECT_EQ(Span1.data(), Values + 2);
162 EXPECT_EQ(Span2.data(), Values + 1);
163 EXPECT_EQ(Span3.data(), Values);
164
165 EXPECT_TRUE(Span0.empty());
166
167 EXPECT_THAT(Span1, ::testing::ElementsAre(2));
168 EXPECT_THAT(Span2, ::testing::ElementsAre(1, 2));
169 EXPECT_THAT(Span3, ::testing::ElementsAre(0, 1, 2));
170 }
171
TEST(Span,LastMethod_IllegalArguments)172 TEST(Span, LastMethod_IllegalArguments) {
173 int Values[] = {0, 1, 2};
174 acxxel::Span<int> Span(Values);
175
176 EXPECT_DEATH(Span.last(-1), "terminate");
177 EXPECT_DEATH(Span.last(4), "terminate");
178 }
179
TEST(Span,SubspanMethod)180 TEST(Span, SubspanMethod) {
181 int Values[] = {0, 1, 2};
182 acxxel::Span<int> Span(Values);
183
184 acxxel::Span<int> Span0 = Span.subspan(0);
185 acxxel::Span<int> Span0e = Span.subspan(0, acxxel::dynamic_extent);
186 acxxel::Span<int> Span00 = Span.subspan(0, 0);
187 acxxel::Span<int> Span01 = Span.subspan(0, 1);
188 acxxel::Span<int> Span02 = Span.subspan(0, 2);
189 acxxel::Span<int> Span03 = Span.subspan(0, 3);
190
191 acxxel::Span<int> Span1 = Span.subspan(1);
192 acxxel::Span<int> Span1e = Span.subspan(1, acxxel::dynamic_extent);
193 acxxel::Span<int> Span10 = Span.subspan(1, 0);
194 acxxel::Span<int> Span11 = Span.subspan(1, 1);
195 acxxel::Span<int> Span12 = Span.subspan(1, 2);
196
197 acxxel::Span<int> Span2 = Span.subspan(2);
198 acxxel::Span<int> Span2e = Span.subspan(2, acxxel::dynamic_extent);
199 acxxel::Span<int> Span20 = Span.subspan(2, 0);
200 acxxel::Span<int> Span21 = Span.subspan(2, 1);
201
202 acxxel::Span<int> Span3 = Span.subspan(3);
203 acxxel::Span<int> Span3e = Span.subspan(3, acxxel::dynamic_extent);
204 acxxel::Span<int> Span30 = Span.subspan(3, 0);
205
206 EXPECT_EQ(Span0.data(), Values);
207 EXPECT_EQ(Span0e.data(), Values);
208 EXPECT_EQ(Span00.data(), Values);
209 EXPECT_EQ(Span01.data(), Values);
210 EXPECT_EQ(Span02.data(), Values);
211 EXPECT_EQ(Span03.data(), Values);
212
213 EXPECT_EQ(Span1.data(), Values + 1);
214 EXPECT_EQ(Span1e.data(), Values + 1);
215 EXPECT_EQ(Span10.data(), Values + 1);
216 EXPECT_EQ(Span11.data(), Values + 1);
217 EXPECT_EQ(Span12.data(), Values + 1);
218
219 EXPECT_EQ(Span2.data(), Values + 2);
220 EXPECT_EQ(Span2e.data(), Values + 2);
221 EXPECT_EQ(Span20.data(), Values + 2);
222 EXPECT_EQ(Span21.data(), Values + 2);
223
224 EXPECT_EQ(Span3.data(), Values + 3);
225 EXPECT_EQ(Span3e.data(), Values + 3);
226 EXPECT_EQ(Span30.data(), Values + 3);
227
228 EXPECT_TRUE(Span00.empty());
229 EXPECT_TRUE(Span10.empty());
230 EXPECT_TRUE(Span20.empty());
231 EXPECT_TRUE(Span30.empty());
232
233 EXPECT_THAT(Span0, ::testing::ElementsAre(0, 1, 2));
234 EXPECT_THAT(Span0e, ::testing::ElementsAre(0, 1, 2));
235 EXPECT_THAT(Span01, ::testing::ElementsAre(0));
236 EXPECT_THAT(Span02, ::testing::ElementsAre(0, 1));
237 EXPECT_THAT(Span03, ::testing::ElementsAre(0, 1, 2));
238
239 EXPECT_THAT(Span1, ::testing::ElementsAre(1, 2));
240 EXPECT_THAT(Span1e, ::testing::ElementsAre(1, 2));
241 EXPECT_THAT(Span11, ::testing::ElementsAre(1));
242 EXPECT_THAT(Span12, ::testing::ElementsAre(1, 2));
243
244 EXPECT_THAT(Span2, ::testing::ElementsAre(2));
245 EXPECT_THAT(Span2e, ::testing::ElementsAre(2));
246 EXPECT_THAT(Span21, ::testing::ElementsAre(2));
247
248 EXPECT_TRUE(Span3.empty());
249 EXPECT_TRUE(Span3e.empty());
250 }
251
TEST(Span,SubspanMethod_IllegalArguments)252 TEST(Span, SubspanMethod_IllegalArguments) {
253 int Values[] = {0, 1, 2};
254 acxxel::Span<int> Span(Values);
255 EXPECT_DEATH(Span.subspan(-1, 0), "terminate");
256 EXPECT_DEATH(Span.subspan(0, -2), "terminate");
257 EXPECT_DEATH(Span.subspan(0, 4), "terminate");
258 EXPECT_DEATH(Span.subspan(1, 3), "terminate");
259 EXPECT_DEATH(Span.subspan(2, 2), "terminate");
260 EXPECT_DEATH(Span.subspan(3, 1), "terminate");
261 EXPECT_DEATH(Span.subspan(4, 0), "terminate");
262 }
263
TEST(Span,ElementAccess)264 TEST(Span, ElementAccess) {
265 int Values[] = {0, 1, 2};
266 acxxel::Span<int> Span(Values);
267
268 EXPECT_EQ(&Span[0], Values);
269 EXPECT_EQ(&Span[1], Values + 1);
270 EXPECT_EQ(&Span[2], Values + 2);
271 EXPECT_EQ(&Span(0), Values);
272 EXPECT_EQ(&Span(1), Values + 1);
273 EXPECT_EQ(&Span(2), Values + 2);
274
275 Span[0] = 5;
276 EXPECT_EQ(Values[0], 5);
277
278 Span(0) = 0;
279 EXPECT_EQ(Values[0], 0);
280
281 const int ConstValues[] = {0, 1, 2};
282 acxxel::Span<const int> ConstSpan(ConstValues);
283
284 EXPECT_EQ(&ConstSpan[0], ConstValues);
285 EXPECT_EQ(&ConstSpan[1], ConstValues + 1);
286 EXPECT_EQ(&ConstSpan[2], ConstValues + 2);
287 EXPECT_EQ(&ConstSpan(0), ConstValues);
288 EXPECT_EQ(&ConstSpan(1), ConstValues + 1);
289 EXPECT_EQ(&ConstSpan(2), ConstValues + 2);
290 }
291
292 } // namespace
293