OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <algorithm> | |
12 #include <string> | |
13 #include <vector> | |
14 | |
15 #include "webrtc/base/array_view.h" | |
16 #include "webrtc/base/buffer.h" | |
17 #include "webrtc/base/checks.h" | |
18 #include "webrtc/base/gunit.h" | |
19 #include "webrtc/test/gmock.h" | |
20 | |
21 namespace rtc { | |
22 | |
23 namespace { | |
24 | |
25 using ::testing::ElementsAre; | |
26 using ::testing::IsEmpty; | |
27 | |
28 template <typename T> | |
29 void Call(ArrayView<T>) {} | |
30 | |
31 } // namespace | |
32 | |
33 TEST(ArrayViewTest, TestConstructFromPtrAndArray) { | |
34 char arr[] = "Arrr!"; | |
35 const char carr[] = "Carrr!"; | |
36 Call<const char>(arr); | |
37 Call<const char>(carr); | |
38 Call<char>(arr); | |
39 // Call<char>(carr); // Compile error, because can't drop const. | |
40 // Call<int>(arr); // Compile error, because incompatible types. | |
41 ArrayView<int*> x; | |
42 EXPECT_EQ(0u, x.size()); | |
43 EXPECT_EQ(nullptr, x.data()); | |
44 ArrayView<char> y = arr; | |
45 EXPECT_EQ(6u, y.size()); | |
46 EXPECT_EQ(arr, y.data()); | |
47 ArrayView<char, 6> yf = arr; | |
48 static_assert(yf.size() == 6, ""); | |
49 EXPECT_EQ(arr, yf.data()); | |
50 ArrayView<const char> z(arr + 1, 3); | |
51 EXPECT_EQ(3u, z.size()); | |
52 EXPECT_EQ(arr + 1, z.data()); | |
53 ArrayView<const char, 3> zf(arr + 1, 3); | |
54 static_assert(zf.size() == 3, ""); | |
55 EXPECT_EQ(arr + 1, zf.data()); | |
56 ArrayView<const char> w(arr, 2); | |
57 EXPECT_EQ(2u, w.size()); | |
58 EXPECT_EQ(arr, w.data()); | |
59 ArrayView<const char, 2> wf(arr, 2); | |
60 static_assert(wf.size() == 2, ""); | |
61 EXPECT_EQ(arr, wf.data()); | |
62 ArrayView<char> q(arr, 0); | |
63 EXPECT_EQ(0u, q.size()); | |
64 EXPECT_EQ(nullptr, q.data()); | |
65 ArrayView<char, 0> qf(arr, 0); | |
66 static_assert(qf.size() == 0, ""); | |
67 EXPECT_EQ(nullptr, qf.data()); | |
68 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
69 // DCHECK error (nullptr with nonzero size). | |
70 EXPECT_DEATH(ArrayView<int>(static_cast<int*>(nullptr), 5), ""); | |
71 #endif | |
72 // These are compile errors, because incompatible types. | |
73 // ArrayView<int> m = arr; | |
74 // ArrayView<float> n(arr + 2, 2); | |
75 } | |
76 | |
77 TEST(ArrayViewTest, TestCopyConstructorVariable) { | |
78 char arr[] = "Arrr!"; | |
79 ArrayView<char> x = arr; | |
80 EXPECT_EQ(6u, x.size()); | |
81 EXPECT_EQ(arr, x.data()); | |
82 ArrayView<char> y = x; // Copy non-const -> non-const. | |
83 EXPECT_EQ(6u, y.size()); | |
84 EXPECT_EQ(arr, y.data()); | |
85 ArrayView<const char> z = x; // Copy non-const -> const. | |
86 EXPECT_EQ(6u, z.size()); | |
87 EXPECT_EQ(arr, z.data()); | |
88 ArrayView<const char> w = z; // Copy const -> const. | |
89 EXPECT_EQ(6u, w.size()); | |
90 EXPECT_EQ(arr, w.data()); | |
91 // ArrayView<char> v = z; // Compile error, because can't drop const. | |
92 } | |
93 | |
94 TEST(ArrayViewTest, TestCopyConstructorFixed) { | |
95 char arr[] = "Arrr!"; | |
96 ArrayView<char, 6> x = arr; | |
97 static_assert(x.size() == 6, ""); | |
98 EXPECT_EQ(arr, x.data()); | |
99 | |
100 // Copy fixed -> fixed. | |
101 ArrayView<char, 6> y = x; // Copy non-const -> non-const. | |
102 static_assert(y.size() == 6, ""); | |
103 EXPECT_EQ(arr, y.data()); | |
104 ArrayView<const char, 6> z = x; // Copy non-const -> const. | |
105 static_assert(z.size() == 6, ""); | |
106 EXPECT_EQ(arr, z.data()); | |
107 ArrayView<const char, 6> w = z; // Copy const -> const. | |
108 static_assert(w.size() == 6, ""); | |
109 EXPECT_EQ(arr, w.data()); | |
110 // ArrayView<char, 6> v = z; // Compile error, because can't drop const. | |
111 | |
112 // Copy fixed -> variable. | |
113 ArrayView<char> yv = x; // Copy non-const -> non-const. | |
114 EXPECT_EQ(6u, yv.size()); | |
115 EXPECT_EQ(arr, yv.data()); | |
116 ArrayView<const char> zv = x; // Copy non-const -> const. | |
117 EXPECT_EQ(6u, zv.size()); | |
118 EXPECT_EQ(arr, zv.data()); | |
119 ArrayView<const char> wv = z; // Copy const -> const. | |
120 EXPECT_EQ(6u, wv.size()); | |
121 EXPECT_EQ(arr, wv.data()); | |
122 // ArrayView<char> vv = z; // Compile error, because can't drop const. | |
123 } | |
124 | |
125 TEST(ArrayViewTest, TestCopyAssignmentVariable) { | |
126 char arr[] = "Arrr!"; | |
127 ArrayView<char> x(arr); | |
128 EXPECT_EQ(6u, x.size()); | |
129 EXPECT_EQ(arr, x.data()); | |
130 ArrayView<char> y; | |
131 y = x; // Copy non-const -> non-const. | |
132 EXPECT_EQ(6u, y.size()); | |
133 EXPECT_EQ(arr, y.data()); | |
134 ArrayView<const char> z; | |
135 z = x; // Copy non-const -> const. | |
136 EXPECT_EQ(6u, z.size()); | |
137 EXPECT_EQ(arr, z.data()); | |
138 ArrayView<const char> w; | |
139 w = z; // Copy const -> const. | |
140 EXPECT_EQ(6u, w.size()); | |
141 EXPECT_EQ(arr, w.data()); | |
142 // ArrayView<char> v; | |
143 // v = z; // Compile error, because can't drop const. | |
144 } | |
145 | |
146 TEST(ArrayViewTest, TestCopyAssignmentFixed) { | |
147 char arr[] = "Arrr!"; | |
148 char init[] = "Init!"; | |
149 ArrayView<char, 6> x(arr); | |
150 EXPECT_EQ(arr, x.data()); | |
151 | |
152 // Copy fixed -> fixed. | |
153 ArrayView<char, 6> y(init); | |
154 y = x; // Copy non-const -> non-const. | |
155 EXPECT_EQ(arr, y.data()); | |
156 ArrayView<const char, 6> z(init); | |
157 z = x; // Copy non-const -> const. | |
158 EXPECT_EQ(arr, z.data()); | |
159 ArrayView<const char, 6> w(init); | |
160 w = z; // Copy const -> const. | |
161 EXPECT_EQ(arr, w.data()); | |
162 // ArrayView<char, 6> v(init); | |
163 // v = z; // Compile error, because can't drop const. | |
164 | |
165 // Copy fixed -> variable. | |
166 ArrayView<char> yv; | |
167 yv = x; // Copy non-const -> non-const. | |
168 EXPECT_EQ(6u, yv.size()); | |
169 EXPECT_EQ(arr, yv.data()); | |
170 ArrayView<const char> zv; | |
171 zv = x; // Copy non-const -> const. | |
172 EXPECT_EQ(6u, zv.size()); | |
173 EXPECT_EQ(arr, zv.data()); | |
174 ArrayView<const char> wv; | |
175 wv = z; // Copy const -> const. | |
176 EXPECT_EQ(6u, wv.size()); | |
177 EXPECT_EQ(arr, wv.data()); | |
178 // ArrayView<char> v; | |
179 // v = z; // Compile error, because can't drop const. | |
180 } | |
181 | |
182 TEST(ArrayViewTest, TestStdVector) { | |
183 std::vector<int> v; | |
184 v.push_back(3); | |
185 v.push_back(11); | |
186 Call<const int>(v); | |
187 Call<int>(v); | |
188 // Call<unsigned int>(v); // Compile error, because incompatible types. | |
189 ArrayView<int> x = v; | |
190 EXPECT_EQ(2u, x.size()); | |
191 EXPECT_EQ(v.data(), x.data()); | |
192 ArrayView<const int> y; | |
193 y = v; | |
194 EXPECT_EQ(2u, y.size()); | |
195 EXPECT_EQ(v.data(), y.data()); | |
196 // ArrayView<double> d = v; // Compile error, because incompatible types. | |
197 const std::vector<int> cv; | |
198 Call<const int>(cv); | |
199 // Call<int>(cv); // Compile error, because can't drop const. | |
200 ArrayView<const int> z = cv; | |
201 EXPECT_EQ(0u, z.size()); | |
202 EXPECT_EQ(nullptr, z.data()); | |
203 // ArrayView<int> w = cv; // Compile error, because can't drop const. | |
204 } | |
205 | |
206 TEST(ArrayViewTest, TestRtcBuffer) { | |
207 rtc::Buffer b = "so buffer"; | |
208 Call<const uint8_t>(b); | |
209 Call<uint8_t>(b); | |
210 // Call<int8_t>(b); // Compile error, because incompatible types. | |
211 ArrayView<uint8_t> x = b; | |
212 EXPECT_EQ(10u, x.size()); | |
213 EXPECT_EQ(b.data(), x.data()); | |
214 ArrayView<const uint8_t> y; | |
215 y = b; | |
216 EXPECT_EQ(10u, y.size()); | |
217 EXPECT_EQ(b.data(), y.data()); | |
218 // ArrayView<char> d = b; // Compile error, because incompatible types. | |
219 const rtc::Buffer cb = "very const"; | |
220 Call<const uint8_t>(cb); | |
221 // Call<uint8_t>(cb); // Compile error, because can't drop const. | |
222 ArrayView<const uint8_t> z = cb; | |
223 EXPECT_EQ(11u, z.size()); | |
224 EXPECT_EQ(cb.data(), z.data()); | |
225 // ArrayView<uint8_t> w = cb; // Compile error, because can't drop const. | |
226 } | |
227 | |
228 TEST(ArrayViewTest, TestSwapVariable) { | |
229 const char arr[] = "Arrr!"; | |
230 const char aye[] = "Aye, Cap'n!"; | |
231 ArrayView<const char> x(arr); | |
232 EXPECT_EQ(6u, x.size()); | |
233 EXPECT_EQ(arr, x.data()); | |
234 ArrayView<const char> y(aye); | |
235 EXPECT_EQ(12u, y.size()); | |
236 EXPECT_EQ(aye, y.data()); | |
237 using std::swap; | |
238 swap(x, y); | |
239 EXPECT_EQ(12u, x.size()); | |
240 EXPECT_EQ(aye, x.data()); | |
241 EXPECT_EQ(6u, y.size()); | |
242 EXPECT_EQ(arr, y.data()); | |
243 // ArrayView<char> z; | |
244 // swap(x, z); // Compile error, because can't drop const. | |
245 } | |
246 | |
247 TEST(FixArrayViewTest, TestSwapFixed) { | |
248 const char arr[] = "Arr!"; | |
249 char aye[] = "Aye!"; | |
250 ArrayView<const char, 5> x(arr); | |
251 EXPECT_EQ(arr, x.data()); | |
252 ArrayView<const char, 5> y(aye); | |
253 EXPECT_EQ(aye, y.data()); | |
254 using std::swap; | |
255 swap(x, y); | |
256 EXPECT_EQ(aye, x.data()); | |
257 EXPECT_EQ(arr, y.data()); | |
258 // ArrayView<char, 5> z(aye); | |
259 // swap(x, z); // Compile error, because can't drop const. | |
260 // ArrayView<const char, 4> w(aye, 4); | |
261 // swap(x, w); // Compile error, because different sizes. | |
262 } | |
263 | |
264 TEST(ArrayViewTest, TestIndexing) { | |
265 char arr[] = "abcdefg"; | |
266 ArrayView<char> x(arr); | |
267 const ArrayView<char> y(arr); | |
268 ArrayView<const char, 8> z(arr); | |
269 EXPECT_EQ(8u, x.size()); | |
270 EXPECT_EQ(8u, y.size()); | |
271 EXPECT_EQ(8u, z.size()); | |
272 EXPECT_EQ('b', x[1]); | |
273 EXPECT_EQ('c', y[2]); | |
274 EXPECT_EQ('d', z[3]); | |
275 x[3] = 'X'; | |
276 y[2] = 'Y'; | |
277 // z[1] = 'Z'; // Compile error, because z's element type is const char. | |
278 EXPECT_EQ('b', x[1]); | |
279 EXPECT_EQ('Y', y[2]); | |
280 EXPECT_EQ('X', z[3]); | |
281 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
282 EXPECT_DEATH(z[8], ""); // DCHECK error (index out of bounds). | |
283 #endif | |
284 } | |
285 | |
286 TEST(ArrayViewTest, TestIterationEmpty) { | |
287 // Variable-size. | |
288 ArrayView<std::vector<std::vector<std::vector<std::string>>>> av; | |
289 EXPECT_EQ(av.begin(), av.end()); | |
290 EXPECT_EQ(av.cbegin(), av.cend()); | |
291 for (auto& e : av) { | |
292 EXPECT_TRUE(false); | |
293 EXPECT_EQ(42u, e.size()); // Dummy use of e to prevent unused var warning. | |
294 } | |
295 | |
296 // Fixed-size. | |
297 ArrayView<std::vector<std::vector<std::vector<std::string>>>, 0> af; | |
298 EXPECT_EQ(af.begin(), af.end()); | |
299 EXPECT_EQ(af.cbegin(), af.cend()); | |
300 for (auto& e : af) { | |
301 EXPECT_TRUE(false); | |
302 EXPECT_EQ(42u, e.size()); // Dummy use of e to prevent unused var warning. | |
303 } | |
304 } | |
305 | |
306 TEST(ArrayViewTest, TestIterationVariable) { | |
307 char arr[] = "Arrr!"; | |
308 ArrayView<char> av(arr); | |
309 EXPECT_EQ('A', *av.begin()); | |
310 EXPECT_EQ('A', *av.cbegin()); | |
311 EXPECT_EQ('\0', *(av.end() - 1)); | |
312 EXPECT_EQ('\0', *(av.cend() - 1)); | |
313 char i = 0; | |
314 for (auto& e : av) { | |
315 EXPECT_EQ(arr + i, &e); | |
316 e = 's' + i; | |
317 ++i; | |
318 } | |
319 i = 0; | |
320 for (auto& e : ArrayView<const char>(av)) { | |
321 EXPECT_EQ(arr + i, &e); | |
322 // e = 'q' + i; // Compile error, because e is a const char&. | |
323 ++i; | |
324 } | |
325 } | |
326 | |
327 TEST(ArrayViewTest, TestIterationFixed) { | |
328 char arr[] = "Arrr!"; | |
329 ArrayView<char, 6> av(arr); | |
330 EXPECT_EQ('A', *av.begin()); | |
331 EXPECT_EQ('A', *av.cbegin()); | |
332 EXPECT_EQ('\0', *(av.end() - 1)); | |
333 EXPECT_EQ('\0', *(av.cend() - 1)); | |
334 char i = 0; | |
335 for (auto& e : av) { | |
336 EXPECT_EQ(arr + i, &e); | |
337 e = 's' + i; | |
338 ++i; | |
339 } | |
340 i = 0; | |
341 for (auto& e : ArrayView<const char, 6>(av)) { | |
342 EXPECT_EQ(arr + i, &e); | |
343 // e = 'q' + i; // Compile error, because e is a const char&. | |
344 ++i; | |
345 } | |
346 } | |
347 | |
348 TEST(ArrayViewTest, TestEmpty) { | |
349 EXPECT_TRUE(ArrayView<int>().empty()); | |
350 const int a[] = {1, 2, 3}; | |
351 EXPECT_FALSE(ArrayView<const int>(a).empty()); | |
352 | |
353 static_assert(ArrayView<int, 0>::empty(), ""); | |
354 static_assert(!ArrayView<int, 3>::empty(), ""); | |
355 } | |
356 | |
357 TEST(ArrayViewTest, TestCompare) { | |
358 int a[] = {1, 2, 3}; | |
359 int b[] = {1, 2, 3}; | |
360 | |
361 EXPECT_EQ(ArrayView<int>(a), ArrayView<int>(a)); | |
362 EXPECT_EQ((ArrayView<int, 3>(a)), (ArrayView<int, 3>(a))); | |
363 EXPECT_EQ(ArrayView<int>(a), (ArrayView<int, 3>(a))); | |
364 EXPECT_EQ(ArrayView<int>(), ArrayView<int>()); | |
365 EXPECT_EQ(ArrayView<int>(), ArrayView<int>(a, 0)); | |
366 EXPECT_EQ(ArrayView<int>(a, 0), ArrayView<int>(b, 0)); | |
367 EXPECT_EQ((ArrayView<int, 0>(a, 0)), ArrayView<int>()); | |
368 | |
369 EXPECT_NE(ArrayView<int>(a), ArrayView<int>(b)); | |
370 EXPECT_NE((ArrayView<int, 3>(a)), (ArrayView<int, 3>(b))); | |
371 EXPECT_NE((ArrayView<int, 3>(a)), ArrayView<int>(b)); | |
372 EXPECT_NE(ArrayView<int>(a), ArrayView<int>()); | |
373 EXPECT_NE(ArrayView<int>(a), ArrayView<int>(a, 2)); | |
374 EXPECT_NE((ArrayView<int, 3>(a)), (ArrayView<int, 2>(a, 2))); | |
375 } | |
376 | |
377 TEST(ArrayViewTest, TestSubViewVariable) { | |
378 int a[] = {1, 2, 3}; | |
379 ArrayView<int> av(a); | |
380 | |
381 EXPECT_EQ(av.subview(0), av); | |
382 | |
383 EXPECT_THAT(av.subview(1), ElementsAre(2, 3)); | |
384 EXPECT_THAT(av.subview(2), ElementsAre(3)); | |
385 EXPECT_THAT(av.subview(3), IsEmpty()); | |
386 EXPECT_THAT(av.subview(4), IsEmpty()); | |
387 | |
388 EXPECT_THAT(av.subview(1, 0), IsEmpty()); | |
389 EXPECT_THAT(av.subview(1, 1), ElementsAre(2)); | |
390 EXPECT_THAT(av.subview(1, 2), ElementsAre(2, 3)); | |
391 EXPECT_THAT(av.subview(1, 3), ElementsAre(2, 3)); | |
392 } | |
393 | |
394 TEST(ArrayViewTest, TestSubViewFixed) { | |
395 int a[] = {1, 2, 3}; | |
396 ArrayView<int, 3> av(a); | |
397 | |
398 EXPECT_EQ(av.subview(0), av); | |
399 | |
400 EXPECT_THAT(av.subview(1), ElementsAre(2, 3)); | |
401 EXPECT_THAT(av.subview(2), ElementsAre(3)); | |
402 EXPECT_THAT(av.subview(3), IsEmpty()); | |
403 EXPECT_THAT(av.subview(4), IsEmpty()); | |
404 | |
405 EXPECT_THAT(av.subview(1, 0), IsEmpty()); | |
406 EXPECT_THAT(av.subview(1, 1), ElementsAre(2)); | |
407 EXPECT_THAT(av.subview(1, 2), ElementsAre(2, 3)); | |
408 EXPECT_THAT(av.subview(1, 3), ElementsAre(2, 3)); | |
409 } | |
410 | |
411 } // namespace rtc | |
OLD | NEW |