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