Thu, 04 Jul 2019 22:23:15 +0200
implements ucx_array_sort()
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_equals) {
122 UcxArray a1 = ucx_array_new(16, sizeof(int));
123 UcxArray a2 = ucx_array_new(16, sizeof(int));
124 UcxArray a3 = ucx_array_new(16, sizeof(long int));
125 UcxArray a4 = ucx_array_new(16, sizeof(int));
127 a1.size = 5;
128 ucx_array_at_int(a1, 0) = 47;
129 ucx_array_at_int(a1, 1) = 11;
130 ucx_array_at_int(a1, 2) = 0;
131 ucx_array_at_int(a1, 3) = 8;
132 ucx_array_at_int(a1, 4) = 15;
133 a2.size = 5;
134 ucx_array_at_int(a2, 0) = 47;
135 ucx_array_at_int(a2, 1) = 11;
136 ucx_array_at_int(a2, 2) = 0;
137 ucx_array_at_int(a2, 3) = 8;
138 ucx_array_at_int(a2, 4) = 15;
139 a3.size = 5;
140 ucx_array_at_longint(a3, 0) = 47;
141 ucx_array_at_longint(a3, 1) = 11;
142 ucx_array_at_longint(a3, 2) = 0;
143 ucx_array_at_longint(a3, 3) = 8;
144 ucx_array_at_longint(a3, 4) = 15;
145 a4.size = 5;
146 ucx_array_at_int(a4, 0) = 47;
147 ucx_array_at_int(a4, 1) = 11;
148 ucx_array_at_int(a4, 2) = -6;
149 ucx_array_at_int(a4, 3) = 8;
150 ucx_array_at_int(a4, 4) = 15;
152 UCX_TEST_BEGIN
154 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, ucx_cmp_int, NULL), "failed");
155 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, ucx_cmp_int, NULL), "failed");
156 UCX_TEST_ASSERT(!ucx_array_equals(a4, a1, ucx_cmp_int, NULL), "failed");
157 UCX_TEST_ASSERT(!ucx_array_equals(a1, a3, ucx_cmp_int, NULL),
158 "comparing arrays of different element size shall fail");
159 UCX_TEST_ASSERT(!ucx_array_equals(a3, a1, ucx_cmp_int, NULL),
160 "comparing arrays of different element size shall fail");
162 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, NULL, NULL),
163 "compare using memcmp() failed");
164 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, NULL, NULL),
165 "compare using memcmp() failed");
167 UCX_TEST_END
168 ucx_array_free(&a1);
169 ucx_array_free(&a2);
170 ucx_array_free(&a3);
171 ucx_array_free(&a4);
172 }
174 UCX_TEST(test_ucx_array_concat) {
175 UcxArray a1 = ucx_array_new(16, sizeof(int));
176 UcxArray a2 = ucx_array_new(16, sizeof(int));
178 a1.size = 2;
179 ucx_array_at_int(a1, 0) = 47;
180 ucx_array_at_int(a1, 1) = 11;
181 a2.size = 3;
182 ucx_array_at_int(a2, 0) = 0;
183 ucx_array_at_int(a2, 1) = 8;
184 ucx_array_at_int(a2, 2) = 15;
186 UCX_TEST_BEGIN
188 UCX_TEST_ASSERT(!ucx_array_concat(&a1, &a2), "failed");
189 UCX_TEST_ASSERT(a1.size == 5, "failed");
190 UCX_TEST_ASSERT(ucx_array_at_int(a1, 0) == 47, "failed");
191 UCX_TEST_ASSERT(ucx_array_at_int(a1, 1) == 11, "failed");
192 UCX_TEST_ASSERT(ucx_array_at_int(a1, 2) == 0, "failed");
193 UCX_TEST_ASSERT(ucx_array_at_int(a1, 3) == 8, "failed");
194 UCX_TEST_ASSERT(ucx_array_at_int(a1, 4) == 15, "failed");
196 a1.elemsize *= 2;
197 UCX_TEST_ASSERT(ucx_array_concat(&a1, &a2),
198 "arrays of different element size must not be concatenated");
199 UCX_TEST_ASSERT(a1.size == 5,
200 "arrays of different element size must not be concatenated");
202 UCX_TEST_END
203 ucx_array_free(&a1);
204 ucx_array_free(&a2);
205 }
207 UCX_TEST(test_ucx_array_at) {
208 UcxArray array = ucx_array_new(16, sizeof(int));
210 int x = 42;
211 ucx_array_append(&array, &x);
212 x = 13;
213 ucx_array_append(&array, &x);
214 x = 5;
215 ucx_array_append(&array, &x);
217 UCX_TEST_BEGIN
219 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 13, "failed");
220 ucx_array_at_int(array, 1) = 80;
221 UCX_TEST_ASSERT(ucx_array_at_int(array, 1) == 80, "assignment failed");
224 UCX_TEST_ASSERT(ucx_array_at_int(array, 0) == 42, "corrupted data");
225 UCX_TEST_ASSERT(ucx_array_at_int(array, 2) == 5, "corrupted data");
227 UCX_TEST_END
229 ucx_array_free(&array);
230 }
232 UCX_TEST(test_ucx_array_find) {
233 UcxArray array = ucx_array_new(16, sizeof(int));
235 array.size = 5;
236 ucx_array_at_int(array, 0) = 47;
237 ucx_array_at_int(array, 1) = 11;
238 ucx_array_at_int(array, 2) = 0;
239 ucx_array_at_int(array, 3) = 8;
240 ucx_array_at_int(array, 4) = 15;
242 int x = 8;
243 int y = 90;
245 UCX_TEST_BEGIN
247 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,ucx_cmp_int,NULL) == 3,
248 "doesn't find element");
249 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,ucx_cmp_int,NULL) == 5,
250 "finds non-existing element");
252 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,NULL,NULL) == 3,
253 "failed using memcmp()");
254 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,NULL,NULL) == 5,
255 "failed using memcmp()");
257 UCX_TEST_END
258 ucx_array_free(&array);
259 }
261 UCX_TEST(test_ucx_array_contains) {
262 UcxArray array = ucx_array_new(16, sizeof(int));
264 array.size = 5;
265 ucx_array_at_int(array, 0) = 47;
266 ucx_array_at_int(array, 1) = 11;
267 ucx_array_at_int(array, 2) = 0;
268 ucx_array_at_int(array, 3) = 8;
269 ucx_array_at_int(array, 4) = 15;
271 int x = 8;
272 int y = 90;
274 UCX_TEST_BEGIN
276 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,ucx_cmp_int,NULL),
277 "false negative");
278 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,ucx_cmp_int,NULL),
279 "false positive");
281 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,NULL,NULL),
282 "false negative using memcmp()");
283 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,NULL,NULL),
284 "false positive using memcmp()");
286 UCX_TEST_END
287 ucx_array_free(&array);
288 }
290 UCX_TEST(test_ucx_array_remove) {
291 UcxArray array = ucx_array_new(16, sizeof(int));
293 array.size = 5;
294 ucx_array_at_int(array, 0) = 47;
295 ucx_array_at_int(array, 1) = 11;
296 ucx_array_at_int(array, 2) = 0;
297 ucx_array_at_int(array, 3) = 8;
298 ucx_array_at_int(array, 4) = 15;
300 UCX_TEST_BEGIN
302 ucx_array_remove(&array, 2);
303 UCX_TEST_ASSERT(
304 ucx_array_at_int(array, 0) == 47 &&
305 ucx_array_at_int(array, 1) == 11 &&
306 ucx_array_at_int(array, 2) == 8 &&
307 ucx_array_at_int(array, 3) == 15,
308 "wrong contents after remove");
309 UCX_TEST_ASSERT(array.size == 4, "wrong size after remove");
311 ucx_array_remove_fast(&array, 1);
312 UCX_TEST_ASSERT(
313 ucx_array_at_int(array, 0) == 47 &&
314 ucx_array_at_int(array, 1) == 15 &&
315 ucx_array_at_int(array, 2) == 8,
316 "wrong contents after fast remove");
317 UCX_TEST_ASSERT(array.size == 3, "wrong size after fast remove");
319 UCX_TEST_END
320 ucx_array_free(&array);
321 }
323 UCX_TEST(test_ucx_array_clone) {
325 UcxArray array = ucx_array_new(16, sizeof(int));
327 array.size = 5;
328 ucx_array_at_int(array, 0) = 47;
329 ucx_array_at_int(array, 1) = 11;
330 ucx_array_at_int(array, 2) = 0;
331 ucx_array_at_int(array, 3) = 8;
332 ucx_array_at_int(array, 4) = 15;
334 UcxArray copy = ucx_array_clone(array);
335 UCX_TEST_BEGIN
337 UCX_TEST_ASSERT(array.data != copy.data, "no true copy");
338 UCX_TEST_ASSERT(array.size == copy.size, "size mismatch");
339 UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch");
340 UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch");
341 UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch");
342 UCX_TEST_ASSERT(ucx_array_equals(array, copy, ucx_cmp_int, NULL), "failed");
344 UCX_TEST_END
346 ucx_array_free(&array);
347 ucx_array_free(©);
348 }
350 UCX_TEST(test_ucx_array_sort) {
351 UcxArray array = ucx_array_new(16, sizeof(int));
352 array.size = 5;
353 ucx_array_at_int(array, 0) = 47;
354 ucx_array_at_int(array, 1) = 11;
355 ucx_array_at_int(array, 2) = 0;
356 ucx_array_at_int(array, 3) = 8;
357 ucx_array_at_int(array, 4) = 15;
359 UcxArray expected = ucx_array_new(16, sizeof(int));
360 expected.size = 5;
361 ucx_array_at_int(expected, 0) = 0;
362 ucx_array_at_int(expected, 1) = 8;
363 ucx_array_at_int(expected, 2) = 11;
364 ucx_array_at_int(expected, 3) = 15;
365 ucx_array_at_int(expected, 4) = 47;
368 UCX_TEST_BEGIN
369 void* original_ptr = array.data;
370 ucx_array_sort(array, ucx_cmp_int, NULL);
371 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), "failed");
372 UCX_TEST_ASSERT(array.size == 5, "size corrupted");
373 UCX_TEST_ASSERT(array.data == original_ptr, "shall not reallocate");
375 ucx_array_reserve(&array, 32);
376 ucx_array_reserve(&expected, 32);
377 array.size = expected.size = 32;
378 for (size_t i = 0 ; i < 32 ; i++) {
379 ucx_array_at_int(array, i) = ((i%2==0)?-1:1) * ((int) i);
380 ucx_array_at_int(expected, i) = (-30+2*i) - (i > 15 ? 1 : 0);
381 }
383 ucx_array_sort(array, ucx_cmp_int, NULL);
384 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL),
385 "failed for bigger arrays");
386 UCX_TEST_END
388 ucx_array_free(&expected);
389 ucx_array_free(&array);
390 }
392 UCX_TEST(test_ucx_array_autogrow) {
393 UcxArray array = ucx_array_new(4, sizeof(int));
394 array.size = 3;
395 ucx_array_at_int(array, 0) = 47;
396 ucx_array_at_int(array, 1) = 11;
397 int x = 5;
399 UCX_TEST_BEGIN
401 void* oldptr = array.data;
403 ucx_array_append(&array, &x);
404 UCX_TEST_ASSERT(array.capacity == 4 && array.data == oldptr,
405 "array should not grow too early");
406 ucx_array_append(&array, &x);
407 UCX_TEST_ASSERT(array.capacity == 8, "array did not grow");
408 UCX_TEST_ASSERT(array.size == 5, "incorrect size after grow");
409 UCX_TEST_ASSERT(ucx_array_at_int(array, 3) == 5 &&
410 ucx_array_at_int(array, 3) == 5, "corrupt data");
412 UCX_TEST_END
413 ucx_array_free(&array);
414 }
416 UCX_TEST(test_ucx_array_shrink) {
417 UcxArray array = ucx_array_new(16, sizeof(int));
418 array.size = 4;
420 UCX_TEST_BEGIN
421 UCX_TEST_ASSERT(!ucx_array_shrink(&array), "failed");
422 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after shrink");
423 UCX_TEST_END
424 ucx_array_free(&array);
425 }
427 UCX_TEST(test_ucx_array_resize) {
428 UcxArray array = ucx_array_new(16, sizeof(int));
429 array.size = 8;
431 UCX_TEST_BEGIN
433 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
434 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after resize");
435 UCX_TEST_ASSERT(array.size == 8, "incorrect size after resize");
437 UCX_TEST_ASSERT(!ucx_array_resize(&array, 4), "failed");
438 UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after resize");
439 UCX_TEST_ASSERT(array.size == 4, "incorrect size after resize");
441 UCX_TEST_END
442 ucx_array_free(&array);
443 }
445 UCX_TEST(test_ucx_array_reserve) {
446 UcxArray array = ucx_array_new(16, sizeof(int));
448 UCX_TEST_BEGIN
450 UCX_TEST_ASSERT(!ucx_array_reserve(&array, 4), "failed");
451 UCX_TEST_ASSERT(array.capacity == 16, "reserve shall not shrink");
453 UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
454 UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after reserve");
456 UCX_TEST_END
457 ucx_array_free(&array);
458 }