• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 "SkRefCnt.h"
9 #include "SkTArray.h"
10 #include "Test.h"
11 
12 // Tests the SkTArray<T> class template.
13 
14 template <bool MEM_MOVE>
TestTSet_basic(skiatest::Reporter * reporter)15 static void TestTSet_basic(skiatest::Reporter* reporter) {
16     SkTArray<int, MEM_MOVE> a;
17 
18     // Starts empty.
19     REPORTER_ASSERT(reporter, a.empty());
20     REPORTER_ASSERT(reporter, a.count() == 0);
21 
22     // { }, add a default constructed element
23     a.push_back() = 0;
24     REPORTER_ASSERT(reporter, !a.empty());
25     REPORTER_ASSERT(reporter, a.count() == 1);
26 
27     // { 0 }, removeShuffle the only element.
28     a.removeShuffle(0);
29     REPORTER_ASSERT(reporter, a.empty());
30     REPORTER_ASSERT(reporter, a.count() == 0);
31 
32     // { }, add a default, add a 1, remove first
33     a.push_back() = 0;
34     REPORTER_ASSERT(reporter, a.push_back() = 1);
35     a.removeShuffle(0);
36     REPORTER_ASSERT(reporter, !a.empty());
37     REPORTER_ASSERT(reporter, a.count() == 1);
38     REPORTER_ASSERT(reporter, a[0] == 1);
39 
40     // { 1 }, replace with new array
41     int b[5] = { 0, 1, 2, 3, 4 };
42     a.reset(b, SK_ARRAY_COUNT(b));
43     REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b));
44     REPORTER_ASSERT(reporter, a[2] == 2);
45     REPORTER_ASSERT(reporter, a[4] == 4);
46 
47     // { 0, 1, 2, 3, 4 }, removeShuffle the last
48     a.removeShuffle(4);
49     REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b) - 1);
50     REPORTER_ASSERT(reporter, a[3] == 3);
51 
52     // { 0, 1, 2, 3 }, remove a middle, note shuffle
53     a.removeShuffle(1);
54     REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b) - 2);
55     REPORTER_ASSERT(reporter, a[0] == 0);
56     REPORTER_ASSERT(reporter, a[1] == 3);
57     REPORTER_ASSERT(reporter, a[2] == 2);
58 
59     // {0, 3, 2 }
60 }
61 
test_swap(skiatest::Reporter * reporter,SkTArray<T> * (& arrays)[4],int (& sizes)[7])62 template <typename T> static void test_swap(skiatest::Reporter* reporter,
63                                             SkTArray<T>* (&arrays)[4],
64                                             int (&sizes)[7])
65 {
66     for (auto a : arrays) {
67     for (auto b : arrays) {
68         if (a == b) {
69             continue;
70         }
71 
72         for (auto sizeA : sizes) {
73         for (auto sizeB : sizes) {
74             a->reset();
75             b->reset();
76 
77             int curr = 0;
78             for (int i = 0; i < sizeA; i++) { a->push_back(curr++); }
79             for (int i = 0; i < sizeB; i++) { b->push_back(curr++); }
80 
81             a->swap(b);
82             REPORTER_ASSERT(reporter, b->count() == sizeA);
83             REPORTER_ASSERT(reporter, a->count() == sizeB);
84 
85             curr = 0;
86             for (auto&& x : *b) { REPORTER_ASSERT(reporter, x == curr++); }
87             for (auto&& x : *a) { REPORTER_ASSERT(reporter, x == curr++); }
88 
89             a->swap(a);
90             curr = sizeA;
91             for (auto&& x : *a) { REPORTER_ASSERT(reporter, x == curr++); }
92         }}
93     }}
94 }
95 
test_swap(skiatest::Reporter * reporter)96 static void test_swap(skiatest::Reporter* reporter) {
97     int sizes[] = {0, 1, 5, 10, 15, 20, 25};
98 
99     SkTArray<int> arr;
100     SkSTArray< 5, int> arr5;
101     SkSTArray<10, int> arr10;
102     SkSTArray<20, int> arr20;
103     SkTArray<int>* arrays[] = { &arr, &arr5, &arr10, &arr20 };
104     test_swap(reporter, arrays, sizes);
105 
106     struct MoveOnlyInt {
107         MoveOnlyInt(int i) : fInt(i) {}
108         MoveOnlyInt(MoveOnlyInt&& that) : fInt(that.fInt) {}
109         bool operator==(int i) { return fInt == i; }
110         int fInt;
111     };
112 
113     SkTArray<MoveOnlyInt> moi;
114     SkSTArray< 5, MoveOnlyInt> moi5;
115     SkSTArray<10, MoveOnlyInt> moi10;
116     SkSTArray<20, MoveOnlyInt> moi20;
117     SkTArray<MoveOnlyInt>* arraysMoi[] = { &moi, &moi5, &moi10, &moi20 };
118     test_swap(reporter, arraysMoi, sizes);
119 }
120 
121 template <typename T, bool MEM_MOVE>
test_copy_ctor(skiatest::Reporter * reporter,SkTArray<T,MEM_MOVE> && array)122 void test_copy_ctor(skiatest::Reporter* reporter, SkTArray<T, MEM_MOVE>&& array) {
123     SkASSERT(array.empty());
124     for (int i = 0; i < 5; ++i) {
125         array.emplace_back(new SkRefCnt);
126         REPORTER_ASSERT(reporter, array.back()->unique());
127     }
128 
129     {
130         SkTArray<T, MEM_MOVE> copy(array);
131         for (const auto& ref : array)
132             REPORTER_ASSERT(reporter, !ref->unique());
133         for (const auto& ref : copy)
134             REPORTER_ASSERT(reporter, !ref->unique());
135     }
136 
137     for (const auto& ref : array)
138         REPORTER_ASSERT(reporter, ref->unique());
139 }
140 
test_move(skiatest::Reporter * reporter)141 static void test_move(skiatest::Reporter* reporter) {
142 #define TEST_MOVE do {                                 \
143     SRC_T src;                                         \
144     src.emplace_back(sk_make_sp<SkRefCnt>());          \
145     {                                                  \
146         /* copy ctor */                                \
147         DST_T copy(src);                               \
148         REPORTER_ASSERT(reporter, !copy[0]->unique()); \
149     }                                                  \
150     {                                                  \
151         /* move ctor */                                \
152         DST_T move(std::move(src));                    \
153         REPORTER_ASSERT(reporter, move[0]->unique());  \
154     }                                                  \
155     REPORTER_ASSERT(reporter, src.empty());            \
156     src.emplace_back(sk_make_sp<SkRefCnt>());          \
157     {                                                  \
158         /* copy assignment */                          \
159         DST_T copy;                                    \
160         copy = src;                                    \
161         REPORTER_ASSERT(reporter, !copy[0]->unique()); \
162     }                                                  \
163     {                                                  \
164         /* move assignment */                          \
165         DST_T move;                                    \
166         move = std::move(src);                         \
167         REPORTER_ASSERT(reporter, move[0]->unique());  \
168     }                                                  \
169     REPORTER_ASSERT(reporter, src.empty());            \
170 } while (false)
171 
172     {
173         using SRC_T = SkTArray<sk_sp<SkRefCnt>, false>;
174         using DST_T = SkTArray<sk_sp<SkRefCnt>, false>;
175         TEST_MOVE;
176     }
177 
178     {
179         using SRC_T = SkTArray<sk_sp<SkRefCnt>, true>;
180         using DST_T = SkTArray<sk_sp<SkRefCnt>, true>;
181         TEST_MOVE;
182     }
183 
184     {
185         using SRC_T = SkSTArray<1, sk_sp<SkRefCnt>, false>;
186         using DST_T = SkSTArray<1, sk_sp<SkRefCnt>, false>;
187         TEST_MOVE;
188     }
189 
190     {
191         using SRC_T = SkSTArray<1, sk_sp<SkRefCnt>, true>;
192         using DST_T = SkSTArray<1, sk_sp<SkRefCnt>, true>;
193         TEST_MOVE;
194     }
195 
196     {
197         using SRC_T = SkTArray<sk_sp<SkRefCnt>, false>;
198         using DST_T = SkSTArray<1, sk_sp<SkRefCnt>, false>;
199         TEST_MOVE;
200     }
201 
202     {
203         using SRC_T = SkTArray<sk_sp<SkRefCnt>, true>;
204         using DST_T = SkSTArray<1, sk_sp<SkRefCnt>, true>;
205         TEST_MOVE;
206     }
207 
208     {
209         using SRC_T = SkSTArray<1, sk_sp<SkRefCnt>, false>;
210         using DST_T = SkTArray<sk_sp<SkRefCnt>, false>;
211         TEST_MOVE;
212     }
213 
214     {
215         using SRC_T = SkSTArray<1, sk_sp<SkRefCnt>, true>;
216         using DST_T = SkTArray<sk_sp<SkRefCnt>, true>;
217         TEST_MOVE;
218     }
219 #undef TEST_MOVE
220 }
221 
allocCntForTest() const222 template <typename T, bool MEM_MOVE> int SkTArray<T, MEM_MOVE>::allocCntForTest() const {
223     return fAllocCount;
224 }
225 
test_unnecessary_alloc(skiatest::Reporter * reporter)226 void test_unnecessary_alloc(skiatest::Reporter* reporter) {
227     {
228         SkTArray<int> a;
229         REPORTER_ASSERT(reporter, a.allocCntForTest() == 0);
230     }
231     {
232         SkSTArray<10, int> a;
233         REPORTER_ASSERT(reporter, a.allocCntForTest() == 10);
234     }
235     {
236         SkTArray<int> a(1);
237         REPORTER_ASSERT(reporter, a.allocCntForTest() >= 1);
238     }
239     {
240         SkTArray<int> a, b;
241         b = a;
242         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
243     }
244     {
245         SkSTArray<10, int> a;
246         SkTArray<int> b;
247         b = a;
248         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
249     }
250     {
251         SkTArray<int> a;
252         SkTArray<int> b(a);
253         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
254     }
255     {
256         SkSTArray<10, int> a;
257         SkTArray<int> b(a);
258         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
259     }
260     {
261         SkTArray<int> a;
262         SkTArray<int> b(std::move(a));
263         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
264     }
265     {
266         SkSTArray<10, int> a;
267         SkTArray<int> b(std::move(a));
268         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
269     }
270     {
271         SkTArray<int> a;
272         SkTArray<int> b;
273         b = std::move(a);
274         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
275     }
276     {
277         SkSTArray<10, int> a;
278         SkTArray<int> b;
279         b = std::move(a);
280         REPORTER_ASSERT(reporter, b.allocCntForTest() == 0);
281     }
282 }
283 
test_self_assignment(skiatest::Reporter * reporter)284 static void test_self_assignment(skiatest::Reporter* reporter) {
285     SkTArray<int> a;
286     a.push_back(1);
287     REPORTER_ASSERT(reporter, !a.empty());
288     REPORTER_ASSERT(reporter, a.count() == 1);
289     REPORTER_ASSERT(reporter, a[0] == 1);
290 
291     a = a;
292     REPORTER_ASSERT(reporter, !a.empty());
293     REPORTER_ASSERT(reporter, a.count() == 1);
294     REPORTER_ASSERT(reporter, a[0] == 1);
295 }
296 
DEF_TEST(TArray,reporter)297 DEF_TEST(TArray, reporter) {
298     TestTSet_basic<true>(reporter);
299     TestTSet_basic<false>(reporter);
300     test_swap(reporter);
301 
302     test_copy_ctor(reporter, SkTArray<sk_sp<SkRefCnt>, false>());
303     test_copy_ctor(reporter, SkTArray<sk_sp<SkRefCnt>,  true>());
304     test_copy_ctor(reporter, SkSTArray< 1, sk_sp<SkRefCnt>, false>());
305     test_copy_ctor(reporter, SkSTArray< 1, sk_sp<SkRefCnt>,  true>());
306     test_copy_ctor(reporter, SkSTArray<10, sk_sp<SkRefCnt>, false>());
307     test_copy_ctor(reporter, SkSTArray<10, sk_sp<SkRefCnt>,  true>());
308 
309     test_move(reporter);
310 
311     test_unnecessary_alloc(reporter);
312 
313     test_self_assignment(reporter);
314 }
315