blob: 0e18e9f96daa851e14e6747d99e5f900b33f44a8 [file] [log] [blame]
bungeman@google.com95ebd172014-03-21 19:39:02 +00001/*
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
Florin Malitac2d5bd02017-03-09 13:34:09 -05008#include "SkRefCnt.h"
bungeman@google.com95ebd172014-03-21 19:39:02 +00009#include "SkTArray.h"
10#include "Test.h"
11
12// Tests the SkTArray<T> class template.
13
Brian Salomon69225d02017-03-15 20:52:35 -040014template <bool MEM_MOVE>
bungeman@google.com95ebd172014-03-21 19:39:02 +000015static void TestTSet_basic(skiatest::Reporter* reporter) {
Brian Salomon69225d02017-03-15 20:52:35 -040016 SkTArray<int, MEM_MOVE> a;
bungeman@google.com95ebd172014-03-21 19:39:02 +000017
18 // Starts empty.
19 REPORTER_ASSERT(reporter, a.empty());
20 REPORTER_ASSERT(reporter, a.count() == 0);
21
22 // { }, add a default constructed element
bungeman@google.com34ce63c2014-03-21 20:14:05 +000023 a.push_back() = 0;
bungeman@google.com95ebd172014-03-21 19:39:02 +000024 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
bungeman@google.com34ce63c2014-03-21 20:14:05 +000033 a.push_back() = 0;
bungeman@google.com95ebd172014-03-21 19:39:02 +000034 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
bungeman0d9e9be2016-04-20 10:22:20 -070062template <typename T> static void test_swap(skiatest::Reporter* reporter,
63 SkTArray<T>* (&arrays)[4],
64 int (&sizes)[7])
65{
mtklein86211002016-03-03 09:48:53 -080066 for (auto a : arrays) {
67 for (auto b : arrays) {
68 if (a == b) {
69 continue;
bsalomon3632f842015-02-10 19:46:58 -080070 }
mtklein86211002016-03-03 09:48:53 -080071
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;
bungeman0d9e9be2016-04-20 10:22:20 -070086 for (auto&& x : *b) { REPORTER_ASSERT(reporter, x == curr++); }
87 for (auto&& x : *a) { REPORTER_ASSERT(reporter, x == curr++); }
mtklein86211002016-03-03 09:48:53 -080088
89 a->swap(a);
90 curr = sizeA;
bungeman0d9e9be2016-04-20 10:22:20 -070091 for (auto&& x : *a) { REPORTER_ASSERT(reporter, x == curr++); }
mtklein86211002016-03-03 09:48:53 -080092 }}
93 }}
bsalomon3632f842015-02-10 19:46:58 -080094}
95
bungeman0d9e9be2016-04-20 10:22:20 -070096static 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
Florin Malitac2d5bd02017-03-09 13:34:09 -0500121template <typename T, bool MEM_MOVE>
122void 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
Florin Malitad54639f2017-03-12 10:40:13 -0400141static 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
Brian Salomon69225d02017-03-15 20:52:35 -0400222template <typename T, bool MEM_MOVE> int SkTArray<T, MEM_MOVE>::allocCntForTest() const {
223 return fAllocCount;
224}
225
226void 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
Greg Daniel70131b92017-03-22 13:33:21 -0400284static 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
bungeman@google.com95ebd172014-03-21 19:39:02 +0000297DEF_TEST(TArray, reporter) {
298 TestTSet_basic<true>(reporter);
299 TestTSet_basic<false>(reporter);
bsalomon3632f842015-02-10 19:46:58 -0800300 test_swap(reporter);
Florin Malitac2d5bd02017-03-09 13:34:09 -0500301
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>());
Florin Malitad54639f2017-03-12 10:40:13 -0400308
309 test_move(reporter);
Brian Salomon69225d02017-03-15 20:52:35 -0400310
311 test_unnecessary_alloc(reporter);
Greg Daniel70131b92017-03-22 13:33:21 -0400312
313 test_self_assignment(reporter);
bungeman@google.com95ebd172014-03-21 19:39:02 +0000314}