• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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