Thu, 04 Jul 2019 22:32:03 +0200
adds ucx_array_set()
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 */
29 #include "array_tests.h"
30 #include <ucx/utils.h>
32 UCX_TEST(test_ucx_array_free) {
33 UcxArray array = ucx_array_new(16, sizeof(int));
35 UCX_TEST_BEGIN
36 ucx_array_free(&array);
37 UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after free");
38 UCX_TEST_ASSERT(array.size == 0, "size not zero after free");
39 UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after free");
40 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(),
41 "allocator corrupted during free");
42 UCX_TEST_END
43 }
45 UCX_TEST(test_ucx_array_new) {
46 UcxArray array = ucx_array_new(16, 47);
48 UCX_TEST_BEGIN
49 UCX_TEST_ASSERT(array.data, "no memory allocated");
50 UCX_TEST_ASSERT(array.size == 0, "size not initially zero");
51 UCX_TEST_ASSERT(array.capacity == 16, "capacity not as requested");
52 UCX_TEST_ASSERT(array.elemsize == 47, "element size not as requested");
53 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(),
54 "array not using the default allocator");
55 UCX_TEST_END
56 ucx_array_free(&array);
57 }
59 UCX_TEST(test_ucx_array_append) {
60 UcxArray array = ucx_array_new(16, sizeof(int));
62 int x = 42;
63 ucx_array_append(&array, &x);
64 UCX_TEST_BEGIN
66 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "failed");
68 x = 13;
69 ucx_array_append(&array, &x);
71 UCX_TEST_ASSERT(array.size == 2, "incorrect size after append");
72 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, "failed");
73 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42,
74 "append corrupted previously inserted data");
76 ucx_array_append(&array, NULL);
78 UCX_TEST_ASSERT(array.size == 3, "incorrect size after NULL append");
79 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 0, "element is not zeroed");
80 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42,
81 "NULL append corrupted previously inserted data");
82 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13,
83 "NULL append corrupted previously inserted data");
85 UCX_TEST_END
87 ucx_array_free(&array);
88 }
90 UCX_TEST(test_ucx_array_prepend) {
91 UcxArray array = ucx_array_new(16, sizeof(int));
93 int x = 42;
94 ucx_array_prepend(&array, &x);
95 UCX_TEST_BEGIN
97 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "failed");
99 x = 13;
100 ucx_array_prepend(&array, &x);
102 UCX_TEST_ASSERT(array.size == 2, "incorrect size after prepend");
103 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 13, "failed");
104 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 42,
105 "prepend corrupted previously inserted data");
107 ucx_array_prepend(&array, NULL);
109 UCX_TEST_ASSERT(array.size == 3, "incorrect size after NULL prepend");
110 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 0, "element is not zeroed");
111 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13,
112 "NULL prepend corrupted previously inserted data");
113 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 42,
114 "NULL prepend corrupted previously inserted data");
116 UCX_TEST_END
118 ucx_array_free(&array);
119 }
121 UCX_TEST(test_ucx_array_set) {
122 UcxArray array = ucx_array_new(16, sizeof(int));
124 int x = 42;
126 UCX_TEST_BEGIN
128 ucx_array_set(&array, 7, &x);
129 UCX_TEST_ASSERT(ucx_array_at_int(array, 7) == 42, "failed");
130 UCX_TEST_ASSERT(array.size >= 8, "array not resized on set");
131 UCX_TEST_ASSERT(array.capacity == 16, "capacity changed unnecessarily");
133 x = 13;
134 ucx_array_set(&array, 27, &x);
136 UCX_TEST_ASSERT(ucx_array_at_int(array, 27) == 13, "failed");
137 UCX_TEST_ASSERT(array.size == 28, "array not resized on set");
138 UCX_TEST_ASSERT(array.capacity == 28, "capacity not grown");
140 ucx_array_set(&array, 7, NULL);
142 UCX_TEST_ASSERT(ucx_array_at_int(array, 7) == 0, "not zeroed on NULL set");
144 UCX_TEST_END
146 ucx_array_free(&array);
147 }
149 UCX_TEST(test_ucx_array_equals) {
150 UcxArray a1 = ucx_array_new(16, sizeof(int));
151 UcxArray a2 = ucx_array_new(16, sizeof(int));
152 UcxArray a3 = ucx_array_new(16, sizeof(long int));
153 UcxArray a4 = ucx_array_new(16, sizeof(int));
155 a1.size = 5;
156 ucx_array_at_int(a1, 0) = 47;
157 ucx_array_at_int(a1, 1) = 11;
158 ucx_array_at_int(a1, 2) = 0;
159 ucx_array_at_int(a1, 3) = 8;
160 ucx_array_at_int(a1, 4) = 15;
161 a2.size = 5;
162 ucx_array_at_int(a2, 0) = 47;
163 ucx_array_at_int(a2, 1) = 11;
164 ucx_array_at_int(a2, 2) = 0;
165 ucx_array_at_int(a2, 3) = 8;
166 ucx_array_at_int(a2, 4) = 15;
167 a3.size = 5;
168 ucx_array_at_longint(a3, 0) = 47;
169 ucx_array_at_longint(a3, 1) = 11;
170 ucx_array_at_longint(a3, 2) = 0;
171 ucx_array_at_longint(a3, 3) = 8;
172 ucx_array_at_longint(a3, 4) = 15;
173 a4.size = 5;
174 ucx_array_at_int(a4, 0) = 47;
175 ucx_array_at_int(a4, 1) = 11;
176 ucx_array_at_int(a4, 2) = -6;
177 ucx_array_at_int(a4, 3) = 8;
178 ucx_array_at_int(a4, 4) = 15;
180 UCX_TEST_BEGIN
182 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, ucx_cmp_int, NULL), "failed");
183 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, ucx_cmp_int, NULL), "failed");
184 UCX_TEST_ASSERT(!ucx_array_equals(a4, a1, ucx_cmp_int, NULL), "failed");
185 UCX_TEST_ASSERT(!ucx_array_equals(a1, a3, ucx_cmp_int, NULL),
186 "comparing arrays of different element size shall fail");
187 UCX_TEST_ASSERT(!ucx_array_equals(a3, a1, ucx_cmp_int, NULL),
188 "comparing arrays of different element size shall fail");
190 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, NULL, NULL),
191 "compare using memcmp() failed");
192 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, NULL, NULL),
193 "compare using memcmp() failed");
195 UCX_TEST_END
196 ucx_array_free(&a1);
197 ucx_array_free(&a2);
198 ucx_array_free(&a3);
199 ucx_array_free(&a4);
200 }
202 UCX_TEST(test_ucx_array_concat) {
203 UcxArray a1 = ucx_array_new(16, sizeof(int));
204 UcxArray a2 = ucx_array_new(16, sizeof(int));
206 a1.size = 2;
207 ucx_array_at_int(a1, 0) = 47;
208 ucx_array_at_int(a1, 1) = 11;
209 a2.size = 3;
210 ucx_array_at_int(a2, 0) = 0;
211 ucx_array_at_int(a2, 1) = 8;
212 ucx_array_at_int(a2, 2) = 15;
214 UCX_TEST_BEGIN
216 UCX_TEST_ASSERT(!ucx_array_concat(&a1, &a2), "failed");
217 UCX_TEST_ASSERT(a1.size == 5, "failed");
218 UCX_TEST_ASSERT(ucx_array_at_int(a1, 0) == 47, "failed");
219 UCX_TEST_ASSERT(ucx_array_at_int(a1, 1) == 11, "failed");
220 UCX_TEST_ASSERT(ucx_array_at_int(a1, 2) == 0, "failed");
221 UCX_TEST_ASSERT(ucx_array_at_int(a1, 3) == 8, "failed");
222 UCX_TEST_ASSERT(ucx_array_at_int(a1, 4) == 15, "failed");
224 a1.elemsize *= 2;
225 UCX_TEST_ASSERT(ucx_array_concat(&a1, &a2),
226 "arrays of different element size must not be concatenated");
227 UCX_TEST_ASSERT(a1.size == 5,
228 "arrays of different element size must not be concatenated");
230 UCX_TEST_END
231 ucx_array_free(&a1);
232 ucx_array_free(&a2);
233 }
235 UCX_TEST(test_ucx_array_at) {
236 UcxArray array = ucx_array_new(16, sizeof(int));
238 int x = 42;
239 ucx_array_append(&array, &x);
240 x = 13;
241 ucx_array_append(&array, &x);
242 x = 5;
243 ucx_array_append(&array, &x);
245 UCX_TEST_BEGIN
247 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, "failed");
248 ucx_array_at_int(array, 1) = 80;
249 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 80, "assignment failed");
252 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "corrupted data");
253 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 5, "corrupted data");
255 UCX_TEST_END
257 ucx_array_free(&array);
258 }
260 UCX_TEST(test_ucx_array_find) {
261 UcxArray array = ucx_array_new(16, sizeof(int));
263 array.size = 5;
264 ucx_array_at_int(array, 0) = 47;
265 ucx_array_at_int(array, 1) = 11;
266 ucx_array_at_int(array, 2) = 0;
267 ucx_array_at_int(array, 3) = 8;
268 ucx_array_at_int(array, 4) = 15;
270 int x = 8;
271 int y = 90;
273 UCX_TEST_BEGIN
275 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,ucx_cmp_int,NULL) == 3,
276 "doesn't find element");
277 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,ucx_cmp_int,NULL) == 5,
278 "finds non-existing element");
280 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,NULL,NULL) == 3,
281 "failed using memcmp()");
282 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,NULL,NULL) == 5,
283 "failed using memcmp()");
285 UCX_TEST_END
286 ucx_array_free(&array);
287 }
289 UCX_TEST(test_ucx_array_contains) {
290 UcxArray array = ucx_array_new(16, sizeof(int));
292 array.size = 5;
293 ucx_array_at_int(array, 0) = 47;
294 ucx_array_at_int(array, 1) = 11;
295 ucx_array_at_int(array, 2) = 0;
296 ucx_array_at_int(array, 3) = 8;
297 ucx_array_at_int(array, 4) = 15;
299 int x = 8;
300 int y = 90;
302 UCX_TEST_BEGIN
304 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,ucx_cmp_int,NULL),
305 "false negative");
306 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,ucx_cmp_int,NULL),
307 "false positive");
309 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,NULL,NULL),
310 "false negative using memcmp()");
311 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,NULL,NULL),
312 "false positive using memcmp()");
314 UCX_TEST_END
315 ucx_array_free(&array);
316 }
318 UCX_TEST(test_ucx_array_remove) {
319 UcxArray array = ucx_array_new(16, sizeof(int));
321 array.size = 5;
322 ucx_array_at_int(array, 0) = 47;
323 ucx_array_at_int(array, 1) = 11;
324 ucx_array_at_int(array, 2) = 0;
325 ucx_array_at_int(array, 3) = 8;
326 ucx_array_at_int(array, 4) = 15;
328 UCX_TEST_BEGIN
330 ucx_array_remove(&array, 2);
331 UCX_TEST_ASSERT(
332 ucx_array_at_int(array, 0) == 47 &&
333 ucx_array_at_int(array, 1) == 11 &&
334 ucx_array_at_int(array, 2) == 8 &&
335 ucx_array_at_int(array, 3) == 15,
336 "wrong contents after remove");
337 UCX_TEST_ASSERT(array.size == 4, "wrong size after remove");
339 ucx_array_remove_fast(&array, 1);
340 UCX_TEST_ASSERT(
341 ucx_array_at_int(array, 0) == 47 &&
342 ucx_array_at_int(array, 1) == 15 &&
343 ucx_array_at_int(array, 2) == 8,
344 "wrong contents after fast remove");
345 UCX_TEST_ASSERT(array.size == 3, "wrong size after fast remove");
347 UCX_TEST_END
348 ucx_array_free(&array);
349 }
351 UCX_TEST(test_ucx_array_clone) {
353 UcxArray array = ucx_array_new(16, sizeof(int));
355 array.size = 5;
356 ucx_array_at_int(array, 0) = 47;
357 ucx_array_at_int(array, 1) = 11;
358 ucx_array_at_int(array, 2) = 0;
359 ucx_array_at_int(array, 3) = 8;
360 ucx_array_at_int(array, 4) = 15;
362 UcxArray copy = ucx_array_clone(array);
363 UCX_TEST_BEGIN
365 UCX_TEST_ASSERT(array.data != copy.data, "no true copy");
366 UCX_TEST_ASSERT(array.size == copy.size, "size mismatch");
367 UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch");
368 UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch");
369 UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch");
370 UCX_TEST_ASSERT(ucx_array_equals(array, copy, ucx_cmp_int, NULL), "failed");
372 UCX_TEST_END
374 ucx_array_free(&array);
375 ucx_array_free(©);
376 }
378 UCX_TEST(test_ucx_array_sort) {
379 UcxArray array = ucx_array_new(16, sizeof(int));
380 array.size = 5;
381 ucx_array_at_int(array, 0) = 47;
382 ucx_array_at_int(array, 1) = 11;
383 ucx_array_at_int(array, 2) = 0;
384 ucx_array_at_int(array, 3) = 8;
385 ucx_array_at_int(array, 4) = 15;
387 UcxArray expected = ucx_array_new(16, sizeof(int));
388 expected.size = 5;
389 ucx_array_at_int(expected, 0) = 0;
390 ucx_array_at_int(expected, 1) = 8;
391 ucx_array_at_int(expected, 2) = 11;
392 ucx_array_at_int(expected, 3) = 15;
393 ucx_array_at_int(expected, 4) = 47;
396 UCX_TEST_BEGIN
397 void* original_ptr = array.data;
398 ucx_array_sort(array, ucx_cmp_int, NULL);
399 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), "failed");
400 UCX_TEST_ASSERT(array.size == 5, "size corrupted");
401 UCX_TEST_ASSERT(array.data == original_ptr, "shall not reallocate");
403 ucx_array_reserve(&array, 32);
404 ucx_array_reserve(&expected, 32);
405 array.size = expected.size = 32;
406 for (size_t i = 0 ; i < 32 ; i++) {
407 ucx_array_at_int(array, i) = ((i%2==0)?-1:1) * ((int) i);
408 ucx_array_at_int(expected, i) = (-30+2*i) - (i > 15 ? 1 : 0);
409 }
411 ucx_array_sort(array, ucx_cmp_int, NULL);
412 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL),
413 "failed for bigger arrays");
414 UCX_TEST_END
416 ucx_array_free(&expected);
417 ucx_array_free(&array);
418 }
420 UCX_TEST(test_ucx_array_autogrow) {
421 UcxArray array = ucx_array_new(4, sizeof(int));
422 array.size = 3;
423 ucx_array_at_int(array, 0) = 47;
424 ucx_array_at_int(array, 1) = 11;
425 int x = 5;
427 UCX_TEST_BEGIN
429 void* oldptr = array.data;
431 ucx_array_append(&array, &x);
432 UCX_TEST_ASSERT(array.capacity == 4 && array.data == oldptr,
433 "array should not grow too early");
434 ucx_array_append(&array, &x);
435 UCX_TEST_ASSERT(array.capacity == 8, "array did not grow");
436 UCX_TEST_ASSERT(array.size == 5, "incorrect size after grow");
437 UCX_TEST_ASSERT(ucx_array_at_int(array, 3) == 5 &&
438 ucx_array_at_int(array, 3) == 5, "corrupt data");
440 UCX_TEST_END
441 ucx_array_free(&array);
442 }
444 UCX_TEST(test_ucx_array_shrink) {
445 UcxArray array = ucx_array_new(16, sizeof(int));
446 array.size = 4;
448 UCX_TEST_BEGIN
449 UCX_TEST_ASSERT(!ucx_array_shrink(&array), "failed");
450 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after shrink");
451 UCX_TEST_END
452 ucx_array_free(&array);
453 }
455 UCX_TEST(test_ucx_array_resize) {
456 UcxArray array = ucx_array_new(16, sizeof(int));
457 array.size = 8;
459 UCX_TEST_BEGIN
461 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
462 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after resize");
463 UCX_TEST_ASSERT(array.size == 8, "incorrect size after resize");
465 UCX_TEST_ASSERT(!ucx_array_resize(&array, 4), "failed");
466 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after resize");
467 UCX_TEST_ASSERT(array.size == 4, "incorrect size after resize");
469 UCX_TEST_END
470 ucx_array_free(&array);
471 }
473 UCX_TEST(test_ucx_array_reserve) {
474 UcxArray array = ucx_array_new(16, sizeof(int));
476 UCX_TEST_BEGIN
478 UCX_TEST_ASSERT(!ucx_array_reserve(&array, 4), "failed");
479 UCX_TEST_ASSERT(array.capacity == 16, "reserve shall not shrink");
481 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
482 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after reserve");
484 UCX_TEST_END
485 ucx_array_free(&array);
486 }