| |
1 /* |
| |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
| |
3 * |
| |
4 * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved. |
| |
5 * |
| |
6 * Redistribution and use in source and binary forms, with or without |
| |
7 * modification, are permitted provided that the following conditions are met: |
| |
8 * |
| |
9 * 1. Redistributions of source code must retain the above copyright |
| |
10 * notice, this list of conditions and the following disclaimer. |
| |
11 * |
| |
12 * 2. Redistributions in binary form must reproduce the above copyright |
| |
13 * notice, this list of conditions and the following disclaimer in the |
| |
14 * documentation and/or other materials provided with the distribution. |
| |
15 * |
| |
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| |
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| |
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| |
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| |
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| |
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| |
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| |
26 * POSSIBILITY OF SUCH DAMAGE. |
| |
27 */ |
| |
28 |
| |
29 #include "array_tests.h" |
| |
30 #include <ucx/utils.h> |
| |
31 |
| |
32 UCX_TEST(test_ucx_array_destroy) { |
| |
33 UcxArray array; |
| |
34 ucx_array_init(&array, 16, sizeof(int)); |
| |
35 |
| |
36 UCX_TEST_BEGIN |
| |
37 ucx_array_destroy(&array); |
| |
38 UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after destroy"); |
| |
39 UCX_TEST_ASSERT(array.size == 0, "size not zero after destroy"); |
| |
40 UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after destroy"); |
| |
41 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(), |
| |
42 "allocator corrupted during destroy"); |
| |
43 UCX_TEST_END |
| |
44 } |
| |
45 |
| |
46 UCX_TEST(test_ucx_array_new) { |
| |
47 UcxArray* array = ucx_array_new(16, 47); |
| |
48 |
| |
49 UCX_TEST_BEGIN |
| |
50 UCX_TEST_ASSERT(array->data, "no memory allocated"); |
| |
51 UCX_TEST_ASSERT(array->size == 0, "size not initially zero"); |
| |
52 UCX_TEST_ASSERT(array->capacity == 16, "capacity not as requested"); |
| |
53 UCX_TEST_ASSERT(array->elemsize == 47, "element size not as requested"); |
| |
54 UCX_TEST_ASSERT(array->allocator == ucx_default_allocator(), |
| |
55 "array not using the default allocator"); |
| |
56 UCX_TEST_END |
| |
57 ucx_array_free(array); |
| |
58 } |
| |
59 |
| |
60 UCX_TEST(test_ucx_array_append_from) { |
| |
61 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
62 int *elements; |
| |
63 |
| |
64 int x = 42; |
| |
65 ucx_array_append_from(array, &x, 1); |
| |
66 UCX_TEST_BEGIN |
| |
67 |
| |
68 elements = array->data; |
| |
69 UCX_TEST_ASSERT(elements[0] == 42, "failed"); |
| |
70 |
| |
71 int y[2] = {13, 37}; |
| |
72 ucx_array_append_from(array, y, 2); |
| |
73 |
| |
74 elements = array->data; |
| |
75 UCX_TEST_ASSERT(array->size == 3, "incorrect size after append"); |
| |
76 UCX_TEST_ASSERT(elements[1] == 13, "failed"); |
| |
77 UCX_TEST_ASSERT(elements[2] == 37, "failed"); |
| |
78 UCX_TEST_ASSERT(elements[0] == 42, |
| |
79 "append corrupted previously inserted data"); |
| |
80 |
| |
81 ucx_array_append_from(array, NULL, 2); |
| |
82 |
| |
83 elements = array->data; |
| |
84 UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL append"); |
| |
85 UCX_TEST_ASSERT(elements[3] == 0, "element is not zeroed"); |
| |
86 UCX_TEST_ASSERT(elements[4] == 0, "element is not zeroed"); |
| |
87 UCX_TEST_ASSERT(elements[0] == 42, |
| |
88 "NULL append corrupted previously inserted data"); |
| |
89 UCX_TEST_ASSERT(elements[1] == 13, |
| |
90 "NULL append corrupted previously inserted data"); |
| |
91 UCX_TEST_ASSERT(elements[2] == 37, |
| |
92 "NULL append corrupted previously inserted data"); |
| |
93 |
| |
94 UCX_TEST_END |
| |
95 |
| |
96 ucx_array_free(array); |
| |
97 } |
| |
98 |
| |
99 UCX_TEST(test_ucx_array_prepend_from) { |
| |
100 int *elems; |
| |
101 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
102 |
| |
103 int x = 42; |
| |
104 ucx_array_prepend_from(array, &x, 1); |
| |
105 UCX_TEST_BEGIN |
| |
106 |
| |
107 elems = array->data; |
| |
108 UCX_TEST_ASSERT(elems[0] == 42, "failed"); |
| |
109 |
| |
110 int y[2] = {13, 37}; |
| |
111 ucx_array_prepend_from(array, y, 2); |
| |
112 |
| |
113 elems = array->data; |
| |
114 UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend"); |
| |
115 UCX_TEST_ASSERT(elems[0] == 13, "failed"); |
| |
116 UCX_TEST_ASSERT(elems[1] == 37, "failed"); |
| |
117 UCX_TEST_ASSERT(elems[2] == 42, |
| |
118 "prepend corrupted previously inserted data"); |
| |
119 |
| |
120 ucx_array_prepend_from(array, NULL, 2); |
| |
121 |
| |
122 elems = array->data; |
| |
123 UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL prepend"); |
| |
124 UCX_TEST_ASSERT(elems[0] == 0, "element is not zeroed"); |
| |
125 UCX_TEST_ASSERT(elems[1] == 0, "element is not zeroed"); |
| |
126 UCX_TEST_ASSERT(elems[2] == 13, |
| |
127 "NULL prepend corrupted previously inserted data"); |
| |
128 UCX_TEST_ASSERT(elems[3] == 37, |
| |
129 "NULL prepend corrupted previously inserted data"); |
| |
130 UCX_TEST_ASSERT(elems[4] == 42, |
| |
131 "NULL prepend corrupted previously inserted data"); |
| |
132 |
| |
133 UCX_TEST_END |
| |
134 |
| |
135 ucx_array_free(array); |
| |
136 } |
| |
137 |
| |
138 UCX_TEST(test_ucx_array_set_from) { |
| |
139 int *elems; |
| |
140 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
141 |
| |
142 int x = 42; |
| |
143 |
| |
144 UCX_TEST_BEGIN |
| |
145 |
| |
146 ucx_array_set_from(array, 7, &x, 1); |
| |
147 |
| |
148 elems = array->data; |
| |
149 UCX_TEST_ASSERT(elems[7] == 42, "failed"); |
| |
150 UCX_TEST_ASSERT(array->size >= 8, "array not resized on set"); |
| |
151 UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily"); |
| |
152 |
| |
153 int y[2] = {13, 37}; |
| |
154 ucx_array_set_from(array, 27, y, 2); |
| |
155 |
| |
156 elems = array->data; |
| |
157 UCX_TEST_ASSERT(elems[27] == 13, "failed"); |
| |
158 UCX_TEST_ASSERT(elems[28] == 37, "failed"); |
| |
159 UCX_TEST_ASSERT(array->size == 29, "array not resized on set"); |
| |
160 UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown"); |
| |
161 |
| |
162 ucx_array_set_from(array, 7, NULL, 2); |
| |
163 |
| |
164 elems = array->data; |
| |
165 UCX_TEST_ASSERT(elems[7] == 0, "not zeroed on NULL set"); |
| |
166 UCX_TEST_ASSERT(elems[8] == 0, "not zeroed on NULL set"); |
| |
167 |
| |
168 UCX_TEST_END |
| |
169 |
| |
170 ucx_array_free(array); |
| |
171 } |
| |
172 |
| |
173 UCX_TEST(test_ucx_array_append) { |
| |
174 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
175 int *elements; |
| |
176 |
| |
177 ucx_array_append(array, 42); |
| |
178 UCX_TEST_BEGIN |
| |
179 |
| |
180 elements = array->data; |
| |
181 UCX_TEST_ASSERT(elements[0] == 42, "failed"); |
| |
182 |
| |
183 ucx_array_append(array, 13); |
| |
184 ucx_array_append(array, 37); |
| |
185 |
| |
186 elements = array->data; |
| |
187 UCX_TEST_ASSERT(array->size == 3, "incorrect size after append"); |
| |
188 UCX_TEST_ASSERT(elements[1] == 13, "failed"); |
| |
189 UCX_TEST_ASSERT(elements[2] == 37, "failed"); |
| |
190 UCX_TEST_ASSERT(elements[0] == 42, |
| |
191 "append corrupted previously inserted data"); |
| |
192 |
| |
193 UCX_TEST_END |
| |
194 |
| |
195 ucx_array_destroy(array); |
| |
196 } |
| |
197 |
| |
198 UCX_TEST(test_ucx_array_prepend) { |
| |
199 int *elems; |
| |
200 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
201 |
| |
202 ucx_array_prepend(array, 42); |
| |
203 UCX_TEST_BEGIN |
| |
204 |
| |
205 elems = array->data; |
| |
206 UCX_TEST_ASSERT(elems[0] == 42, "failed"); |
| |
207 |
| |
208 ucx_array_prepend(array, 37); |
| |
209 ucx_array_prepend(array, 13); |
| |
210 |
| |
211 elems = array->data; |
| |
212 UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend"); |
| |
213 UCX_TEST_ASSERT(elems[0] == 13, "failed"); |
| |
214 UCX_TEST_ASSERT(elems[1] == 37, "failed"); |
| |
215 UCX_TEST_ASSERT(elems[2] == 42, |
| |
216 "prepend corrupted previously inserted data"); |
| |
217 |
| |
218 UCX_TEST_END |
| |
219 |
| |
220 ucx_array_free(array); |
| |
221 } |
| |
222 |
| |
223 UCX_TEST(test_ucx_array_set) { |
| |
224 int *elems; |
| |
225 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
226 |
| |
227 UCX_TEST_BEGIN |
| |
228 |
| |
229 ucx_array_set(array, 7, 42); |
| |
230 |
| |
231 elems = array->data; |
| |
232 UCX_TEST_ASSERT(elems[7] == 42, "failed"); |
| |
233 UCX_TEST_ASSERT(array->size == 8, "array not resized on set"); |
| |
234 UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily"); |
| |
235 |
| |
236 ucx_array_set(array, 27, 13); |
| |
237 ucx_array_set(array, 28, 37); |
| |
238 |
| |
239 elems = array->data; |
| |
240 UCX_TEST_ASSERT(elems[27] == 13, "failed"); |
| |
241 UCX_TEST_ASSERT(elems[28] == 37, "failed"); |
| |
242 UCX_TEST_ASSERT(array->size == 29, "array not resized on set"); |
| |
243 UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown"); |
| |
244 |
| |
245 UCX_TEST_END |
| |
246 |
| |
247 ucx_array_free(array); |
| |
248 } |
| |
249 |
| |
250 UCX_TEST(test_ucx_array_equals) { |
| |
251 UcxArray *a1 = ucx_array_new(16, sizeof(int32_t)); |
| |
252 UcxArray *a2 = ucx_array_new(16, sizeof(int32_t)); |
| |
253 UcxArray *a3 = ucx_array_new(16, sizeof(int64_t)); |
| |
254 UcxArray *a4 = ucx_array_new(16, sizeof(int32_t)); |
| |
255 |
| |
256 int32_t *intelems; |
| |
257 int64_t *longintelems; |
| |
258 |
| |
259 a1->size = 5; |
| |
260 intelems = a1->data; |
| |
261 intelems[0] = 47; |
| |
262 intelems[1] = 11; |
| |
263 intelems[2] = 0; |
| |
264 intelems[3] = 8; |
| |
265 intelems[4] = 15; |
| |
266 a2->size = 5; |
| |
267 intelems = a2->data; |
| |
268 intelems[0] = 47; |
| |
269 intelems[1] = 11; |
| |
270 intelems[2] = 0; |
| |
271 intelems[3] = 8; |
| |
272 intelems[4] = 15; |
| |
273 a3->size = 5; |
| |
274 longintelems = a3->data; |
| |
275 longintelems[0] = 47; |
| |
276 longintelems[1] = 11; |
| |
277 longintelems[2] = 0; |
| |
278 longintelems[3] = 8; |
| |
279 longintelems[4] = 15; |
| |
280 a4->size = 5; |
| |
281 intelems = a4->data; |
| |
282 intelems[0] = 47; |
| |
283 intelems[1] = 11; |
| |
284 intelems[2] = -6; |
| |
285 intelems[3] = 8; |
| |
286 intelems[4] = 15; |
| |
287 |
| |
288 UCX_TEST_BEGIN |
| |
289 |
| |
290 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, ucx_cmp_int32, NULL), "failed"); |
| |
291 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, ucx_cmp_int32, NULL), "failed"); |
| |
292 UCX_TEST_ASSERT(!ucx_array_equals(a4, a1, ucx_cmp_int32, NULL), "failed"); |
| |
293 UCX_TEST_ASSERT(!ucx_array_equals(a1, a3, ucx_cmp_int64, NULL), |
| |
294 "comparing arrays of different element size shall fail"); |
| |
295 UCX_TEST_ASSERT(!ucx_array_equals(a3, a1, ucx_cmp_int64, NULL), |
| |
296 "comparing arrays of different element size shall fail"); |
| |
297 |
| |
298 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, NULL, NULL), |
| |
299 "compare using memcmp() failed"); |
| |
300 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, NULL, NULL), |
| |
301 "compare using memcmp() failed"); |
| |
302 |
| |
303 UCX_TEST_END |
| |
304 ucx_array_free(a1); |
| |
305 ucx_array_free(a2); |
| |
306 ucx_array_free(a3); |
| |
307 ucx_array_free(a4); |
| |
308 } |
| |
309 |
| |
310 UCX_TEST(test_ucx_array_concat) { |
| |
311 UcxArray *a1 = ucx_array_new(16, sizeof(int)); |
| |
312 UcxArray *a2 = ucx_array_new(16, sizeof(int)); |
| |
313 int *elems; |
| |
314 |
| |
315 a1->size = 2; |
| |
316 elems = a1->data; |
| |
317 elems[0] = 47; |
| |
318 elems[1] = 11; |
| |
319 a2->size = 3; |
| |
320 elems = a2->data; |
| |
321 elems[0] = 0; |
| |
322 elems[1] = 8; |
| |
323 elems[2] = 15; |
| |
324 |
| |
325 UCX_TEST_BEGIN |
| |
326 |
| |
327 UCX_TEST_ASSERT(!ucx_array_concat(a1, a2), "failed"); |
| |
328 UCX_TEST_ASSERT(a1->size == 5, "failed"); |
| |
329 elems = a1->data; |
| |
330 UCX_TEST_ASSERT(elems[0] == 47, "failed"); |
| |
331 UCX_TEST_ASSERT(elems[1] == 11, "failed"); |
| |
332 UCX_TEST_ASSERT(elems[2] == 0, "failed"); |
| |
333 UCX_TEST_ASSERT(elems[3] == 8, "failed"); |
| |
334 UCX_TEST_ASSERT(elems[4] == 15, "failed"); |
| |
335 |
| |
336 a1->elemsize *= 2; |
| |
337 UCX_TEST_ASSERT(ucx_array_concat(a1, a2), |
| |
338 "arrays of different element size must not be concatenated"); |
| |
339 UCX_TEST_ASSERT(a1->size == 5, |
| |
340 "arrays of different element size must not be concatenated"); |
| |
341 |
| |
342 UCX_TEST_END |
| |
343 ucx_array_free(a1); |
| |
344 ucx_array_free(a2); |
| |
345 } |
| |
346 |
| |
347 UCX_TEST(test_ucx_array_at) { |
| |
348 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
349 |
| |
350 int x[3] = {42, 13, 5}; |
| |
351 ucx_array_append_from(array, x, 3); |
| |
352 |
| |
353 UCX_TEST_BEGIN |
| |
354 |
| |
355 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 1) == 13, "failed"); |
| |
356 *(int*)ucx_array_at(array, 1) = 80; |
| |
357 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 1) == 80, "assignment failed"); |
| |
358 |
| |
359 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 0) == 42, "corrupted data"); |
| |
360 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 2) == 5, "corrupted data"); |
| |
361 |
| |
362 UCX_TEST_END |
| |
363 |
| |
364 ucx_array_free(array); |
| |
365 } |
| |
366 |
| |
367 UCX_TEST(test_ucx_array_find) { |
| |
368 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
369 int *elems; |
| |
370 |
| |
371 array->size = 5; |
| |
372 elems = array->data; |
| |
373 elems[0] = 47; |
| |
374 elems[1] = 11; |
| |
375 elems[2] = 0; |
| |
376 elems[3] = 8; |
| |
377 elems[4] = 15; |
| |
378 |
| |
379 int x = 8; |
| |
380 int y = 90; |
| |
381 |
| |
382 UCX_TEST_BEGIN |
| |
383 |
| |
384 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,ucx_cmp_int,NULL) == 3, |
| |
385 "doesn't find element"); |
| |
386 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,ucx_cmp_int,NULL) == 5, |
| |
387 "finds non-existing element"); |
| |
388 |
| |
389 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,NULL,NULL) == 3, |
| |
390 "failed using memcmp()"); |
| |
391 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,NULL,NULL) == 5, |
| |
392 "failed using memcmp()"); |
| |
393 |
| |
394 UCX_TEST_END |
| |
395 ucx_array_free(array); |
| |
396 } |
| |
397 |
| |
398 UCX_TEST(test_ucx_array_contains) { |
| |
399 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
400 int *elems; |
| |
401 |
| |
402 array->size = 5; |
| |
403 elems = array->data; |
| |
404 elems[0] = 47; |
| |
405 elems[1] = 11; |
| |
406 elems[2] = 0; |
| |
407 elems[3] = 8; |
| |
408 elems[4] = 15; |
| |
409 |
| |
410 int x = 8; |
| |
411 int y = 90; |
| |
412 |
| |
413 UCX_TEST_BEGIN |
| |
414 |
| |
415 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,ucx_cmp_int,NULL), |
| |
416 "false negative"); |
| |
417 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,ucx_cmp_int,NULL), |
| |
418 "false positive"); |
| |
419 |
| |
420 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,NULL,NULL), |
| |
421 "false negative using memcmp()"); |
| |
422 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,NULL,NULL), |
| |
423 "false positive using memcmp()"); |
| |
424 |
| |
425 UCX_TEST_END |
| |
426 ucx_array_free(array); |
| |
427 } |
| |
428 |
| |
429 UCX_TEST(test_ucx_array_remove) { |
| |
430 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
431 int *elems; |
| |
432 |
| |
433 array->size = 5; |
| |
434 elems = array->data; |
| |
435 elems[0] = 47; |
| |
436 elems[1] = 11; |
| |
437 elems[2] = 0; |
| |
438 elems[3] = 8; |
| |
439 elems[4] = 15; |
| |
440 |
| |
441 UCX_TEST_BEGIN |
| |
442 |
| |
443 ucx_array_remove(array, 2); |
| |
444 elems = array->data; |
| |
445 UCX_TEST_ASSERT( |
| |
446 elems[0] == 47 && |
| |
447 elems[1] == 11 && |
| |
448 elems[2] == 8 && |
| |
449 elems[3] == 15, |
| |
450 "wrong contents after remove"); |
| |
451 UCX_TEST_ASSERT(array->size == 4, "wrong size after remove"); |
| |
452 |
| |
453 ucx_array_remove_fast(array, 1); |
| |
454 elems = array->data; |
| |
455 UCX_TEST_ASSERT( |
| |
456 elems[0] == 47 && |
| |
457 elems[1] == 15 && |
| |
458 elems[2] == 8, |
| |
459 "wrong contents after fast remove"); |
| |
460 UCX_TEST_ASSERT(array->size == 3, "wrong size after fast remove"); |
| |
461 |
| |
462 UCX_TEST_END |
| |
463 ucx_array_free(array); |
| |
464 } |
| |
465 |
| |
466 UCX_TEST(test_ucx_array_clone) { |
| |
467 UcxArray array; |
| |
468 UcxArray copy; |
| |
469 ucx_array_init(&array, 16, sizeof(int)); |
| |
470 ucx_array_init(©, 4, 2*sizeof(double)); |
| |
471 int *elems; |
| |
472 |
| |
473 array.size = 5; |
| |
474 elems = array.data; |
| |
475 elems[0] = 47; |
| |
476 elems[1] = 11; |
| |
477 elems[2] = 0; |
| |
478 elems[3] = 8; |
| |
479 elems[4] = 15; |
| |
480 |
| |
481 ucx_array_clone(©, &array); |
| |
482 UCX_TEST_BEGIN |
| |
483 |
| |
484 UCX_TEST_ASSERT(array.data != copy.data, "no true copy"); |
| |
485 UCX_TEST_ASSERT(array.size == copy.size, "size mismatch"); |
| |
486 UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch"); |
| |
487 UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch"); |
| |
488 UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch"); |
| |
489 UCX_TEST_ASSERT(ucx_array_equals(&array, ©, ucx_cmp_int, NULL), |
| |
490 "contents do not match after clone"); |
| |
491 |
| |
492 UCX_TEST_END |
| |
493 |
| |
494 ucx_array_destroy(&array); |
| |
495 ucx_array_destroy(©); |
| |
496 } |
| |
497 |
| |
498 static int ucx_cmp_int_reverse(const void* x, const void* y, void* data) { |
| |
499 return -ucx_cmp_int(x,y,data); |
| |
500 } |
| |
501 |
| |
502 UCX_TEST(test_ucx_array_sort) { |
| |
503 int *elems; |
| |
504 |
| |
505 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
506 array->size = 5; |
| |
507 elems = array->data; |
| |
508 elems[0] = 47; |
| |
509 elems[1] = 11; |
| |
510 elems[2] = 0; |
| |
511 elems[3] = 8; |
| |
512 elems[4] = 15; |
| |
513 |
| |
514 UcxArray *expected = ucx_array_new(16, sizeof(int)); |
| |
515 expected->size = 5; |
| |
516 elems = expected->data; |
| |
517 elems[0] = 0; |
| |
518 elems[1] = 8; |
| |
519 elems[2] = 11; |
| |
520 elems[3] = 15; |
| |
521 elems[4] = 47; |
| |
522 |
| |
523 UcxArray *expectedrev = ucx_array_new(16, sizeof(int)); |
| |
524 expectedrev->size = 5; |
| |
525 elems = expectedrev->data; |
| |
526 elems[0] = 47; |
| |
527 elems[1] = 15; |
| |
528 elems[2] = 11; |
| |
529 elems[3] = 8; |
| |
530 elems[4] = 0; |
| |
531 |
| |
532 |
| |
533 UCX_TEST_BEGIN |
| |
534 void* original_ptr = array->data; |
| |
535 ucx_array_sort(array, ucx_cmp_int, NULL); |
| |
536 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), "failed"); |
| |
537 UCX_TEST_ASSERT(array->size == 5, "size corrupted"); |
| |
538 UCX_TEST_ASSERT(array->data == original_ptr, "shall not reallocate"); |
| |
539 |
| |
540 ucx_array_sort(array, ucx_cmp_int_reverse, NULL); |
| |
541 UCX_TEST_ASSERT(ucx_array_equals(array, expectedrev, NULL, NULL), "failed"); |
| |
542 |
| |
543 ucx_array_reserve(array, 32); |
| |
544 ucx_array_reserve(expected, 32); |
| |
545 array->size = expected->size = 32; |
| |
546 for (size_t i = 0 ; i < 32 ; i++) { |
| |
547 ((int*)array->data)[i]= ((i%2==0)?-1:1) * ((int) i); |
| |
548 ((int*)expected->data)[i] = (-30+2*i) - (i > 15 ? 1 : 0); |
| |
549 } |
| |
550 |
| |
551 /* dummy third argument to trigger a possible fallback for qsort_s */ |
| |
552 ucx_array_sort(array, ucx_cmp_int, array->data); |
| |
553 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), |
| |
554 "failed for bigger arrays"); |
| |
555 UCX_TEST_END |
| |
556 |
| |
557 ucx_array_free(expectedrev); |
| |
558 ucx_array_free(expected); |
| |
559 ucx_array_free(array); |
| |
560 } |
| |
561 |
| |
562 UCX_TEST(test_ucx_array_autogrow) { |
| |
563 int *elems; |
| |
564 UcxArray *array = ucx_array_new(4, sizeof(int)); |
| |
565 array->size = 3; |
| |
566 elems = array->data; |
| |
567 elems[0] = 47; |
| |
568 elems[1] = 11; |
| |
569 int x = 5; |
| |
570 |
| |
571 UCX_TEST_BEGIN |
| |
572 |
| |
573 void* oldptr = array->data; |
| |
574 |
| |
575 ucx_array_append(array, 5); |
| |
576 UCX_TEST_ASSERT(array->capacity == 4 && array->data == oldptr, |
| |
577 "array should not grow too early"); |
| |
578 ucx_array_append(array, 5); |
| |
579 elems = array->data; |
| |
580 UCX_TEST_ASSERT(array->capacity == 8, "array did not grow"); |
| |
581 UCX_TEST_ASSERT(array->size == 5, "incorrect size after grow"); |
| |
582 UCX_TEST_ASSERT(elems[3] == 5 && elems[4] == 5, "corrupt data"); |
| |
583 |
| |
584 UCX_TEST_END |
| |
585 ucx_array_free(array); |
| |
586 } |
| |
587 |
| |
588 UCX_TEST(test_ucx_array_shrink) { |
| |
589 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
590 array->size = 4; |
| |
591 |
| |
592 UCX_TEST_BEGIN |
| |
593 UCX_TEST_ASSERT(!ucx_array_shrink(array), "failed"); |
| |
594 UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after shrink"); |
| |
595 UCX_TEST_END |
| |
596 ucx_array_free(array); |
| |
597 } |
| |
598 |
| |
599 UCX_TEST(test_ucx_array_resize) { |
| |
600 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
601 array->size = 8; |
| |
602 |
| |
603 UCX_TEST_BEGIN |
| |
604 |
| |
605 UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed"); |
| |
606 UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after resize"); |
| |
607 UCX_TEST_ASSERT(array->size == 8, "incorrect size after resize"); |
| |
608 |
| |
609 UCX_TEST_ASSERT(!ucx_array_resize(array, 4), "failed"); |
| |
610 UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after resize"); |
| |
611 UCX_TEST_ASSERT(array->size == 4, "incorrect size after resize"); |
| |
612 |
| |
613 UCX_TEST_END |
| |
614 ucx_array_free(array); |
| |
615 } |
| |
616 |
| |
617 UCX_TEST(test_ucx_array_reserve) { |
| |
618 UcxArray *array = ucx_array_new(16, sizeof(int)); |
| |
619 |
| |
620 UCX_TEST_BEGIN |
| |
621 |
| |
622 UCX_TEST_ASSERT(!ucx_array_reserve(array, 4), "failed"); |
| |
623 UCX_TEST_ASSERT(array->capacity == 16, "reserve shall not shrink"); |
| |
624 |
| |
625 UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed"); |
| |
626 UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after reserve"); |
| |
627 |
| |
628 UCX_TEST_END |
| |
629 ucx_array_free(array); |
| |
630 } |
| |
631 |
| |
632 UCX_TEST(test_ucx_array_util_set) { |
| |
633 size_t capacity = 16; |
| |
634 int* array = malloc(sizeof(int)*capacity); |
| |
635 |
| |
636 UCX_TEST_BEGIN |
| |
637 |
| |
638 UCX_ARRAY_UTIL_SET(&array, &capacity, 7, 42); |
| |
639 |
| |
640 UCX_TEST_ASSERT(array[7] == 42, "failed"); |
| |
641 UCX_TEST_ASSERT(capacity == 16, "capacity changed unnecessarily"); |
| |
642 |
| |
643 UCX_ARRAY_UTIL_SET(&array, &capacity, 37, 13); |
| |
644 UCX_ARRAY_UTIL_SET(&array, &capacity, 38, 37); |
| |
645 |
| |
646 UCX_TEST_ASSERT(array[37] == 13, "failed"); |
| |
647 UCX_TEST_ASSERT(array[38] == 37, "failed"); |
| |
648 UCX_TEST_ASSERT(capacity == 64, "capacity not grown"); |
| |
649 |
| |
650 UCX_TEST_END |
| |
651 |
| |
652 free(array); |
| |
653 } |