1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "include/core/SkRefCnt.h"
9 #include "include/core/SkSpan.h"
10 #include "include/private/base/SkTemplates.h"
11 #include "src/base/SkRandom.h"
12 #include "src/base/SkTSearch.h"
13 #include "src/base/SkTSort.h"
14 #include "src/base/SkZip.h"
15 #include "src/core/SkEnumerate.h"
16 #include "tests/Test.h"
17
18 #include <array>
19 #include <cstddef>
20 #include <cstdint>
21 #include <initializer_list>
22 #include <memory>
23 #include <new>
24 #include <tuple>
25 #include <utility>
26 #include <vector>
27
28 using namespace skia_private;
29
30 class RefClass : public SkRefCnt {
31 public:
RefClass(int n)32 RefClass(int n) : fN(n) {}
get() const33 int get() const { return fN; }
34
35 private:
36 int fN;
37
38 using INHERITED = SkRefCnt;
39 };
40
test_autounref(skiatest::Reporter * reporter)41 static void test_autounref(skiatest::Reporter* reporter) {
42 RefClass obj(0);
43 REPORTER_ASSERT(reporter, obj.unique());
44
45 sk_sp<RefClass> tmp(&obj);
46 REPORTER_ASSERT(reporter, &obj == tmp.get());
47 REPORTER_ASSERT(reporter, obj.unique());
48
49 REPORTER_ASSERT(reporter, &obj == tmp.release());
50 REPORTER_ASSERT(reporter, obj.unique());
51 REPORTER_ASSERT(reporter, nullptr == tmp.release());
52 REPORTER_ASSERT(reporter, nullptr == tmp.get());
53
54 obj.ref();
55 REPORTER_ASSERT(reporter, !obj.unique());
56 {
57 sk_sp<RefClass> tmp2(&obj);
58 }
59 REPORTER_ASSERT(reporter, obj.unique());
60 }
61
test_autostarray(skiatest::Reporter * reporter)62 static void test_autostarray(skiatest::Reporter* reporter) {
63 RefClass obj0(0);
64 RefClass obj1(1);
65 REPORTER_ASSERT(reporter, obj0.unique());
66 REPORTER_ASSERT(reporter, obj1.unique());
67
68 {
69 AutoSTArray<2, sk_sp<RefClass> > tmp;
70 REPORTER_ASSERT(reporter, 0 == tmp.count());
71
72 tmp.reset(0); // test out reset(0) when already at 0
73 tmp.reset(4); // this should force a new allocation
74 REPORTER_ASSERT(reporter, 4 == tmp.count());
75 tmp[0].reset(SkRef(&obj0));
76 tmp[1].reset(SkRef(&obj1));
77 REPORTER_ASSERT(reporter, !obj0.unique());
78 REPORTER_ASSERT(reporter, !obj1.unique());
79
80 // test out reset with data in the array (and a new allocation)
81 tmp.reset(0);
82 REPORTER_ASSERT(reporter, 0 == tmp.count());
83 REPORTER_ASSERT(reporter, obj0.unique());
84 REPORTER_ASSERT(reporter, obj1.unique());
85
86 tmp.reset(2); // this should use the preexisting allocation
87 REPORTER_ASSERT(reporter, 2 == tmp.count());
88 tmp[0].reset(SkRef(&obj0));
89 tmp[1].reset(SkRef(&obj1));
90 }
91
92 // test out destructor with data in the array (and using existing allocation)
93 REPORTER_ASSERT(reporter, obj0.unique());
94 REPORTER_ASSERT(reporter, obj1.unique());
95
96 {
97 // test out allocating ctor (this should allocate new memory)
98 AutoSTArray<2, sk_sp<RefClass> > tmp(4);
99 REPORTER_ASSERT(reporter, 4 == tmp.count());
100
101 tmp[0].reset(SkRef(&obj0));
102 tmp[1].reset(SkRef(&obj1));
103 REPORTER_ASSERT(reporter, !obj0.unique());
104 REPORTER_ASSERT(reporter, !obj1.unique());
105
106 // Test out resut with data in the array and malloced storage
107 tmp.reset(0);
108 REPORTER_ASSERT(reporter, obj0.unique());
109 REPORTER_ASSERT(reporter, obj1.unique());
110
111 tmp.reset(2); // this should use the preexisting storage
112 tmp[0].reset(SkRef(&obj0));
113 tmp[1].reset(SkRef(&obj1));
114 REPORTER_ASSERT(reporter, !obj0.unique());
115 REPORTER_ASSERT(reporter, !obj1.unique());
116
117 tmp.reset(4); // this should force a new malloc
118 REPORTER_ASSERT(reporter, obj0.unique());
119 REPORTER_ASSERT(reporter, obj1.unique());
120
121 tmp[0].reset(SkRef(&obj0));
122 tmp[1].reset(SkRef(&obj1));
123 REPORTER_ASSERT(reporter, !obj0.unique());
124 REPORTER_ASSERT(reporter, !obj1.unique());
125 }
126
127 REPORTER_ASSERT(reporter, obj0.unique());
128 REPORTER_ASSERT(reporter, obj1.unique());
129 }
130
131 /////////////////////////////////////////////////////////////////////////////
132
133 #define kSEARCH_COUNT 91
134
test_search(skiatest::Reporter * reporter)135 static void test_search(skiatest::Reporter* reporter) {
136 int i, array[kSEARCH_COUNT];
137 SkRandom rand;
138
139 for (i = 0; i < kSEARCH_COUNT; i++) {
140 array[i] = rand.nextS();
141 }
142
143 SkTHeapSort<int>(array, kSEARCH_COUNT);
144 // make sure we got sorted properly
145 for (i = 1; i < kSEARCH_COUNT; i++) {
146 REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
147 }
148
149 // make sure we can find all of our values
150 for (i = 0; i < kSEARCH_COUNT; i++) {
151 int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
152 REPORTER_ASSERT(reporter, index == i);
153 }
154
155 // make sure that random values are either found, or the correct
156 // insertion index is returned
157 for (i = 0; i < 10000; i++) {
158 int value = rand.nextS();
159 int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
160
161 if (index >= 0) {
162 REPORTER_ASSERT(reporter,
163 index < kSEARCH_COUNT && array[index] == value);
164 } else {
165 index = ~index;
166 REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
167 if (index < kSEARCH_COUNT) {
168 REPORTER_ASSERT(reporter, value < array[index]);
169 if (index > 0) {
170 REPORTER_ASSERT(reporter, value > array[index - 1]);
171 }
172 } else {
173 // we should append the new value
174 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
175 }
176 }
177 }
178 }
179
DEF_TEST(Utils,reporter)180 DEF_TEST(Utils, reporter) {
181 test_search(reporter);
182 test_autounref(reporter);
183 test_autostarray(reporter);
184 }
185
DEF_TEST(SkEnumerate,reporter)186 DEF_TEST(SkEnumerate, reporter) {
187
188 int A[] = {1, 2, 3, 4};
189 auto enumeration = SkMakeEnumerate(A);
190
191 size_t check = 0;
192 for (auto [i, v] : enumeration) {
193 REPORTER_ASSERT(reporter, i == check);
194 REPORTER_ASSERT(reporter, v == (int)check+1);
195
196 check++;
197 }
198
199 check = 0;
200 for (auto [i, v] : SkMakeEnumerate(A)) {
201 REPORTER_ASSERT(reporter, i == check);
202 REPORTER_ASSERT(reporter, v == (int)check+1);
203
204 check++;
205 }
206
207 check = 0;
208 std::vector<int> vec = {1, 2, 3, 4};
209 for (auto [i, v] : SkMakeEnumerate(vec)) {
210 REPORTER_ASSERT(reporter, i == check);
211 REPORTER_ASSERT(reporter, v == (int)check+1);
212 check++;
213 }
214 REPORTER_ASSERT(reporter, check == 4);
215
216 check = 0;
217 for (auto [i, v] : SkMakeEnumerate(SkSpan(vec))) {
218 REPORTER_ASSERT(reporter, i == check);
219 REPORTER_ASSERT(reporter, v == (int)check+1);
220 check++;
221 }
222
223 {
224 auto e = SkMakeEnumerate(SkSpan(vec)).first(2);
225 for (auto[i, v] : e) {
226 REPORTER_ASSERT(reporter, v == (int) i + 1);
227 }
228 REPORTER_ASSERT(reporter, e.size() == 2);
229 }
230
231 {
232 auto e = SkMakeEnumerate(SkSpan(vec)).last(2);
233 for (auto[i, v] : e) {
234 REPORTER_ASSERT(reporter, v == (int) i + 1);
235 }
236 REPORTER_ASSERT(reporter, e.size() == 2);
237 }
238
239 {
240 auto e = SkMakeEnumerate(SkSpan(vec)).subspan(1, 2);
241 for (auto[i, v] : e) {
242 REPORTER_ASSERT(reporter, v == (int) i + 1);
243 }
244 REPORTER_ASSERT(reporter, e.size() == 2);
245 }
246
247 {
248 struct I {
249 I() = default;
250 I(const I&) = default;
251 I(int v) : i{v} { }
252 ~I() {}
253 int i;
254 };
255
256 I is[10];
257 auto s = SkSpan(is);
258 for (auto [i, v] : SkMakeEnumerate(s)) {
259 new (&v) I(i);
260 }
261
262 for (size_t i = 0; i < s.size(); i++) {
263 REPORTER_ASSERT(reporter, s[i].i == (int)i);
264 REPORTER_ASSERT(reporter, is[i].i == (int)i);
265 }
266 }
267
268 {
269 std::unique_ptr<int> is[10];
270 std::unique_ptr<int> os[10];
271 auto s = SkSpan(is);
272 for (auto [i, v] : SkMakeEnumerate(s)) {
273 v = std::make_unique<int>(i);
274 }
275
276 for (auto [i, v] : SkMakeEnumerate(SkSpan(os))) {
277 v = std::move(s[i]);
278 }
279
280 for (size_t i = 0; i < s.size(); i++) {
281 REPORTER_ASSERT(reporter, *os[i] == (int)i);
282 REPORTER_ASSERT(reporter, is[i] == nullptr);
283 }
284 }
285
286 {
287 std::unique_ptr<int> is[10];
288 std::unique_ptr<int> os[10];
289 auto s = SkSpan(is);
290 for (auto [i, v] : SkMakeEnumerate(s)) {
291 v = std::make_unique<int>(i);
292 }
293
294 for (auto [i, ov, iv] : SkMakeEnumerate(SkMakeZip(os, is))) {
295 ov = std::move(iv);
296 }
297
298 for (size_t i = 0; i < s.size(); i++) {
299 REPORTER_ASSERT(reporter, *os[i] == (int)i);
300 REPORTER_ASSERT(reporter, is[i] == nullptr);
301 }
302 }
303 }
304
DEF_TEST(SkZip,reporter)305 DEF_TEST(SkZip, reporter) {
306 uint16_t A[] = {1, 2, 3, 4};
307 const float B[] = {10.f, 20.f, 30.f, 40.f};
308 std::vector<int> C = {{20, 30, 40, 50}};
309 std::array<int, 4> D = {{100, 200, 300, 400}};
310 SkSpan<int> S = SkSpan(C);
311
312 // Check SkZip calls
313 SkZip<uint16_t, const float, int, int, int>
314 z{4, &A[0], &B[0], C.data(), D.data(), S.data()};
315
316 REPORTER_ASSERT(reporter, z.size() == 4);
317 REPORTER_ASSERT(reporter, !z.empty());
318
319 {
320 // Check front
321 auto t = z.front();
322 REPORTER_ASSERT(reporter, std::get<0>(t) == 1);
323 REPORTER_ASSERT(reporter, std::get<1>(t) == 10.f);
324 REPORTER_ASSERT(reporter, std::get<2>(t) == 20);
325 REPORTER_ASSERT(reporter, std::get<3>(t) == 100);
326 REPORTER_ASSERT(reporter, std::get<4>(t) == 20);
327 }
328
329 {
330 // Check back
331 auto t = z.back();
332 REPORTER_ASSERT(reporter, std::get<0>(t) == 4);
333 REPORTER_ASSERT(reporter, std::get<1>(t) == 40.f);
334 }
335
336 {
337 // Check ranged-for
338 int i = 0;
339 for (auto [a, b, c, d, s] : z) {
340 REPORTER_ASSERT(reporter, a == A[i]);
341 REPORTER_ASSERT(reporter, b == B[i]);
342 REPORTER_ASSERT(reporter, c == C[i]);
343 REPORTER_ASSERT(reporter, d == D[i]);
344 REPORTER_ASSERT(reporter, s == S[i]);
345
346 i++;
347 }
348 REPORTER_ASSERT(reporter, i = 4);
349 }
350
351 {
352 // Check first(n)
353 int i = 0;
354 for (auto [a, b, c, d, s] : z.first(2)) {
355 REPORTER_ASSERT(reporter, a == A[i]);
356 REPORTER_ASSERT(reporter, b == B[i]);
357 REPORTER_ASSERT(reporter, c == C[i]);
358 REPORTER_ASSERT(reporter, d == D[i]);
359 REPORTER_ASSERT(reporter, s == S[i]);
360
361 i++;
362 }
363 REPORTER_ASSERT(reporter, i = 2);
364 }
365
366 {
367 // Check last(n)
368 int i = 0;
369 for (auto t : z.last(2)) {
370 uint16_t a; float b; int c; int d; int s;
371 std::tie(a, b, c, d, s) = t;
372 REPORTER_ASSERT(reporter, a == A[i + 2]);
373 REPORTER_ASSERT(reporter, b == B[i + 2]);
374 REPORTER_ASSERT(reporter, c == C[i + 2]);
375 REPORTER_ASSERT(reporter, d == D[i + 2]);
376 REPORTER_ASSERT(reporter, s == S[i + 2]);
377
378 i++;
379 }
380 REPORTER_ASSERT(reporter, i = 2);
381 }
382
383 {
384 // Check subspan(offset, count)
385 int i = 0;
386 for (auto t : z.subspan(1, 2)) {
387 uint16_t a; float b; int c; int d; int s;
388 std::tie(a, b, c, d, s) = t;
389 REPORTER_ASSERT(reporter, a == A[i + 1]);
390 REPORTER_ASSERT(reporter, b == B[i + 1]);
391 REPORTER_ASSERT(reporter, c == C[i + 1]);
392 REPORTER_ASSERT(reporter, d == D[i + 1]);
393 REPORTER_ASSERT(reporter, s == S[i + 1]);
394
395 i++;
396 }
397 REPORTER_ASSERT(reporter, i = 2);
398 }
399
400 {
401 // Check copy.
402 auto zz{z};
403 int i = 0;
404 for (auto [a, b, c, d, s] : zz) {
405 REPORTER_ASSERT(reporter, a == A[i]);
406 REPORTER_ASSERT(reporter, b == B[i]);
407 REPORTER_ASSERT(reporter, c == C[i]);
408 REPORTER_ASSERT(reporter, d == D[i]);
409 REPORTER_ASSERT(reporter, s == S[i]);
410
411 i++;
412 }
413 REPORTER_ASSERT(reporter, i = 4);
414 }
415
416 {
417 // Check const restricting copy
418 SkZip<const uint16_t, const float, const int, int, int> cz = z;
419 int i = 0;
420 for (auto [a, b, c, d, s] : cz) {
421 REPORTER_ASSERT(reporter, a == A[i]);
422 REPORTER_ASSERT(reporter, b == B[i]);
423 REPORTER_ASSERT(reporter, c == C[i]);
424 REPORTER_ASSERT(reporter, d == D[i]);
425 REPORTER_ASSERT(reporter, s == S[i]);
426
427 i++;
428 }
429 REPORTER_ASSERT(reporter, i = 4);
430 }
431
432 {
433 // Check data() returns all the original pointers
434 auto ptrs = z.data();
435 REPORTER_ASSERT(reporter,
436 ptrs == std::make_tuple(&A[0], &B[0], C.data(), D.data(), S.data()));
437 }
438
439 {
440 // Check index getter
441 auto span = z.get<1>();
442 REPORTER_ASSERT(reporter, span[1] == 20.f);
443 }
444
445 // The following mutates the data.
446 {
447 // Check indexing
448 auto [a, b, c, d, e] = z[1];
449 REPORTER_ASSERT(reporter, a == 2);
450 REPORTER_ASSERT(reporter, b == 20.f);
451 REPORTER_ASSERT(reporter, c == 30);
452 REPORTER_ASSERT(reporter, d == 200);
453 REPORTER_ASSERT(reporter, e == 30);
454
455 // Check correct refs returned.
456 REPORTER_ASSERT(reporter, &a == &A[1]);
457 REPORTER_ASSERT(reporter, &b == &B[1]);
458 REPORTER_ASSERT(reporter, &c == &C[1]);
459 REPORTER_ASSERT(reporter, &d == &D[1]);
460 REPORTER_ASSERT(reporter, &e == &S[1]);
461
462 // Check assignment
463 a = 20;
464 // std::get<1>(t) = 300.f; // is const
465 c = 300;
466 d = 2000;
467 e = 300;
468
469 auto t1 = z[1];
470 REPORTER_ASSERT(reporter, std::get<0>(t1) == 20);
471 REPORTER_ASSERT(reporter, std::get<1>(t1) == 20.f);
472 REPORTER_ASSERT(reporter, std::get<2>(t1) == 300);
473 REPORTER_ASSERT(reporter, std::get<3>(t1) == 2000);
474 REPORTER_ASSERT(reporter, std::get<4>(t1) == 300);
475 }
476 }
477
DEF_TEST(SkMakeZip,reporter)478 DEF_TEST(SkMakeZip, reporter) {
479 uint16_t A[] = {1, 2, 3, 4};
480 const float B[] = {10.f, 20.f, 30.f, 40.f};
481 const std::vector<int> C = {{20, 30, 40, 50}};
482 std::array<int, 4> D = {{100, 200, 300, 400}};
483 SkSpan<const int> S = SkSpan(C);
484 uint16_t* P = &A[0];
485 {
486 // Check make zip
487 auto zz = SkMakeZip(&A[0], B, C, D, S, P);
488
489 int i = 0;
490 for (auto [a, b, c, d, s, p] : zz) {
491 REPORTER_ASSERT(reporter, a == A[i]);
492 REPORTER_ASSERT(reporter, b == B[i]);
493 REPORTER_ASSERT(reporter, c == C[i]);
494 REPORTER_ASSERT(reporter, d == D[i]);
495 REPORTER_ASSERT(reporter, s == S[i]);
496 REPORTER_ASSERT(reporter, p == P[i]);
497
498 i++;
499 }
500 REPORTER_ASSERT(reporter, i = 4);
501 }
502
503 {
504 // Check SkMakeZip in ranged for check OneSize calc of B.
505 int i = 0;
506 for (auto [a, b, c, d, s] : SkMakeZip(&A[0], B, C, D, S)) {
507 REPORTER_ASSERT(reporter, a == A[i]);
508 REPORTER_ASSERT(reporter, b == B[i]);
509 REPORTER_ASSERT(reporter, c == C[i]);
510 REPORTER_ASSERT(reporter, d == D[i]);
511 REPORTER_ASSERT(reporter, s == S[i]);
512
513 i++;
514 }
515 REPORTER_ASSERT(reporter, i = 4);
516 }
517
518 {
519 // Check SkMakeZip in ranged for OneSize of C
520 int i = 0;
521 for (auto [a, b, c, d, s] : SkMakeZip(&A[0], &B[0], C, D, S)) {
522 REPORTER_ASSERT(reporter, a == A[i]);
523 REPORTER_ASSERT(reporter, b == B[i]);
524 REPORTER_ASSERT(reporter, c == C[i]);
525 REPORTER_ASSERT(reporter, d == D[i]);
526 REPORTER_ASSERT(reporter, s == S[i]);
527
528 i++;
529 }
530 REPORTER_ASSERT(reporter, i = 4);
531 }
532
533 {
534 // Check SkMakeZip in ranged for OneSize for S
535 int i = 0;
536 for (auto [s, a, b, c, d] : SkMakeZip(S, A, B, C, D)) {
537 REPORTER_ASSERT(reporter, a == A[i]);
538 REPORTER_ASSERT(reporter, b == B[i]);
539 REPORTER_ASSERT(reporter, c == C[i]);
540 REPORTER_ASSERT(reporter, d == D[i]);
541 REPORTER_ASSERT(reporter, s == S[i]);
542
543 i++;
544 }
545 REPORTER_ASSERT(reporter, i = 4);
546 }
547
548 {
549 // Check SkMakeZip in ranged for
550 int i = 0;
551 for (auto [c, s, a, b, d] : SkMakeZip(C, S, A, B, D)) {
552 REPORTER_ASSERT(reporter, a == A[i]);
553 REPORTER_ASSERT(reporter, b == B[i]);
554 REPORTER_ASSERT(reporter, c == C[i]);
555 REPORTER_ASSERT(reporter, d == D[i]);
556 REPORTER_ASSERT(reporter, s == S[i]);
557
558 i++;
559 }
560 REPORTER_ASSERT(reporter, i = 4);
561 }
562
563 {
564 // Check SkEnumerate and SkMakeZip in ranged for
565 auto zz = SkMakeZip(A, B, C, D, S);
566 for (auto [i, a, b, c, d, s] : SkMakeEnumerate(zz)) {
567 REPORTER_ASSERT(reporter, a == A[i]);
568 REPORTER_ASSERT(reporter, b == B[i]);
569 REPORTER_ASSERT(reporter, c == C[i]);
570 REPORTER_ASSERT(reporter, d == D[i]);
571 REPORTER_ASSERT(reporter, s == S[i]);
572 }
573 }
574
575 {
576 // Check SkEnumerate and SkMakeZip in ranged for
577 const auto& zz = SkMakeZip(A, B, C, D, S);
578 for (auto [i, a, b, c, d, s] : SkMakeEnumerate(zz)) {
579 REPORTER_ASSERT(reporter, a == A[i]);
580 REPORTER_ASSERT(reporter, b == B[i]);
581 REPORTER_ASSERT(reporter, c == C[i]);
582 REPORTER_ASSERT(reporter, d == D[i]);
583 REPORTER_ASSERT(reporter, s == S[i]);
584 }
585 }
586
587 {
588 // Check SkEnumerate and SkMakeZip in ranged for
589 for (auto [i, a, b, c, d, s] : SkMakeEnumerate(SkMakeZip(A, B, C, D, S))) {
590 REPORTER_ASSERT(reporter, a == A[i]);
591 REPORTER_ASSERT(reporter, b == B[i]);
592 REPORTER_ASSERT(reporter, c == C[i]);
593 REPORTER_ASSERT(reporter, d == D[i]);
594 REPORTER_ASSERT(reporter, s == S[i]);
595 }
596 }
597
598 {
599 std::vector<int>v;
600 auto z = SkMakeZip(v);
601 REPORTER_ASSERT(reporter, z.empty());
602 }
603
604 {
605 constexpr static uint16_t cA[] = {1, 2, 3, 4};
606 // Not constexpr in stdc++11 library.
607 //constexpr static std::array<int, 4> cD = {{100, 200, 300, 400}};
608 constexpr static const uint16_t* cP = &cA[0];
609 constexpr auto z = SkMakeZip(cA, cP);
610 REPORTER_ASSERT(reporter, !z.empty());
611 }
612 }
613