UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2023 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 "cx/test.h" 30 #include "util_allocator.h" 31 #include "cx/compare.h" 32 33 #include "cx/array_list.h" 34 #include "cx/linked_list.h" 35 #include "cx/kv_list.h" 36 37 #include <stdarg.h> 38 #include <errno.h> 39 40 CX_TEST(test_array_add) { 41 CX_ARRAY_DECLARE(int, arr); 42 arr = cxCallocDefault(5, sizeof(int)); 43 arr[0] = 2; 44 arr[1] = 3; 45 arr[2] = 5; 46 arr[3] = 7; 47 arr[4] = 11; 48 arr_size = 3; 49 arr_capacity = 5; 50 int elem = 8, elem2 = 47; 51 int result; 52 CX_TEST_DO { 53 result = cx_array_simple_add(arr, elem); 54 CX_TEST_ASSERT(result == 0); 55 CX_TEST_ASSERT(arr[0] == 2); 56 CX_TEST_ASSERT(arr[1] == 3); 57 CX_TEST_ASSERT(arr[2] == 5); 58 CX_TEST_ASSERT(arr[3] == 8); 59 CX_TEST_ASSERT(arr[4] == 11); 60 CX_TEST_ASSERT(arr_size == 4); 61 CX_TEST_ASSERT(arr_capacity == 5); 62 63 arr_size = 5; 64 result = cx_array_simple_add(arr, elem2); 65 CX_TEST_ASSERT(result == 0); 66 CX_TEST_ASSERT(arr[0] == 2); 67 CX_TEST_ASSERT(arr[1] == 3); 68 CX_TEST_ASSERT(arr[2] == 5); 69 CX_TEST_ASSERT(arr[3] == 8); 70 CX_TEST_ASSERT(arr[4] == 11); 71 CX_TEST_ASSERT(arr[5] == 47); 72 CX_TEST_ASSERT(arr_size == 6); 73 CX_TEST_ASSERT(arr_capacity >= 6); 74 } 75 cxFreeDefault(arr); 76 } 77 78 CX_TEST(test_array_add8) { 79 CX_ARRAY_DECLARE_SIZED(int, arr, uint8_t); 80 arr = cxCallocDefault(5, sizeof(int)); 81 arr[0] = 2; 82 arr[1] = 3; 83 arr[2] = 5; 84 arr[3] = 7; 85 arr[4] = 11; 86 arr_size = 3; 87 arr_capacity = 5; 88 int elem = 8, elem2 = 47; 89 int result; 90 CX_TEST_DO { 91 result = cx_array_simple_add(arr, elem); 92 CX_TEST_ASSERT(result == 0); 93 CX_TEST_ASSERT(arr[0] == 2); 94 CX_TEST_ASSERT(arr[1] == 3); 95 CX_TEST_ASSERT(arr[2] == 5); 96 CX_TEST_ASSERT(arr[3] == 8); 97 CX_TEST_ASSERT(arr[4] == 11); 98 CX_TEST_ASSERT(arr_size == 4); 99 CX_TEST_ASSERT(arr_capacity == 5); 100 101 arr_size = 5; 102 result = cx_array_simple_add(arr, elem2); 103 CX_TEST_ASSERT(result == 0); 104 CX_TEST_ASSERT(arr[0] == 2); 105 CX_TEST_ASSERT(arr[1] == 3); 106 CX_TEST_ASSERT(arr[2] == 5); 107 CX_TEST_ASSERT(arr[3] == 8); 108 CX_TEST_ASSERT(arr[4] == 11); 109 CX_TEST_ASSERT(arr[5] == 47); 110 CX_TEST_ASSERT(arr_size == 6); 111 CX_TEST_ASSERT(arr_capacity >= 6); 112 113 result = cx_array_simple_copy(arr, 260, &elem, 1); 114 CX_TEST_ASSERT(result != 0); 115 CX_TEST_ASSERT(errno == EOVERFLOW); 116 CX_TEST_ASSERT(arr_size == 6); 117 CX_TEST_ASSERT(arr_capacity < 128); 118 } 119 cxFreeDefault(arr); 120 } 121 122 CX_TEST(test_array_add16) { 123 CX_ARRAY_DECLARE_SIZED(char, arr, uint16_t); 124 cx_array_initialize(arr, 300); 125 arr_size = 270; 126 int result; 127 CX_TEST_DO { 128 char elem = 'A'; 129 result = cx_array_simple_add(arr, elem); 130 CX_TEST_ASSERT(result == 0); 131 CX_TEST_ASSERT(arr[270] == 'A'); 132 CX_TEST_ASSERT(arr_size == 271); 133 CX_TEST_ASSERT(arr_capacity == 300); 134 135 char *hello = "Hello"; 136 result = cx_array_simple_copy(arr, 9000, hello, 5); 137 CX_TEST_ASSERT(result == 0); 138 CX_TEST_ASSERT(arr[9000] == 'H'); 139 CX_TEST_ASSERT(arr[9001] == 'e'); 140 CX_TEST_ASSERT(arr[9002] == 'l'); 141 CX_TEST_ASSERT(arr[9003] == 'l'); 142 CX_TEST_ASSERT(arr[9004] == 'o'); 143 CX_TEST_ASSERT(arr_size == 9005); 144 CX_TEST_ASSERT(arr_capacity == 9*1024); 145 146 // does not fit into 16-bit sized array 147 result = cx_array_simple_copy(arr, 65532, hello, 5); 148 CX_TEST_ASSERT(result != 0); 149 CX_TEST_ASSERT(errno == EOVERFLOW); 150 CX_TEST_ASSERT(arr_size == 9005); 151 CX_TEST_ASSERT(arr_capacity == 9*1024); 152 } 153 cxFreeDefault(arr); 154 } 155 156 CX_TEST(test_array_copy_unsupported_width) { 157 CX_ARRAY_DECLARE_SIZED(int, arr, uint16_t); 158 cx_array_initialize(arr, 16); 159 int result; 160 CX_TEST_DO { 161 int elem = 5; 162 result = cx_array_copy( 163 (void **) &(arr), 164 &(arr_size), 165 &(arr_capacity), 166 12, // unsupported width 167 5, 168 &elem, sizeof(int), 169 1, 170 cx_array_default_reallocator 171 ); 172 CX_TEST_ASSERT(result != 0); 173 CX_TEST_ASSERT(errno == EINVAL); 174 CX_TEST_ASSERT(arr_size == 0); 175 CX_TEST_ASSERT(arr_capacity == 16); 176 } 177 cxFreeDefault(arr); 178 } 179 180 CX_TEST(test_array_copy_overlap) { 181 CX_ARRAY_DECLARE_SIZED(char, arr, uint8_t); 182 cx_array_initialize(arr, 16); 183 strcpy(arr, "Hello, World!"); 184 CX_TEST_DO { 185 errno = 0; 186 int result = cx_array_simple_copy(arr, 7, arr, 14); 187 CX_TEST_ASSERT(result == 0); 188 CX_TEST_ASSERT(errno == 0); 189 CX_TEST_ASSERT(arr_size == 21); 190 CX_TEST_ASSERT(arr_capacity == 32); 191 CX_TEST_ASSERT(0 == memcmp(arr, "Hello, Hello, World!\0", 21)); 192 } 193 cxFreeDefault(arr); 194 } 195 196 CX_TEST(test_array_reserve) { 197 { 198 // default size 199 CX_ARRAY_DECLARE(int, arr); 200 cx_array_initialize(arr, 16); 201 int result; 202 CX_TEST_DO { 203 result = cx_array_reserve( 204 (void **) &(arr), 205 &(arr_size), 206 &(arr_capacity), 207 0, // default width 208 sizeof(int), 209 30, 210 cx_array_default_reallocator 211 ); 212 CX_TEST_ASSERT(result == 0); 213 CX_TEST_ASSERT(arr_size == 0); 214 CX_TEST_ASSERT(arr_capacity == 30); 215 } 216 cxFreeDefault(arr); 217 } 218 { 219 // 16-bit size 220 CX_ARRAY_DECLARE_SIZED(char, arr, uint16_t); 221 cx_array_initialize(arr, 16); 222 arr_size = 5; 223 int result; 224 CX_TEST_DO { 225 errno = 0; 226 result = cx_array_simple_reserve(arr, 3); 227 CX_TEST_ASSERT(result == 0); 228 CX_TEST_ASSERT(errno == 0); 229 CX_TEST_ASSERT(arr_size == 5); 230 CX_TEST_ASSERT(arr_capacity == 16); 231 232 result = cx_array_simple_reserve(arr, 20); 233 CX_TEST_ASSERT(result == 0); 234 CX_TEST_ASSERT(errno == 0); 235 CX_TEST_ASSERT(arr_size == 5); 236 CX_TEST_ASSERT(arr_capacity == 25); 237 238 result = cx_array_simple_reserve(arr, 2000); 239 CX_TEST_ASSERT(result == 0); 240 CX_TEST_ASSERT(errno == 0); 241 CX_TEST_ASSERT(arr_size == 5); 242 CX_TEST_ASSERT(arr_capacity == 2005); 243 244 // this does not fit into an array with a 16-bit size 245 result = cx_array_simple_reserve(arr, 70000); 246 CX_TEST_ASSERT(result == 1); 247 CX_TEST_ASSERT(errno == EOVERFLOW); 248 CX_TEST_ASSERT(arr_size == 5); 249 CX_TEST_ASSERT(arr_capacity == 2005); 250 } 251 cxFreeDefault(arr); 252 } 253 { 254 // 8-bit size 255 CX_ARRAY_DECLARE_SIZED(char, arr, uint8_t); 256 cx_array_initialize(arr, 16); 257 arr_size = 5; 258 int result; 259 CX_TEST_DO { 260 errno = 0; 261 result = cx_array_simple_reserve(arr, 3); 262 CX_TEST_ASSERT(result == 0); 263 CX_TEST_ASSERT(errno == 0); 264 CX_TEST_ASSERT(arr_size == 5); 265 CX_TEST_ASSERT(arr_capacity == 16); 266 267 result = cx_array_simple_reserve(arr, 20); 268 CX_TEST_ASSERT(result == 0); 269 CX_TEST_ASSERT(errno == 0); 270 CX_TEST_ASSERT(arr_size == 5); 271 CX_TEST_ASSERT(arr_capacity == 25); 272 273 // this does not fit into an array with an 8-bit size 274 arr_size = 10; 275 result = cx_array_simple_reserve(arr, 250); 276 CX_TEST_ASSERT(result == 1); 277 CX_TEST_ASSERT(errno == EOVERFLOW); 278 CX_TEST_ASSERT(arr_size == 10); 279 CX_TEST_ASSERT(arr_capacity == 25); 280 } 281 cxFreeDefault(arr); 282 } 283 } 284 285 CX_TEST(test_array_reserve_unsupported_width) { 286 CX_ARRAY_DECLARE_SIZED(int, arr, uint16_t); 287 cx_array_initialize(arr, 16); 288 int result; 289 CX_TEST_DO { 290 result = cx_array_reserve( 291 (void **) &(arr), 292 &(arr_size), 293 &(arr_capacity), 294 12, // unsupported width 295 sizeof(int), 296 30, 297 cx_array_default_reallocator 298 ); 299 CX_TEST_ASSERT(result != 0); 300 CX_TEST_ASSERT(errno == EINVAL); 301 CX_TEST_ASSERT(arr_size == 0); 302 CX_TEST_ASSERT(arr_capacity == 16); 303 } 304 cxFreeDefault(arr); 305 } 306 307 CX_TEST(test_array_insert_sorted) { 308 int d1 = 50; 309 int d2 = 80; 310 int d3 = 60; 311 int d4 = 40; 312 int d5 = 70; 313 int d6a[6] = {52, 54, 56, 62, 64, 75}; 314 int d7a[6] = {51, 57, 58, 65, 77, 78}; 315 int d8 = 90; 316 int d9 = 56; 317 int d10a[3] = {67, 75, 90}; 318 int d11a[6] = {58, 59, 71, 71, 72, 75}; 319 int d12a[3] = {10, 120, 130}; 320 int expected[31] = { 321 10, 40, 50, 51, 52, 54, 56, 56, 57, 58, 58, 59, 60, 62, 64, 65, 67, 322 70, 71, 71, 72, 75, 75, 75, 77, 78, 80, 90, 90, 120, 130 323 }; 324 325 CX_ARRAY_DECLARE(int, array); 326 cx_array_initialize(array, 4); 327 328 CX_TEST_DO { 329 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d1, cx_cmp_int)); 330 CX_TEST_ASSERT(array_size == 1); 331 CX_TEST_ASSERT(array_capacity == 4); 332 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d2, cx_cmp_int)); 333 CX_TEST_ASSERT(array_size == 2); 334 CX_TEST_ASSERT(array_capacity == 4); 335 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d3, cx_cmp_int)); 336 CX_TEST_ASSERT(array_size == 3); 337 CX_TEST_ASSERT(array_capacity == 4); 338 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d4, cx_cmp_int)); 339 CX_TEST_ASSERT(array_size == 4); 340 CX_TEST_ASSERT(array_capacity == 4); 341 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d5, cx_cmp_int)); 342 CX_TEST_ASSERT(array_size == 5); 343 CX_TEST_ASSERT(array_capacity >= 5); 344 CX_TEST_ASSERT(0 == cx_array_simple_insert_sorted(array, d6a, 6, cx_cmp_int)); 345 CX_TEST_ASSERT(array_size == 11); 346 CX_TEST_ASSERT(array_capacity >= 11); 347 CX_TEST_ASSERT(0 == cx_array_simple_insert_sorted(array, d7a, 6, cx_cmp_int)); 348 CX_TEST_ASSERT(array_size == 17); 349 CX_TEST_ASSERT(array_capacity >= 17); 350 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d8, cx_cmp_int)); 351 CX_TEST_ASSERT(array_size == 18); 352 CX_TEST_ASSERT(array_capacity >= 18); 353 CX_TEST_ASSERT(0 == cx_array_simple_add_sorted(array, d9, cx_cmp_int)); 354 CX_TEST_ASSERT(array_size == 19); 355 CX_TEST_ASSERT(array_capacity >= 19); 356 CX_TEST_ASSERT(0 == cx_array_simple_insert_sorted(array, d10a, 3, cx_cmp_int)); 357 CX_TEST_ASSERT(array_size == 22); 358 CX_TEST_ASSERT(array_capacity >= 22); 359 CX_TEST_ASSERT(0 == cx_array_simple_insert_sorted(array, d11a, 6, cx_cmp_int)); 360 CX_TEST_ASSERT(array_size == 28); 361 CX_TEST_ASSERT(array_capacity >= 28); 362 CX_TEST_ASSERT(0 == cx_array_simple_insert_sorted(array, d12a, 3, cx_cmp_int)); 363 CX_TEST_ASSERT(array_size == 31); 364 CX_TEST_ASSERT(array_capacity >= 31); 365 366 CX_TEST_ASSERT(0 == memcmp(array, expected, 31 * sizeof(int))); 367 } 368 cxFreeDefault(array); 369 } 370 371 CX_TEST(test_array_insert_unique) { 372 int d1 = 50; 373 int d2 = 80; 374 int d3 = 60; 375 int d4 = 40; 376 int d5 = 70; 377 int d6a[6] = {52, 54, 56, 62, 64, 75}; 378 int d7a[6] = {51, 57, 58, 65, 77, 78}; 379 int d8 = 90; 380 int d9 = 56; 381 int d10a[3] = {67, 75, 90}; 382 int d11a[8] = {90, 90, 90, 95, 95, 100, 110, 110}; 383 int expected[22] = { 384 40, 50, 51, 52, 54, 56, 57, 58, 60, 62, 64, 385 65, 67, 70, 75, 77, 78, 80, 90, 95, 100, 110 386 }; 387 388 CX_ARRAY_DECLARE(int, array); 389 cx_array_initialize(array, 4); 390 391 CX_TEST_DO { 392 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d1, cx_cmp_int)); 393 CX_TEST_ASSERT(array_size == 1); 394 CX_TEST_ASSERT(array_capacity == 4); 395 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d2, cx_cmp_int)); 396 CX_TEST_ASSERT(array_size == 2); 397 CX_TEST_ASSERT(array_capacity == 4); 398 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d3, cx_cmp_int)); 399 CX_TEST_ASSERT(array_size == 3); 400 CX_TEST_ASSERT(array_capacity == 4); 401 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d4, cx_cmp_int)); 402 CX_TEST_ASSERT(array_size == 4); 403 CX_TEST_ASSERT(array_capacity == 4); 404 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d5, cx_cmp_int)); 405 CX_TEST_ASSERT(array_size == 5); 406 CX_TEST_ASSERT(array_capacity >= 5); 407 CX_TEST_ASSERT(0 == cx_array_simple_insert_unique(array, d6a, 6, cx_cmp_int)); 408 CX_TEST_ASSERT(array_size == 11); 409 CX_TEST_ASSERT(array_capacity >= 11); 410 CX_TEST_ASSERT(0 == cx_array_simple_insert_unique(array, d7a, 6, cx_cmp_int)); 411 CX_TEST_ASSERT(array_size == 17); 412 CX_TEST_ASSERT(array_capacity >= 17); 413 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d8, cx_cmp_int)); 414 CX_TEST_ASSERT(array_size == 18); 415 CX_TEST_ASSERT(array_capacity >= 18); 416 CX_TEST_ASSERT(0 == cx_array_simple_add_unique(array, d9, cx_cmp_int)); 417 CX_TEST_ASSERT(array_size == 18); 418 CX_TEST_ASSERT(array_capacity >= 18); 419 CX_TEST_ASSERT(0 == cx_array_simple_insert_unique(array, d10a, 3, cx_cmp_int)); 420 CX_TEST_ASSERT(array_size == 19); 421 CX_TEST_ASSERT(array_capacity >= 19); 422 CX_TEST_ASSERT(0 == cx_array_simple_insert_unique(array, d11a, 8, cx_cmp_int)); 423 CX_TEST_ASSERT(array_size == 22); 424 CX_TEST_ASSERT(array_capacity >= 22); 425 426 CX_TEST_ASSERT(0 == memcmp(array, expected, 22 * sizeof(int))); 427 } 428 cxFreeDefault(array); 429 } 430 431 CX_TEST(test_array_binary_search) { 432 int array[18] = { 433 40, 50, 51, 52, 54, 56, 57, 58, 60, 434 62, 64, 65, 70, 75, 77, 78, 80, 90 435 }; 436 437 CX_TEST_DO { 438 for (size_t i = 0; i < 18; i++) { 439 CX_TEST_ASSERT(i == cx_array_binary_search(array, 18, sizeof(int), &array[i], cx_cmp_int)); 440 } 441 442 int s = 58; 443 CX_TEST_ASSERT(7 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 444 CX_TEST_ASSERT(7 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 445 s = 60; 446 CX_TEST_ASSERT(8 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 447 CX_TEST_ASSERT(8 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 448 s = 59; 449 CX_TEST_ASSERT(7 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 450 CX_TEST_ASSERT(8 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 451 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 452 s = 79; 453 CX_TEST_ASSERT(15 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 454 CX_TEST_ASSERT(16 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 455 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 456 s = 66; 457 CX_TEST_ASSERT(11 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 458 CX_TEST_ASSERT(12 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 459 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 460 s = 69; 461 CX_TEST_ASSERT(11 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 462 CX_TEST_ASSERT(12 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 463 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 464 s = 95; 465 CX_TEST_ASSERT(17 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 466 CX_TEST_ASSERT(18 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 467 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 468 s = 30; 469 CX_TEST_ASSERT(18 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 470 CX_TEST_ASSERT(0 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 471 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 472 473 // special case - size 0 474 s = 40; 475 CX_TEST_ASSERT(0 == cx_array_binary_search_inf(array, 0, sizeof(int), &s, cx_cmp_int)); 476 CX_TEST_ASSERT(0 == cx_array_binary_search_sup(array, 0, sizeof(int), &s, cx_cmp_int)); 477 CX_TEST_ASSERT(0 == cx_array_binary_search(array, 0, sizeof(int), &s, cx_cmp_int)); 478 479 // special case - size 1, searched element is smaller 480 s = 30; 481 CX_TEST_ASSERT(1 == cx_array_binary_search_inf(array, 1, sizeof(int), &s, cx_cmp_int)); 482 CX_TEST_ASSERT(0 == cx_array_binary_search_sup(array, 1, sizeof(int), &s, cx_cmp_int)); 483 CX_TEST_ASSERT(1 == cx_array_binary_search(array, 1, sizeof(int), &s, cx_cmp_int)); 484 485 // special case - size 1, searched element is larger 486 s = 50; 487 CX_TEST_ASSERT(0 == cx_array_binary_search_inf(array, 1, sizeof(int), &s, cx_cmp_int)); 488 CX_TEST_ASSERT(1 == cx_array_binary_search_sup(array, 1, sizeof(int), &s, cx_cmp_int)); 489 CX_TEST_ASSERT(1 == cx_array_binary_search(array, 1, sizeof(int), &s, cx_cmp_int)); 490 491 // special case - size 1, element matches 492 s = 40; 493 CX_TEST_ASSERT(0 == cx_array_binary_search_inf(array, 1, sizeof(int), &s, cx_cmp_int)); 494 CX_TEST_ASSERT(0 == cx_array_binary_search_sup(array, 1, sizeof(int), &s, cx_cmp_int)); 495 CX_TEST_ASSERT(0 == cx_array_binary_search(array, 1, sizeof(int), &s, cx_cmp_int)); 496 } 497 } 498 499 CX_TEST(test_array_binary_search_with_duplicates) { 500 int array[18] = { 501 40, 50, 55, 55, 55, 57, 57, 58, 60, 502 62, 64, 65, 70, 70, 70, 78, 80, 90 503 }; 504 int s; 505 CX_TEST_DO { 506 // exact matches (largest index on duplicate) 507 s = 40; 508 CX_TEST_ASSERT(0 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 509 s = 50; 510 CX_TEST_ASSERT(1 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 511 s = 55; 512 CX_TEST_ASSERT(4 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 513 s = 57; 514 CX_TEST_ASSERT(6 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 515 s = 58; 516 CX_TEST_ASSERT(7 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 517 s = 65; 518 CX_TEST_ASSERT(11 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 519 s = 70; 520 CX_TEST_ASSERT(14 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 521 s = 78; 522 CX_TEST_ASSERT(15 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 523 524 // not found 525 s = 30; 526 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 527 s = 75; 528 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 529 s = 52; 530 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 531 s = 100; 532 CX_TEST_ASSERT(18 == cx_array_binary_search(array, 18, sizeof(int), &s, cx_cmp_int)); 533 534 // infimum 535 s = 55; // also yields an exact match 536 CX_TEST_ASSERT(4 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 537 s = 56; 538 CX_TEST_ASSERT(4 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 539 s = 75; 540 CX_TEST_ASSERT(14 == cx_array_binary_search_inf(array, 18, sizeof(int), &s, cx_cmp_int)); 541 542 // supremum (smallest index) 543 s = 52; 544 CX_TEST_ASSERT(2 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 545 s = 66; 546 CX_TEST_ASSERT(12 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 547 s = 75; 548 CX_TEST_ASSERT(15 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 549 s = 70; // exact match, we want the smallest index 550 CX_TEST_ASSERT(12 == cx_array_binary_search_sup(array, 18, sizeof(int), &s, cx_cmp_int)); 551 } 552 } 553 554 typedef struct node { 555 struct node *next; 556 struct node *prev; 557 int data; 558 } node; 559 560 static int test_cmp_node(const void *l, const void *r) { 561 const node *left = l; 562 const node *right = r; 563 return left->data - right->data; 564 } 565 566 const ptrdiff_t loc_prev = offsetof(struct node, prev); 567 const ptrdiff_t loc_next = offsetof(struct node, next); 568 const ptrdiff_t loc_data = offsetof(struct node, data); 569 570 static node *create_nodes_test_data(size_t len) { 571 node *begin = calloc(1, sizeof(node)); 572 void *prev = begin; 573 for (size_t i = 1; i < len; i++) { 574 node *n = calloc(1, sizeof(node)); 575 cx_linked_list_link(prev, n, loc_prev, loc_next); 576 prev = n; 577 } 578 return begin; 579 } 580 581 void assign_nodes_test_data(node *n, ...) { 582 va_list ap; 583 va_start(ap, n); 584 while (n != NULL) { 585 n->data = va_arg(ap, int); 586 n = n->next; 587 } 588 va_end(ap); 589 } 590 591 static void destroy_nodes_test_data(node *n) { 592 while (n != NULL) { 593 void *next = n->next; 594 free(n); 595 n = next; 596 } 597 } 598 599 static int *int_test_data(size_t len) { 600 int *data = malloc(len*sizeof(int)); 601 for (size_t i = 0 ; i < len ; i++) { 602 data[i] = rand(); // NOLINT(*-msc50-cpp) 603 } 604 return data; 605 } 606 607 CX_TEST(test_linked_list_link_unlink) { 608 node a = {0}, b = {0}, c = {0}; 609 610 CX_TEST_DO { 611 cx_linked_list_link(&a, &b, loc_prev, loc_next); 612 CX_TEST_ASSERT(a.prev == NULL); 613 CX_TEST_ASSERT(a.next == &b); 614 CX_TEST_ASSERT(b.prev == &a); 615 CX_TEST_ASSERT(b.next == NULL); 616 617 cx_linked_list_unlink(&a, &b, loc_prev, loc_next); 618 CX_TEST_ASSERT(a.prev == NULL); 619 CX_TEST_ASSERT(a.next == NULL); 620 CX_TEST_ASSERT(b.prev == NULL); 621 CX_TEST_ASSERT(b.next == NULL); 622 623 cx_linked_list_link(&b, &c, loc_prev, loc_next); 624 cx_linked_list_link(&a, &b, loc_prev, loc_next); 625 cx_linked_list_unlink(&b, &c, loc_prev, loc_next); 626 CX_TEST_ASSERT(a.prev == NULL); 627 CX_TEST_ASSERT(a.next == &b); 628 CX_TEST_ASSERT(b.prev == &a); 629 CX_TEST_ASSERT(b.next == NULL); 630 CX_TEST_ASSERT(c.prev == NULL); 631 CX_TEST_ASSERT(c.next == NULL); 632 } 633 } 634 635 CX_TEST(test_linked_list_at) { 636 node a = {0}, b = {0}, c = {0}, d = {0}; 637 638 cx_linked_list_link(&a, &b, loc_prev, loc_next); 639 cx_linked_list_link(&b, &c, loc_prev, loc_next); 640 cx_linked_list_link(&c, &d, loc_prev, loc_next); 641 642 CX_TEST_DO { 643 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 0) == &a); 644 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 1) == &b); 645 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 2) == &c); 646 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 3) == &d); 647 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 4) == NULL); 648 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_prev, 0) == &a); 649 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 1) == &b); 650 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 2) == &c); 651 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 3) == &d); 652 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 4) == NULL); 653 CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 0) == &a); 654 CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 1) == &b); 655 } 656 } 657 658 CX_TEST(test_linked_list_find) { 659 node *list = create_nodes_test_data(4); 660 assign_nodes_test_data(list, 2, 4, 6, 8); 661 CX_TEST_DO { 662 size_t i = 10; 663 int s; 664 s = 2; 665 node *n = list; 666 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n); 667 CX_TEST_ASSERT(i == 0); 668 n = n->next; 669 s = 4; 670 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n); 671 CX_TEST_ASSERT(i == 1); 672 n = n->next; 673 s = 6; 674 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n); 675 CX_TEST_ASSERT(i == 2); 676 n = n->next; 677 s = 8; 678 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == n); 679 CX_TEST_ASSERT(i == 3); 680 s = 10; 681 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == NULL); 682 s = -2; 683 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s, &i) == NULL); 684 } 685 destroy_nodes_test_data(list); 686 } 687 688 CX_TEST(test_linked_list_compare) { 689 void *la = create_nodes_test_data(4); 690 void *lb = create_nodes_test_data(3); 691 void *lc = create_nodes_test_data(4); 692 assign_nodes_test_data(la, 2, 4, 6, 8); 693 assign_nodes_test_data(lb, 2, 4, 6); 694 assign_nodes_test_data(lc, 2, 4, 6, 9); 695 CX_TEST_DO { 696 CX_TEST_ASSERT(cx_linked_list_compare(la, lb, loc_next, loc_data, cx_cmp_int) > 0); 697 CX_TEST_ASSERT(cx_linked_list_compare(lb, la, loc_next, loc_data, cx_cmp_int) < 0); 698 CX_TEST_ASSERT(cx_linked_list_compare(lc, la, loc_next, loc_data, cx_cmp_int) > 0); 699 CX_TEST_ASSERT(cx_linked_list_compare(la, lc, loc_next, loc_data, cx_cmp_int) < 0); 700 CX_TEST_ASSERT(cx_linked_list_compare(la, la, loc_next, loc_data, cx_cmp_int) == 0); 701 } 702 destroy_nodes_test_data(la); 703 destroy_nodes_test_data(lb); 704 destroy_nodes_test_data(lc); 705 } 706 707 CX_TEST(test_linked_list_add) { 708 node nodes[4]; 709 void *begin, *end; 710 CX_TEST_DO { 711 // test with begin, end / prev, next 712 memset(nodes, 0, sizeof(node)*4); 713 end = begin = NULL; 714 715 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]); 716 CX_TEST_ASSERT(begin == &nodes[0]); 717 CX_TEST_ASSERT(end == &nodes[0]); 718 CX_TEST_ASSERT(nodes[0].prev == NULL); 719 CX_TEST_ASSERT(nodes[0].next == NULL); 720 721 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]); 722 CX_TEST_ASSERT(begin == &nodes[0]); 723 CX_TEST_ASSERT(end == &nodes[1]); 724 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); 725 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); 726 727 // test with begin only / prev, next 728 memset(nodes, 0, sizeof(node)*4); 729 end = begin = NULL; 730 731 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]); 732 CX_TEST_ASSERT(begin == &nodes[0]); 733 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]); 734 CX_TEST_ASSERT(begin == &nodes[0]); 735 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); 736 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); 737 738 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]); 739 CX_TEST_ASSERT(nodes[1].next == &nodes[2]); 740 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]); 741 742 // test with end only / prev, next 743 memset(nodes, 0, sizeof(node)*4); 744 end = begin = NULL; 745 746 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]); 747 CX_TEST_ASSERT(end == &nodes[0]); 748 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]); 749 CX_TEST_ASSERT(end == &nodes[1]); 750 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); 751 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]); 752 753 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]); 754 CX_TEST_ASSERT(end == &nodes[2]); 755 CX_TEST_ASSERT(nodes[1].next == &nodes[2]); 756 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]); 757 758 // test with begin, end / next 759 memset(nodes, 0, sizeof(node)*4); 760 end = begin = NULL; 761 762 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]); 763 CX_TEST_ASSERT(begin == &nodes[0]); 764 CX_TEST_ASSERT(end == &nodes[0]); 765 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]); 766 CX_TEST_ASSERT(end == &nodes[1]); 767 CX_TEST_ASSERT(nodes[0].next == &nodes[1]); 768 CX_TEST_ASSERT(nodes[1].prev == NULL); 769 } 770 } 771 772 CX_TEST(test_linked_list_prepend) { 773 node nodes[4]; 774 void *begin, *end; 775 CX_TEST_DO { 776 // test with begin, end / prev, next 777 memset(nodes, 0, sizeof(node) * 4); 778 end = begin = NULL; 779 780 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]); 781 CX_TEST_ASSERT(begin == &nodes[0]); 782 CX_TEST_ASSERT(end == &nodes[0]); 783 CX_TEST_ASSERT(nodes[0].prev == NULL); 784 CX_TEST_ASSERT(nodes[0].next == NULL); 785 786 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]); 787 CX_TEST_ASSERT(begin == &nodes[1]); 788 CX_TEST_ASSERT(end == &nodes[0]); 789 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); 790 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); 791 792 // test with begin only / prev, next 793 memset(nodes, 0, sizeof(node) * 4); 794 end = begin = NULL; 795 796 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]); 797 CX_TEST_ASSERT(begin == &nodes[0]); 798 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]); 799 CX_TEST_ASSERT(begin == &nodes[1]); 800 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); 801 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); 802 803 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]); 804 CX_TEST_ASSERT(begin == &nodes[2]); 805 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); 806 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]); 807 808 // test with end only / prev, next 809 memset(nodes, 0, sizeof(node) * 4); 810 end = begin = NULL; 811 812 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]); 813 CX_TEST_ASSERT(end == &nodes[0]); 814 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]); 815 CX_TEST_ASSERT(end == &nodes[0]); 816 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); 817 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]); 818 819 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]); 820 CX_TEST_ASSERT(end == &nodes[0]); 821 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); 822 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]); 823 824 // test with begin, end / next 825 memset(nodes, 0, sizeof(node) * 4); 826 end = begin = NULL; 827 828 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]); 829 CX_TEST_ASSERT(begin == &nodes[0]); 830 CX_TEST_ASSERT(end == &nodes[0]); 831 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]); 832 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]); 833 CX_TEST_ASSERT(begin == &nodes[2]); 834 CX_TEST_ASSERT(end == &nodes[0]); 835 CX_TEST_ASSERT(nodes[1].next == &nodes[0]); 836 CX_TEST_ASSERT(nodes[2].next == &nodes[1]); 837 CX_TEST_ASSERT(nodes[1].prev == NULL); 838 CX_TEST_ASSERT(nodes[0].prev == NULL); 839 } 840 } 841 842 CX_TEST(test_linked_list_insert) { 843 node nodes[4]; 844 void *begin, *end; 845 CX_TEST_DO { 846 // insert mid list 847 memset(nodes, 0, sizeof(node) * 4); 848 begin = &nodes[0]; 849 end = &nodes[2]; 850 851 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 852 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 853 854 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]); 855 CX_TEST_ASSERT(begin == &nodes[0]); 856 CX_TEST_ASSERT(end == &nodes[2]); 857 CX_TEST_ASSERT(nodes[1].next == &nodes[3]); 858 CX_TEST_ASSERT(nodes[2].prev == &nodes[3]); 859 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]); 860 CX_TEST_ASSERT(nodes[3].next == &nodes[2]); 861 862 // insert end 863 memset(nodes, 0, sizeof(node) * 4); 864 begin = &nodes[0]; 865 end = &nodes[2]; 866 867 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 868 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 869 870 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]); 871 CX_TEST_ASSERT(begin == &nodes[0]); 872 CX_TEST_ASSERT(end == &nodes[3]); 873 CX_TEST_ASSERT(nodes[2].next == &nodes[3]); 874 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]); 875 CX_TEST_ASSERT(nodes[3].next == NULL); 876 877 // insert begin 878 memset(nodes, 0, sizeof(node) * 4); 879 begin = &nodes[0]; 880 end = &nodes[2]; 881 882 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 883 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 884 885 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]); 886 CX_TEST_ASSERT(begin == &nodes[3]); 887 CX_TEST_ASSERT(end == &nodes[2]); 888 CX_TEST_ASSERT(nodes[0].prev == &nodes[3]); 889 CX_TEST_ASSERT(nodes[3].prev == NULL); 890 CX_TEST_ASSERT(nodes[3].next == &nodes[0]); 891 } 892 } 893 894 CX_TEST(test_linked_list_insert_chain) { 895 node nodes[5]; 896 void *begin, *end; 897 CX_TEST_DO { 898 // insert mid list 899 memset(nodes, 0, sizeof(node) * 5); 900 begin = &nodes[0]; end = &nodes[2]; 901 902 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 903 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 904 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); 905 906 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL); 907 CX_TEST_ASSERT(begin == &nodes[0]); 908 CX_TEST_ASSERT(end == &nodes[2]); 909 CX_TEST_ASSERT(nodes[1].next == &nodes[3]); 910 CX_TEST_ASSERT(nodes[2].prev == &nodes[4]); 911 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]); 912 CX_TEST_ASSERT(nodes[4].next == &nodes[2]); 913 914 // insert end 915 memset(nodes, 0, sizeof(node) * 5); 916 begin = &nodes[0]; end = &nodes[2]; 917 918 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 919 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 920 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); 921 922 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL); 923 CX_TEST_ASSERT(begin == &nodes[0]); 924 CX_TEST_ASSERT(end == &nodes[4]); 925 CX_TEST_ASSERT(nodes[2].next == &nodes[3]); 926 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]); 927 CX_TEST_ASSERT(nodes[4].next == NULL); 928 929 // insert begin 930 memset(nodes, 0, sizeof(node) * 5); 931 begin = &nodes[0]; end = &nodes[2]; 932 933 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next); 934 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next); 935 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next); 936 937 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL); 938 CX_TEST_ASSERT(begin == &nodes[3]); 939 CX_TEST_ASSERT(end == &nodes[2]); 940 CX_TEST_ASSERT(nodes[0].prev == &nodes[4]); 941 CX_TEST_ASSERT(nodes[3].prev == NULL); 942 CX_TEST_ASSERT(nodes[4].next == &nodes[0]); 943 } 944 } 945 946 CX_TEST(test_linked_list_insert_sorted) { 947 node nodes[5] = {0}; 948 void *begin, *end; 949 nodes[0].data = 3; 950 nodes[1].data = 6; 951 nodes[2].data = 10; 952 nodes[3].data = 11; 953 nodes[4].data = 15; 954 for (unsigned i = 0 ; i < 4 ; i++) { 955 cx_linked_list_link(&nodes[i], &nodes[i+1], loc_prev, loc_next); 956 } 957 begin = &nodes[0]; 958 end = &nodes[4]; 959 CX_TEST_DO { 960 // insert a single node 961 node new_node = {0}; 962 new_node.data = 5; 963 cx_linked_list_insert_sorted( 964 &begin, &end, 965 loc_prev, loc_next, 966 &new_node, test_cmp_node 967 ); 968 CX_TEST_ASSERT(new_node.prev == &nodes[0]); 969 CX_TEST_ASSERT(new_node.next == &nodes[1]); 970 CX_TEST_ASSERT(nodes[0].next == &new_node); 971 CX_TEST_ASSERT(nodes[1].prev == &new_node); 972 CX_TEST_ASSERT(begin == &nodes[0]); 973 CX_TEST_ASSERT(end == &nodes[4]); 974 975 // insert a new beginning node 976 node new_begin = {0}; 977 new_begin.data = 1; 978 cx_linked_list_insert_sorted( 979 &begin, &end, 980 loc_prev, loc_next, 981 &new_begin, test_cmp_node 982 ); 983 CX_TEST_ASSERT(new_begin.prev == NULL); 984 CX_TEST_ASSERT(new_begin.next == &nodes[0]); 985 CX_TEST_ASSERT(nodes[0].prev == &new_begin); 986 CX_TEST_ASSERT(begin == &new_begin); 987 CX_TEST_ASSERT(end == &nodes[4]); 988 989 // duplicate the beginning node 990 // (expectation is that the duplicate is inserted after the first node) 991 node new_begin_dup = {0}; 992 new_begin_dup.data = 1; 993 cx_linked_list_insert_sorted( 994 &begin, &end, 995 loc_prev, loc_next, 996 &new_begin_dup, test_cmp_node 997 ); 998 CX_TEST_ASSERT(new_begin_dup.prev == &new_begin); 999 CX_TEST_ASSERT(new_begin_dup.next == &nodes[0]); 1000 CX_TEST_ASSERT(nodes[0].prev == &new_begin_dup); 1001 CX_TEST_ASSERT(new_begin.next == &new_begin_dup); 1002 CX_TEST_ASSERT(begin == &new_begin); 1003 CX_TEST_ASSERT(end == &nodes[4]); 1004 1005 // now insert a chain 1006 node chain_start = {NULL, NULL, 8}; 1007 node chain_mid = {NULL, NULL, 14}; 1008 node chain_end = {NULL, NULL, 17}; 1009 cx_linked_list_link(&chain_start, &chain_mid, loc_prev, loc_next); 1010 cx_linked_list_link(&chain_mid, &chain_end, loc_prev, loc_next); 1011 1012 cx_linked_list_insert_sorted_chain( 1013 &begin, &end, 1014 loc_prev, loc_next, 1015 &chain_start, test_cmp_node 1016 ); 1017 1018 CX_TEST_ASSERT(chain_start.prev == &nodes[1]); 1019 CX_TEST_ASSERT(chain_start.next == &nodes[2]); 1020 CX_TEST_ASSERT(chain_mid.prev == &nodes[3]); 1021 CX_TEST_ASSERT(chain_mid.next == &nodes[4]); 1022 CX_TEST_ASSERT(chain_end.prev == &nodes[4]); 1023 CX_TEST_ASSERT(chain_end.next == NULL); 1024 CX_TEST_ASSERT(begin == &new_begin); 1025 CX_TEST_ASSERT(end == &chain_end); 1026 } 1027 } 1028 1029 CX_TEST(test_linked_list_insert_unique) { 1030 node nodes[5] = {0}; 1031 void *begin, *end; 1032 nodes[0].data = 3; 1033 nodes[1].data = 6; 1034 nodes[2].data = 10; 1035 nodes[3].data = 11; 1036 nodes[4].data = 15; 1037 for (unsigned i = 0 ; i < 4 ; i++) { 1038 cx_linked_list_link(&nodes[i], &nodes[i+1], loc_prev, loc_next); 1039 } 1040 begin = &nodes[0]; 1041 end = &nodes[4]; 1042 CX_TEST_DO { 1043 // insert a single node 1044 node new_node = {0}; 1045 new_node.data = 5; 1046 CX_TEST_ASSERT(0 == cx_linked_list_insert_unique( 1047 &begin, &end, 1048 loc_prev, loc_next, 1049 &new_node, test_cmp_node 1050 )); 1051 CX_TEST_ASSERT(new_node.prev == &nodes[0]); 1052 CX_TEST_ASSERT(new_node.next == &nodes[1]); 1053 CX_TEST_ASSERT(nodes[0].next == &new_node); 1054 CX_TEST_ASSERT(nodes[1].prev == &new_node); 1055 CX_TEST_ASSERT(begin == &nodes[0]); 1056 CX_TEST_ASSERT(end == &nodes[4]); 1057 1058 // now as duplicate 1059 node new_node_dup = {0}; 1060 new_node_dup.data = 5; 1061 CX_TEST_ASSERT(0 != cx_linked_list_insert_unique( 1062 &begin, &end, 1063 loc_prev, loc_next, 1064 &new_node_dup, test_cmp_node 1065 )); 1066 CX_TEST_ASSERT(new_node_dup.prev == NULL); 1067 CX_TEST_ASSERT(new_node_dup.next == NULL); 1068 CX_TEST_ASSERT(new_node.prev == &nodes[0]); 1069 CX_TEST_ASSERT(new_node.next == &nodes[1]); 1070 CX_TEST_ASSERT(nodes[0].next == &new_node); 1071 CX_TEST_ASSERT(nodes[1].prev == &new_node); 1072 CX_TEST_ASSERT(begin == &nodes[0]); 1073 CX_TEST_ASSERT(end == &nodes[4]); 1074 1075 // insert a new beginning node 1076 node new_begin = {0}; 1077 new_begin.data = 1; 1078 CX_TEST_ASSERT(0 == cx_linked_list_insert_unique( 1079 &begin, &end, 1080 loc_prev, loc_next, 1081 &new_begin, test_cmp_node 1082 )); 1083 CX_TEST_ASSERT(new_begin.prev == NULL); 1084 CX_TEST_ASSERT(new_begin.next == &nodes[0]); 1085 CX_TEST_ASSERT(nodes[0].prev == &new_begin); 1086 CX_TEST_ASSERT(begin == &new_begin); 1087 CX_TEST_ASSERT(end == &nodes[4]); 1088 1089 // now as duplicate 1090 node new_begin_dup = {0}; 1091 new_begin_dup.data = 1; 1092 CX_TEST_ASSERT(0 != cx_linked_list_insert_unique( 1093 &begin, &end, 1094 loc_prev, loc_next, 1095 &new_begin_dup, test_cmp_node 1096 )); 1097 CX_TEST_ASSERT(new_begin_dup.prev == NULL); 1098 CX_TEST_ASSERT(new_begin_dup.next == NULL); 1099 CX_TEST_ASSERT(new_begin.prev == NULL); 1100 CX_TEST_ASSERT(new_begin.next == &nodes[0]); 1101 CX_TEST_ASSERT(nodes[0].prev == &new_begin); 1102 CX_TEST_ASSERT(begin == &new_begin); 1103 CX_TEST_ASSERT(end == &nodes[4]); 1104 1105 // now insert a chain with two duplicates 1106 node chain_start = {NULL, NULL, 8}; 1107 node chain_mid1 = {NULL, NULL, 11}; 1108 node chain_mid2 = {NULL, NULL, 14}; 1109 node chain_mid3 = {NULL, NULL, 15}; 1110 node chain_mid4 = {NULL, NULL, 15}; 1111 node chain_end = {NULL, NULL, 17}; 1112 cx_linked_list_link(&chain_start, &chain_mid1, loc_prev, loc_next); 1113 cx_linked_list_link(&chain_mid1, &chain_mid2, loc_prev, loc_next); 1114 cx_linked_list_link(&chain_mid2, &chain_mid3, loc_prev, loc_next); 1115 cx_linked_list_link(&chain_mid3, &chain_mid4, loc_prev, loc_next); 1116 cx_linked_list_link(&chain_mid4, &chain_end, loc_prev, loc_next); 1117 1118 node *dup_start = cx_linked_list_insert_unique_chain( 1119 &begin, &end, 1120 loc_prev, loc_next, 1121 &chain_start, test_cmp_node 1122 ); 1123 1124 CX_TEST_ASSERT(chain_start.prev == &nodes[1]); 1125 CX_TEST_ASSERT(chain_start.next == &nodes[2]); 1126 CX_TEST_ASSERT(chain_mid2.prev == &nodes[3]); 1127 CX_TEST_ASSERT(chain_mid2.next == &nodes[4]); 1128 CX_TEST_ASSERT(chain_end.prev == &nodes[4]); 1129 CX_TEST_ASSERT(chain_end.next == NULL); 1130 CX_TEST_ASSERT(begin == &new_begin); 1131 CX_TEST_ASSERT(end == &chain_end); 1132 1133 // the duplicates 1134 CX_TEST_ASSERT(dup_start == &chain_mid1); 1135 CX_TEST_ASSERT(dup_start->prev == NULL); 1136 CX_TEST_ASSERT(dup_start->next == &chain_mid3); 1137 CX_TEST_ASSERT(chain_mid3.prev == &chain_mid1); 1138 CX_TEST_ASSERT(chain_mid3.next == &chain_mid4); 1139 CX_TEST_ASSERT(chain_mid4.prev == &chain_mid3); 1140 CX_TEST_ASSERT(chain_mid4.next == NULL); 1141 } 1142 } 1143 1144 CX_TEST(test_linked_list_first) { 1145 node *testdata = create_nodes_test_data(3); 1146 void *begin = testdata; 1147 CX_TEST_DO { 1148 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata, loc_prev)); 1149 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next, loc_prev)); 1150 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next->next, loc_prev)); 1151 } 1152 destroy_nodes_test_data(testdata); 1153 } 1154 1155 CX_TEST(test_linked_list_last) { 1156 node *testdata = create_nodes_test_data(3); 1157 void *end = testdata->next->next; 1158 CX_TEST_DO { 1159 CX_TEST_ASSERT(end == cx_linked_list_last(testdata, loc_next)); 1160 CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next, loc_next)); 1161 CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next->next, loc_next)); 1162 } 1163 destroy_nodes_test_data(testdata); 1164 } 1165 1166 CX_TEST(test_linked_list_prev) { 1167 node *testdata = create_nodes_test_data(3); 1168 CX_TEST_DO { 1169 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata) == NULL); 1170 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next) == testdata); 1171 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next->next) == testdata->next); 1172 } 1173 destroy_nodes_test_data(testdata); 1174 } 1175 1176 CX_TEST(test_linked_list_remove) { 1177 node *testdata = create_nodes_test_data(3); 1178 assign_nodes_test_data(testdata, 2, 4, 6); 1179 node *first = testdata; 1180 node *second = first->next; 1181 node *third = second->next; 1182 void *begin = testdata; 1183 void *end = third; 1184 1185 CX_TEST_DO { 1186 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second); 1187 CX_TEST_ASSERT(begin == first); 1188 CX_TEST_ASSERT(end == third); 1189 CX_TEST_ASSERT(first->prev == NULL); 1190 CX_TEST_ASSERT(first->next == third); 1191 CX_TEST_ASSERT(third->prev == first); 1192 CX_TEST_ASSERT(third->next == NULL); 1193 1194 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third); 1195 CX_TEST_ASSERT(begin == first); 1196 CX_TEST_ASSERT(end == first); 1197 CX_TEST_ASSERT(first->prev == NULL); 1198 CX_TEST_ASSERT(first->next == NULL); 1199 1200 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first); 1201 CX_TEST_ASSERT(begin == NULL); 1202 CX_TEST_ASSERT(end == NULL); 1203 } 1204 // list is not intact anymore, we have to free nodes individually 1205 free(first); 1206 free(second); 1207 free(third); 1208 } 1209 1210 CX_TEST(test_linked_list_remove_chain) { 1211 node *testdata = create_nodes_test_data(5); 1212 assign_nodes_test_data(testdata, 2, 4, 6, 8, 10); 1213 void *begin = testdata; 1214 void *end = cx_linked_list_last(testdata, loc_next); 1215 void *orig_end = end; 1216 // remember what we need to free 1217 node *kill_list[5]; 1218 kill_list[0] = testdata; 1219 for (unsigned i = 1 ; i < 5 ; i++) { 1220 kill_list[i] = kill_list[i-1]->next; 1221 } 1222 1223 CX_TEST_DO { 1224 // remove chain, but pretend that we don't have a prev pointer! 1225 size_t result = cx_linked_list_remove_chain( 1226 &begin, &end, -1, loc_next, 1227 cx_linked_list_at(begin, 0, loc_next, 2), 1228 2 1229 ); 1230 CX_TEST_ASSERT(result == 2); 1231 CX_TEST_ASSERT(begin == testdata); 1232 CX_TEST_ASSERT(end == orig_end); 1233 node *new_idx2 = cx_linked_list_at(begin, 0, loc_next, 2); 1234 CX_TEST_ASSERT(new_idx2->data == 10); 1235 CX_TEST_ASSERT(new_idx2->next == NULL); 1236 // we pretended we don't have prev, so it still points to 8! 1237 CX_TEST_ASSERT(new_idx2->prev->data == 8); 1238 1239 // remove last elements and try to remove more than we have 1240 result = cx_linked_list_remove_chain( 1241 &begin, &end, -1, loc_next, 1242 cx_linked_list_at(begin, 0, loc_next, 2), 1243 2 1244 ); 1245 CX_TEST_ASSERT(result == 1); 1246 CX_TEST_ASSERT(begin == testdata); 1247 CX_TEST_ASSERT(end == testdata->next); 1248 CX_TEST_ASSERT(NULL == testdata->next->next); 1249 } 1250 1251 for (unsigned i = 0 ; i < 5 ; i++) { 1252 free(kill_list[i]); 1253 } 1254 } 1255 1256 CX_TEST(test_linked_list_size) { 1257 node *td5 = create_nodes_test_data(5); 1258 node *td13 = create_nodes_test_data(13); 1259 CX_TEST_DO { 1260 CX_TEST_ASSERT(cx_linked_list_size(NULL, loc_next) == 0); 1261 CX_TEST_ASSERT(cx_linked_list_size(td5, loc_next) == 5); 1262 CX_TEST_ASSERT(cx_linked_list_size(td13, loc_next) == 13); 1263 } 1264 destroy_nodes_test_data(td5); 1265 destroy_nodes_test_data(td13); 1266 } 1267 1268 CX_TEST(test_linked_list_sort_empty) { 1269 void *begin = NULL; 1270 CX_TEST_DO { 1271 // cannot assert something, we can just test that it does not crash 1272 cx_linked_list_sort(&begin, NULL, loc_prev, loc_next, loc_data, cx_cmp_int); 1273 CX_TEST_ASSERT(true); 1274 } 1275 } 1276 1277 CX_TEST(test_linked_list_sort) { 1278 const size_t len = 1500; 1279 int *testdata = int_test_data(len); 1280 void *scrambled = create_nodes_test_data(len); 1281 node *n = scrambled; 1282 for (size_t i = 0; i < len; i++) { 1283 n->data = testdata[i]; 1284 n = n->next; 1285 } 1286 int *sorted = malloc(len*sizeof(int)); 1287 memcpy(sorted, testdata, len*sizeof(int)); 1288 qsort(sorted, len, sizeof(int), cx_cmp_int); 1289 1290 void *begin = scrambled; 1291 void *end = cx_linked_list_last(begin, loc_next); 1292 1293 CX_TEST_DO { 1294 cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, cx_cmp_int); 1295 node *check = begin; 1296 node *check_last = NULL; 1297 for (size_t i = 0; i < len; i++) { 1298 CX_TEST_ASSERT(check->data == sorted[i]); 1299 CX_TEST_ASSERT(check->prev == check_last); 1300 if (i < len - 1) { 1301 CX_TEST_ASSERT(check->next != NULL); 1302 } 1303 check_last = check; 1304 check = check->next; 1305 } 1306 CX_TEST_ASSERT(check == NULL); 1307 CX_TEST_ASSERT(end == check_last); 1308 } 1309 destroy_nodes_test_data(begin); 1310 free(sorted); 1311 free(testdata); 1312 } 1313 1314 CX_TEST(test_linked_list_reverse) { 1315 void *testdata = create_nodes_test_data(4); 1316 void *expected = create_nodes_test_data(4); 1317 assign_nodes_test_data(testdata, 2, 4, 6, 8); 1318 assign_nodes_test_data(expected, 8, 6, 4, 2); 1319 void *begin = testdata; 1320 CX_TEST_DO { 1321 void *end = cx_linked_list_last(begin, loc_next); 1322 void *orig_begin = begin, *orig_end = end; 1323 1324 cx_linked_list_reverse(&begin, &end, loc_prev, loc_next); 1325 CX_TEST_ASSERT(end == orig_begin); 1326 CX_TEST_ASSERT(begin == orig_end); 1327 CX_TEST_ASSERT(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, cx_cmp_int)); 1328 } 1329 destroy_nodes_test_data(begin); 1330 destroy_nodes_test_data(expected); 1331 } 1332 1333 1334 CX_TEST(test_empty_list_size) { 1335 CX_TEST_DO { 1336 CX_TEST_ASSERT(cxEmptyList->collection.size == 0); 1337 CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0); 1338 } 1339 } 1340 1341 CX_TEST(test_empty_list_iterator) { 1342 CxList *list = cxEmptyList; 1343 1344 CxIterator it1 = cxListIterator(list); 1345 CxIterator it2 = cxListBackwardsIterator(list); 1346 1347 CX_TEST_DO { 1348 CX_TEST_ASSERT(!cxIteratorValid(it1)); 1349 CX_TEST_ASSERT(!cxIteratorValid(it2)); 1350 1351 int c = 0; 1352 cx_foreach(void*, data, it1) c++; 1353 cx_foreach(void*, data, it2) c++; 1354 CX_TEST_ASSERT(c == 0); 1355 } 1356 } 1357 1358 CX_TEST(test_null_list_iterator) { 1359 CxList *list = NULL; 1360 1361 CxIterator it1 = cxListIterator(list); 1362 CxIterator it2 = cxListBackwardsIterator(list); 1363 CxIterator it3 = cxListIteratorAt(list, 0); 1364 CxIterator it4 = cxListBackwardsIteratorAt(list, 0); 1365 1366 CX_TEST_DO { 1367 CX_TEST_ASSERT(!cxIteratorValid(it1)); 1368 CX_TEST_ASSERT(!cxIteratorValid(it2)); 1369 CX_TEST_ASSERT(!cxIteratorValid(it3)); 1370 CX_TEST_ASSERT(!cxIteratorValid(it4)); 1371 1372 int c = 0; 1373 cx_foreach(void*, data, it1) c++; 1374 cx_foreach(void*, data, it2) c++; 1375 cx_foreach(void*, data, it3) c++; 1376 cx_foreach(void*, data, it4) c++; 1377 CX_TEST_ASSERT(c == 0); 1378 } 1379 } 1380 1381 CX_TEST(test_empty_list_noops) { 1382 CX_TEST_DO { 1383 CxList copy = *cxEmptyList; 1384 cxListSort(cxEmptyList); 1385 cxListClear(cxEmptyList); 1386 cxListFree(cxEmptyList); 1387 CX_TEST_ASSERT(0 == memcmp(&copy, cxEmptyList, sizeof(CxList))); // NOLINT(*-suspicious-memory-comparison) 1388 } 1389 } 1390 1391 CX_TEST(test_empty_list_at) { 1392 CX_TEST_DO { 1393 // the placeholder empty list 1394 CX_TEST_ASSERT(cxListAt(cxEmptyList, 0) == NULL); 1395 CX_TEST_ASSERT(cxListAt(cxEmptyList, 1) == NULL); 1396 // a "true" empty list 1397 CxList *list = cxLinkedListCreateSimple(sizeof(int)); 1398 CX_TEST_ASSERT(cxListAt(list, 0) == NULL); 1399 CX_TEST_ASSERT(cxListAt(list, 1) == NULL); 1400 cxListFree(list); 1401 } 1402 } 1403 1404 CX_TEST(test_empty_list_find) { 1405 int x = 42, y = 1337; 1406 CX_TEST_DO { 1407 // the placeholder empty list 1408 CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) == 0); 1409 CX_TEST_ASSERT(cxListFindRemove(cxEmptyList, &y) == 0); 1410 // a "true" empty list 1411 CxList *list = cxLinkedListCreateSimple(sizeof(int)); 1412 CX_TEST_ASSERT(cxListFind(list, &x) == 0); 1413 CX_TEST_ASSERT(cxListFindRemove(list, &y) == 0); 1414 cxListFree(list); 1415 } 1416 } 1417 1418 CX_TEST(test_empty_list_compare) { 1419 CxList *empty = cxEmptyList; 1420 CxList *ll = cxLinkedListCreateSimple(sizeof(int)); 1421 CxList *al = cxArrayListCreateSimple(sizeof(int), 8); 1422 int x = 5; 1423 CX_TEST_DO { 1424 CX_TEST_ASSERT(0 == cxListCompare(empty, cxEmptyList)); 1425 CX_TEST_ASSERT(0 == cxListCompare(ll, cxEmptyList)); 1426 CX_TEST_ASSERT(0 == cxListCompare(al, cxEmptyList)); 1427 CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, ll)); 1428 CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, al)); 1429 1430 cxListAdd(ll, &x); 1431 cxListAdd(al, &x); 1432 1433 CX_TEST_ASSERT(0 < cxListCompare(ll, cxEmptyList)); 1434 CX_TEST_ASSERT(0 < cxListCompare(al, cxEmptyList)); 1435 CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, ll)); 1436 CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, al)); 1437 } 1438 cxListFree(ll); 1439 cxListFree(al); 1440 } 1441 1442 CX_TEST(test_null_list_free) { 1443 CX_TEST_DO { 1444 // cannot really verify, but asan or valgrind would complain 1445 cxListFree(NULL); 1446 } 1447 } 1448 1449 CX_TEST(test_list_ll_create) { 1450 CxTestingAllocator talloc; 1451 cx_testing_allocator_init(&talloc); 1452 CxAllocator *alloc = &talloc.base; 1453 CX_TEST_DO { 1454 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); 1455 CX_TEST_ASSERT(list != NULL); 1456 CX_TEST_ASSERT(list->collection.elem_size == sizeof(int)); 1457 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1458 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1459 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1460 CX_TEST_ASSERT(cxListSize(list) == 0); 1461 CX_TEST_ASSERT(list->collection.allocator == alloc); 1462 CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int); 1463 CX_TEST_ASSERT(!list->collection.store_pointer); 1464 cxListFree(list); 1465 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1466 } 1467 cx_testing_allocator_destroy(&talloc); 1468 } 1469 1470 CX_TEST(test_list_ll_create_simple) { 1471 CxList *list = cxLinkedListCreateSimple(sizeof(int)); 1472 CX_TEST_DO { 1473 CX_TEST_ASSERT(list != NULL); 1474 CX_TEST_ASSERT(list->collection.elem_size == sizeof(int)); 1475 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1476 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1477 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1478 CX_TEST_ASSERT(cxListSize(list) == 0); 1479 CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator); 1480 CX_TEST_ASSERT(list->collection.cmpfunc == NULL); 1481 CX_TEST_ASSERT(!list->collection.store_pointer); 1482 } 1483 cxListFree(list); 1484 } 1485 1486 CX_TEST(test_list_ll_create_simple_for_pointers) { 1487 CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS); 1488 CX_TEST_DO { 1489 CX_TEST_ASSERT(list != NULL); 1490 CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*)); 1491 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1492 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1493 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1494 CX_TEST_ASSERT(cxListSize(list) == 0); 1495 CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator); 1496 CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr); 1497 CX_TEST_ASSERT(list->collection.store_pointer); 1498 } 1499 cxListFree(list); 1500 } 1501 1502 CX_TEST(test_list_arl_create) { 1503 CxTestingAllocator talloc; 1504 cx_testing_allocator_init(&talloc); 1505 CxAllocator *alloc = &talloc.base; 1506 CX_TEST_DO { 1507 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); 1508 CX_TEST_ASSERT(list != NULL); 1509 CX_TEST_ASSERT(list->collection.elem_size == sizeof(int)); 1510 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1511 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1512 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1513 CX_TEST_ASSERT(cxListSize(list) == 0); 1514 CX_TEST_ASSERT(list->collection.allocator == alloc); 1515 CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_int); 1516 CX_TEST_ASSERT(!list->collection.store_pointer); 1517 cxListFree(list); 1518 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1519 } 1520 cx_testing_allocator_destroy(&talloc); 1521 } 1522 1523 CX_TEST(test_list_arl_create_simple) { 1524 CxList *list = cxArrayListCreateSimple(sizeof(int), 8); 1525 CX_TEST_DO { 1526 CX_TEST_ASSERT(list != NULL); 1527 CX_TEST_ASSERT(list->collection.elem_size == sizeof(int)); 1528 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1529 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1530 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1531 CX_TEST_ASSERT(cxListSize(list) == 0); 1532 CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator); 1533 CX_TEST_ASSERT(list->collection.cmpfunc == NULL); 1534 CX_TEST_ASSERT(!list->collection.store_pointer); 1535 } 1536 cxListFree(list); 1537 } 1538 1539 CX_TEST(test_list_arl_create_simple_for_pointers) { 1540 CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8); 1541 CX_TEST_DO { 1542 CX_TEST_ASSERT(list != NULL); 1543 CX_TEST_ASSERT(list->collection.elem_size == sizeof(void*)); 1544 CX_TEST_ASSERT(list->collection.simple_destructor == NULL); 1545 CX_TEST_ASSERT(list->collection.advanced_destructor == NULL); 1546 CX_TEST_ASSERT(list->collection.destructor_data == NULL); 1547 CX_TEST_ASSERT(cxListSize(list) == 0); 1548 CX_TEST_ASSERT(list->collection.allocator == cxDefaultAllocator); 1549 CX_TEST_ASSERT(list->collection.cmpfunc == cx_cmp_ptr); 1550 CX_TEST_ASSERT(list->collection.store_pointer); 1551 } 1552 cxListFree(list); 1553 } 1554 1555 static void test_fake_simple_int_destr(void *elem) { 1556 *(int *) elem = 42; 1557 } 1558 1559 CX_TEST(test_list_pll_destroy_no_destr) { 1560 CxTestingAllocator talloc; 1561 cx_testing_allocator_init(&talloc); 1562 CxAllocator *alloc = &talloc.base; 1563 CX_TEST_DO { 1564 void *item = cxMalloc(alloc, sizeof(int)); 1565 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1566 cxListAdd(list, item); 1567 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1568 cxListFree(list); 1569 // item is not yet freed 1570 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1571 cxFree(alloc, item); 1572 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1573 } 1574 cx_testing_allocator_destroy(&talloc); 1575 } 1576 1577 CX_TEST(test_list_pll_destroy_simple_destr) { 1578 CX_TEST_DO { 1579 int item = 0; 1580 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1581 list->collection.simple_destructor = test_fake_simple_int_destr; 1582 cxListAdd(list, &item); 1583 cxListFree(list); 1584 CX_TEST_ASSERT(item == 42); 1585 } 1586 } 1587 1588 CX_TEST(test_list_pll_destroy_adv_destr) { 1589 CxTestingAllocator talloc; 1590 cx_testing_allocator_init(&talloc); 1591 CxAllocator *alloc = &talloc.base; 1592 CX_TEST_DO { 1593 void *item = cxMalloc(alloc, sizeof(int)); 1594 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 1595 list->collection.destructor_data = alloc; 1596 list->collection.advanced_destructor = (cx_destructor_func2) cxFree; 1597 cxListAdd(list, item); 1598 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1599 cxListFree(list); 1600 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1601 } 1602 cx_testing_allocator_destroy(&talloc); 1603 } 1604 1605 CX_TEST(test_list_parl_destroy_no_destr) { 1606 CxTestingAllocator talloc; 1607 cx_testing_allocator_init(&talloc); 1608 CxAllocator *alloc = &talloc.base; 1609 CX_TEST_DO { 1610 void *item = cxMalloc(alloc, sizeof(int)); 1611 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4); 1612 cxListAdd(list, item); 1613 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1614 cxListFree(list); 1615 // item is not yet freed 1616 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1617 cxFree(alloc, item); 1618 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1619 } 1620 cx_testing_allocator_destroy(&talloc); 1621 } 1622 1623 CX_TEST(test_list_parl_destroy_simple_destr) { 1624 CX_TEST_DO { 1625 int item = 0; 1626 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4); 1627 list->collection.simple_destructor = test_fake_simple_int_destr; 1628 cxListAdd(list, &item); 1629 cxListFree(list); 1630 CX_TEST_ASSERT(item == 42); 1631 } 1632 } 1633 1634 CX_TEST(test_list_parl_destroy_adv_destr) { 1635 CxTestingAllocator talloc; 1636 cx_testing_allocator_init(&talloc); 1637 CxAllocator *alloc = &talloc.base; 1638 CX_TEST_DO { 1639 void *item = cxMalloc(alloc, sizeof(int)); 1640 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4); 1641 list->collection.destructor_data = alloc; 1642 list->collection.advanced_destructor = (cx_destructor_func2) cxFree; 1643 cxListAdd(list, item); 1644 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1645 cxListFree(list); 1646 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1647 } 1648 cx_testing_allocator_destroy(&talloc); 1649 } 1650 1651 #define set_up_combo \ 1652 CxTestingAllocator talloc; \ 1653 cx_testing_allocator_init(&talloc); \ 1654 CxAllocator *alloc = &talloc.base; \ 1655 CX_TEST_DO { 1656 #define tear_down_combo \ 1657 cxListFree(list); \ 1658 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));\ 1659 } \ 1660 cx_testing_allocator_destroy(&talloc); 1661 #define roll_out_test_invokers(name) \ 1662 CX_TEST(test_list_ll_##name) { \ 1663 set_up_combo \ 1664 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); \ 1665 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \ 1666 tear_down_combo \ 1667 } \ 1668 CX_TEST(test_list_arl_##name) { \ 1669 set_up_combo \ 1670 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); \ 1671 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \ 1672 tear_down_combo \ 1673 } \ 1674 CX_TEST(test_list_kvl_##name) { \ 1675 set_up_combo \ 1676 CxList *list = cxKvListCreate(alloc, cx_cmp_int, sizeof(int)); \ 1677 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \ 1678 tear_down_combo \ 1679 } \ 1680 CX_TEST(test_list_pll_##name) { \ 1681 set_up_combo \ 1682 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \ 1683 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \ 1684 tear_down_combo \ 1685 } \ 1686 CX_TEST(test_list_parl_##name) { \ 1687 set_up_combo \ 1688 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS, 8); \ 1689 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \ 1690 tear_down_combo \ 1691 } \ 1692 CX_TEST(test_list_pkvl_##name) { \ 1693 set_up_combo \ 1694 CxList *list = cxKvListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \ 1695 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \ 1696 tear_down_combo \ 1697 } 1698 #define roll_out_test_combos(name, body) \ 1699 static CX_TEST_SUBROUTINE(test_list_verify_##name, CxList *list, \ 1700 cx_attr_unused bool isptrlist) body \ 1701 roll_out_test_invokers(name) 1702 1703 static void set_default_class_funcs(CxList *list, cx_list_class *defaulted_cl) { 1704 const cx_list_class *cl = list->climpl == NULL ? list->cl : list->climpl; 1705 memcpy(defaulted_cl, cl, sizeof(cx_list_class)); 1706 defaulted_cl->insert_array = cx_list_default_insert_array; 1707 defaulted_cl->insert_unique = cx_list_default_insert_unique; 1708 defaulted_cl->insert_sorted = cx_list_default_insert_sorted; 1709 defaulted_cl->sort = cx_list_default_sort; 1710 defaulted_cl->swap = cx_list_default_swap; 1711 defaulted_cl->compare = NULL; 1712 if (list->climpl == NULL) { 1713 list->cl = defaulted_cl; 1714 } else { 1715 list->climpl = defaulted_cl; 1716 } 1717 } 1718 1719 #define do_set_default_class_funcs(list) \ 1720 cx_list_class defaulted_cl; \ 1721 set_default_class_funcs(list, &defaulted_cl) 1722 #define roll_out_test_combos_with_defaulted_funcs(name, body) \ 1723 static CX_TEST_SUBROUTINE(test_list_verify_##name, CxList *list, \ 1724 cx_attr_unused bool isptrlist) body \ 1725 roll_out_test_invokers(name) \ 1726 CX_TEST(test_list_llm_##name) { \ 1727 set_up_combo \ 1728 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); \ 1729 do_set_default_class_funcs(list); \ 1730 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \ 1731 tear_down_combo \ 1732 } \ 1733 CX_TEST(test_list_arlm_##name) { \ 1734 set_up_combo \ 1735 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); \ 1736 do_set_default_class_funcs(list); \ 1737 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \ 1738 tear_down_combo \ 1739 } \ 1740 CX_TEST(test_list_pllm_##name) { \ 1741 set_up_combo \ 1742 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \ 1743 do_set_default_class_funcs(list); \ 1744 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \ 1745 tear_down_combo \ 1746 } \ 1747 CX_TEST(test_list_parlm_##name) { \ 1748 set_up_combo \ 1749 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS, 8); \ 1750 do_set_default_class_funcs(list); \ 1751 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \ 1752 tear_down_combo \ 1753 } 1754 1755 #define array_init(...) {__VA_ARGS__} 1756 1757 static inline int *int_test_data_added_to_list(CxList *list, bool isptrlist, size_t len) { 1758 int *testdata = int_test_data(len); 1759 if (isptrlist) { 1760 for (size_t i = 0; i < len; i++) { 1761 cxListAdd(list, &testdata[i]); 1762 } 1763 } else { 1764 cxListAddArray(list, testdata, len); 1765 } 1766 return testdata; 1767 } 1768 1769 roll_out_test_combos(add, { 1770 const size_t len = 250; 1771 int *testdata = int_test_data(len); 1772 for (size_t i = 0; i < len; i++) { 1773 CX_TEST_ASSERT(cxListAdd(list, &testdata[i]) == 0); 1774 } 1775 CX_TEST_ASSERT(cxListSize(list) == len); 1776 for (size_t i = 0; i < len; i++) { 1777 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]); 1778 } 1779 for (size_t i = 0; i < len; i++) { 1780 ++testdata[i]; 1781 } 1782 if (isptrlist) { 1783 for (size_t i = 0; i < len; i++) { 1784 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]); 1785 } 1786 } else { 1787 for (size_t i = 0; i < len; i++) { 1788 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i] - 1); 1789 } 1790 } 1791 free(testdata); 1792 }) 1793 1794 roll_out_test_combos(insert, { 1795 int a = 5; 1796 int b = 47; 1797 int c = 13; 1798 int d = 42; 1799 CX_TEST_ASSERT(cxListInsert(list, 1, &a) != 0); 1800 CX_TEST_ASSERT(cxListSize(list) == 0); 1801 CX_TEST_ASSERT(cxListInsert(list, 0, &a) == 0); 1802 CX_TEST_ASSERT(cxListSize(list) == 1); 1803 CX_TEST_ASSERT(cxListInsert(list, 0, &b) == 0); 1804 CX_TEST_ASSERT(cxListSize(list) == 2); 1805 CX_TEST_ASSERT(cxListInsert(list, 1, &c) == 0); 1806 CX_TEST_ASSERT(cxListSize(list) == 3); 1807 CX_TEST_ASSERT(cxListInsert(list, 3, &d) == 0); 1808 CX_TEST_ASSERT(cxListSize(list) == 4); 1809 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 47); 1810 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 13); 1811 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 5); 1812 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 42); 1813 }) 1814 1815 roll_out_test_combos(emplace, { 1816 if (isptrlist) { 1817 int **x; 1818 int y = 5; 1819 int z = 7; 1820 int w = 13; 1821 1822 x = cxListEmplace(list); 1823 CX_TEST_ASSERT(x != NULL); 1824 CX_TEST_ASSERT(cxListSize(list) == 1); 1825 *x = &y; 1826 CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 5); 1827 1828 x = cxListEmplace(list); 1829 CX_TEST_ASSERT(x != NULL); 1830 CX_TEST_ASSERT(cxListSize(list) == 2); 1831 *x = &z; 1832 CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 7); 1833 1834 CX_TEST_ASSERT(NULL == cxListEmplaceAt(list, 3)); 1835 CX_TEST_ASSERT(cxListSize(list) == 2); 1836 1837 x = cxListEmplaceAt(list, 1); 1838 CX_TEST_ASSERT(x != NULL); 1839 CX_TEST_ASSERT(cxListSize(list) == 3); 1840 *x = &w; 1841 CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 5); 1842 CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 13); 1843 CX_TEST_ASSERT(*(int*)cxListAt(list, 2) == 7); 1844 } else { 1845 int *x; 1846 1847 x = cxListEmplace(list); 1848 CX_TEST_ASSERT(x != NULL); 1849 CX_TEST_ASSERT(cxListSize(list) == 1); 1850 *x = 5; 1851 CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 5); 1852 1853 x = cxListEmplace(list); 1854 CX_TEST_ASSERT(x != NULL); 1855 CX_TEST_ASSERT(cxListSize(list) == 2); 1856 *x = 7; 1857 CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 7); 1858 1859 CX_TEST_ASSERT(NULL == cxListEmplaceAt(list, 3)); 1860 CX_TEST_ASSERT(cxListSize(list) == 2); 1861 1862 x = cxListEmplaceAt(list, 1); 1863 CX_TEST_ASSERT(x != NULL); 1864 CX_TEST_ASSERT(cxListSize(list) == 3); 1865 *x = 13; 1866 CX_TEST_ASSERT(*(int*)cxListAt(list, 0) == 5); 1867 CX_TEST_ASSERT(*(int*)cxListAt(list, 1) == 13); 1868 CX_TEST_ASSERT(*(int*)cxListAt(list, 2) == 7); 1869 } 1870 }) 1871 1872 roll_out_test_combos_with_defaulted_funcs(insert_array, { 1873 int a[5] = array_init(5, 47, 11, 13, 42); 1874 int b[5] = array_init(9, 18, 72, 50, 7); 1875 int *aptr[5]; 1876 int *bptr[5]; 1877 for (size_t i = 0; i < 5; i++) { 1878 aptr[i] = &a[i]; 1879 bptr[i] = &b[i]; 1880 } 1881 1882 size_t inserted; 1883 1884 if (isptrlist) { 1885 inserted = cxListInsertArray(list, 0, aptr, 5); 1886 } else { 1887 inserted = cxListInsertArray(list, 0, a, 5); 1888 } 1889 CX_TEST_ASSERT(inserted == 5); 1890 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5); 1891 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47); 1892 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11); 1893 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 13); 1894 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 42); 1895 if (isptrlist) { 1896 inserted = cxListInsertArray(list, 3, bptr, 5); 1897 } else { 1898 inserted = cxListInsertArray(list, 3, b, 5); 1899 } 1900 CX_TEST_ASSERT(inserted == 5); 1901 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5); 1902 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47); 1903 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11); 1904 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 9); 1905 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 18); 1906 CX_TEST_ASSERT(*(int *) cxListAt(list, 5) == 72); 1907 CX_TEST_ASSERT(*(int *) cxListAt(list, 6) == 50); 1908 CX_TEST_ASSERT(*(int *) cxListAt(list, 7) == 7); 1909 CX_TEST_ASSERT(*(int *) cxListAt(list, 8) == 13); 1910 CX_TEST_ASSERT(*(int *) cxListAt(list, 9) == 42); 1911 }) 1912 1913 roll_out_test_combos_with_defaulted_funcs(emplace_array, { 1914 int a[5] = array_init(5, 47, 11, 13, 42); 1915 int b[5] = array_init(9, 18, 72, 50, 7); 1916 1917 CxIterator iter; 1918 1919 iter = cxListEmplaceArray(list, 5); 1920 CX_TEST_ASSERT(cxListSize(list) == 5); 1921 CX_TEST_ASSERT(iter.elem_count == 5); 1922 CX_TEST_ASSERT(iter.index == 0); 1923 if (isptrlist) { 1924 cx_foreach(int **, elem, iter) { 1925 *elem = a + iter.index; 1926 } 1927 } else { 1928 cx_foreach(int *, elem, iter) { 1929 *elem = a[iter.index]; 1930 } 1931 } 1932 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5); 1933 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47); 1934 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11); 1935 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 13); 1936 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 42); 1937 iter = cxListEmplaceArrayAt(list, 3, 5); 1938 CX_TEST_ASSERT(cxListSize(list) == 10); 1939 CX_TEST_ASSERT(iter.elem_count == 5); 1940 CX_TEST_ASSERT(iter.index == 0); 1941 if (isptrlist) { 1942 cx_foreach(int **, elem, iter) { 1943 *elem = b + iter.index; 1944 } 1945 } else { 1946 cx_foreach(int *, elem, iter) { 1947 *elem = b[iter.index]; 1948 } 1949 } 1950 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5); 1951 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47); 1952 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11); 1953 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 9); 1954 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 18); 1955 CX_TEST_ASSERT(*(int *) cxListAt(list, 5) == 72); 1956 CX_TEST_ASSERT(*(int *) cxListAt(list, 6) == 50); 1957 CX_TEST_ASSERT(*(int *) cxListAt(list, 7) == 7); 1958 CX_TEST_ASSERT(*(int *) cxListAt(list, 8) == 13); 1959 CX_TEST_ASSERT(*(int *) cxListAt(list, 9) == 42); 1960 }) 1961 1962 roll_out_test_combos_with_defaulted_funcs(insert_sorted, { 1963 int d1 = 50; 1964 int d2 = 80; 1965 int d3 = 60; 1966 int d4 = 40; 1967 int d5 = 70; 1968 int d6a[6] = array_init(52, 54, 56, 62, 64, 75); 1969 int d7a[6] = array_init(51, 57, 58, 65, 77, 78); 1970 int d8 = 90; 1971 int d9 = 56; 1972 int d10a[3] = array_init(67, 75, 90); 1973 int *d6ptr[6]; 1974 int *d7ptr[6]; 1975 int *d10ptr[3]; 1976 for (size_t i = 0; i < 6; i++) { 1977 d6ptr[i] = &d6a[i]; 1978 d7ptr[i] = &d7a[i]; 1979 } 1980 for (size_t i = 0 ; i < 3 ; i++) { 1981 d10ptr[i] = &d10a[i]; 1982 } 1983 size_t inserted; 1984 int expected[22] = array_init( 1985 40, 50, 51, 52, 54, 56, 56, 57, 58, 60, 1986 62, 64, 65, 67, 70, 75, 75, 77, 78, 80, 90, 90 1987 ); 1988 1989 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d1)); 1990 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d2)); 1991 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d3)); 1992 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d4)); 1993 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d5)); 1994 if (isptrlist) { 1995 inserted = cxListInsertSortedArray(list, d6ptr, 6); 1996 } else { 1997 inserted = cxListInsertSortedArray(list, d6a, 6); 1998 } 1999 CX_TEST_ASSERT(inserted == 6); 2000 if (isptrlist) { 2001 inserted = cxListInsertSortedArray(list, d7ptr, 6); 2002 } else { 2003 inserted = cxListInsertSortedArray(list, d7a, 6); 2004 } 2005 CX_TEST_ASSERT(inserted == 6); 2006 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d8)); 2007 CX_TEST_ASSERT(0 == cxListInsertSorted(list, &d9)); 2008 if (isptrlist) { 2009 inserted = cxListInsertSortedArray(list, d10ptr, 3); 2010 } else { 2011 inserted = cxListInsertSortedArray(list, d10a, 3); 2012 } 2013 CX_TEST_ASSERT(inserted == 3); 2014 CX_TEST_ASSERT(cxListSize(list) == 22); 2015 for (size_t i = 0; i < 22; i++) { 2016 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]); 2017 } 2018 }) 2019 2020 roll_out_test_combos_with_defaulted_funcs(insert_unique, { 2021 int d1 = 50; 2022 int d2 = 80; 2023 int d3 = 60; 2024 int d4 = 40; 2025 int d5 = 70; 2026 int d6a[8] = array_init(52, 54, 56, 56, 62, 62, 64, 75); 2027 int d7a[8] = array_init(51, 51, 57, 58, 65, 77, 78, 78); 2028 int d8 = 90; 2029 int d9 = 56; 2030 int d10a[5] = array_init(58, 58, 67, 75, 90); 2031 int *d6ptr[8]; 2032 int *d7ptr[8]; 2033 int *d10ptr[5]; 2034 for (size_t i = 0; i < 8; i++) { 2035 d6ptr[i] = &d6a[i]; 2036 d7ptr[i] = &d7a[i]; 2037 } 2038 for (size_t i = 0 ; i < 5 ; i++) { 2039 d10ptr[i] = &d10a[i]; 2040 } 2041 size_t processed; 2042 int expected[19] = array_init( 2043 40, 50, 51, 52, 54, 56, 57, 58, 60, 2044 62, 64, 65, 67, 70, 75, 77, 78, 80, 90 2045 ); 2046 2047 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d1)); 2048 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d2)); 2049 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d3)); 2050 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d4)); 2051 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d5)); 2052 if (isptrlist) { 2053 processed = cxListInsertUniqueArray(list, d6ptr, 8); 2054 } else { 2055 processed = cxListInsertUniqueArray(list, d6a, 8); 2056 } 2057 CX_TEST_ASSERT(processed == 8); 2058 if (isptrlist) { 2059 processed = cxListInsertUniqueArray(list, d7ptr, 8); 2060 } else { 2061 processed = cxListInsertUniqueArray(list, d7a, 8); 2062 } 2063 CX_TEST_ASSERT(processed == 8); 2064 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d8)); 2065 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d9)); 2066 if (isptrlist) { 2067 processed = cxListInsertUniqueArray(list, d10ptr, 5); 2068 } else { 2069 processed = cxListInsertUniqueArray(list, d10a, 5); 2070 } 2071 CX_TEST_ASSERT(processed == 5); 2072 CX_TEST_ASSERT(cxListSize(list) == 19); 2073 for (size_t i = 0; i < 19; i++) { 2074 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]); 2075 } 2076 }) 2077 2078 roll_out_test_combos_with_defaulted_funcs(insert_unique_not_sorted, { 2079 int d1 = 50; 2080 int d2 = 80; 2081 int d3 = 60; 2082 int d4 = 40; 2083 int d5 = 70; 2084 int d6a[6] = array_init(52, 54, 56, 62, 64, 75); 2085 int d7a[6] = array_init(51, 57, 58, 65, 77, 78); 2086 int d8 = 90; 2087 int d9 = 56; 2088 int d10a[3] = array_init(67, 75, 90); 2089 int *d6ptr[6]; 2090 int *d7ptr[6]; 2091 int *d10ptr[3]; 2092 for (size_t i = 0; i < 6; i++) { 2093 d6ptr[i] = &d6a[i]; 2094 d7ptr[i] = &d7a[i]; 2095 } 2096 for (size_t i = 0 ; i < 3 ; i++) { 2097 d10ptr[i] = &d10a[i]; 2098 } 2099 size_t inserted; 2100 int expected[19] = array_init( 2101 50, 80, 60, 40, 70, 52, 54, 56, 62, 64, 2102 75, 51, 57, 58, 65, 77, 78, 90, 67 2103 ); 2104 2105 // begin with an unsorted list! 2106 CX_TEST_ASSERT(0 == cxListAdd(list, &d1)); 2107 CX_TEST_ASSERT(0 == cxListAdd(list, &d2)); 2108 CX_TEST_ASSERT(0 == cxListAdd(list, &d3)); 2109 CX_TEST_ASSERT(0 == cxListAdd(list, &d4)); 2110 2111 // not start adding unique items 2112 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d5)); 2113 if (isptrlist) { 2114 inserted = cxListInsertUniqueArray(list, d6ptr, 6); 2115 } else { 2116 inserted = cxListInsertUniqueArray(list, d6a, 6); 2117 } 2118 CX_TEST_ASSERT(inserted == 6); 2119 if (isptrlist) { 2120 inserted = cxListInsertUniqueArray(list, d7ptr, 6); 2121 } else { 2122 inserted = cxListInsertUniqueArray(list, d7a, 6); 2123 } 2124 CX_TEST_ASSERT(inserted == 6); 2125 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d8)); 2126 CX_TEST_ASSERT(0 == cxListInsertUnique(list, &d9)); 2127 if (isptrlist) { 2128 inserted = cxListInsertUniqueArray(list, d10ptr, 3); 2129 } else { 2130 inserted = cxListInsertUniqueArray(list, d10a, 3); 2131 } 2132 CX_TEST_ASSERT(inserted == 3); 2133 CX_TEST_ASSERT(cxListSize(list) == 19); 2134 for (size_t i = 0; i < 19; i++) { 2135 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]); 2136 } 2137 }) 2138 2139 roll_out_test_combos(remove, { 2140 const size_t testdata_len = 32; 2141 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2142 2143 CX_TEST_ASSERT(cxListRemove(list, 2) == 0); 2144 CX_TEST_ASSERT(cxListRemove(list, 4) == 0); 2145 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 2); 2146 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[0]); 2147 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[1]); 2148 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == testdata[3]); 2149 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == testdata[4]); 2150 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == testdata[6]); 2151 CX_TEST_ASSERT(cxListRemove(list, 0) == 0); 2152 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 3); 2153 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[1]); 2154 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[3]); 2155 CX_TEST_ASSERT(cxListRemove(list, testdata_len) != 0); 2156 free(testdata); 2157 }) 2158 2159 roll_out_test_combos(remove_and_get, { 2160 int testdata[10]; 2161 for (unsigned i = 0 ; i < 10 ; i++) { 2162 testdata[i] = 2*i; 2163 cxListAdd(list, &testdata[i]); 2164 } 2165 if (isptrlist) { 2166 int *x; 2167 CX_TEST_ASSERT(cxListPop(list, &x) == 0); 2168 CX_TEST_ASSERT(*x == 18); 2169 CX_TEST_ASSERT(cxListPop(list, &x) == 0); 2170 CX_TEST_ASSERT(*x == 16); 2171 CX_TEST_ASSERT(cxListPopFront(list, &x) == 0); 2172 CX_TEST_ASSERT(*x == 0); 2173 CX_TEST_ASSERT(cxListPopFront(list, &x) == 0); 2174 CX_TEST_ASSERT(*x == 2); 2175 CX_TEST_ASSERT(cxListRemoveAndGet(list, 3, &x) == 0); 2176 CX_TEST_ASSERT(*x == 10); 2177 CX_TEST_ASSERT(cxListRemoveAndGet(list, 3, &x) == 0); 2178 CX_TEST_ASSERT(*x == 12); 2179 CX_TEST_ASSERT(cxListRemoveAndGet(list, 8, &x) != 0); 2180 CX_TEST_ASSERT(*x == 12); 2181 2182 *x = 1337; 2183 cxListClear(list); 2184 CX_TEST_ASSERT(cxListRemoveAndGet(list, 0, &x) != 0); 2185 CX_TEST_ASSERT(cxListRemoveAndGet(list, 1, &x) != 0); 2186 CX_TEST_ASSERT(cxListPop(list, &x) != 0); 2187 CX_TEST_ASSERT(cxListPopFront(list, &x) != 0); 2188 CX_TEST_ASSERT(*x == 1337); 2189 } else { 2190 int x; 2191 CX_TEST_ASSERT(cxListPop(list, &x) == 0); 2192 CX_TEST_ASSERT(x == 18); 2193 CX_TEST_ASSERT(cxListPop(list, &x) == 0); 2194 CX_TEST_ASSERT(x == 16); 2195 CX_TEST_ASSERT(cxListPopFront(list, &x) == 0); 2196 CX_TEST_ASSERT(x == 0); 2197 CX_TEST_ASSERT(cxListPopFront(list, &x) == 0); 2198 CX_TEST_ASSERT(x == 2); 2199 CX_TEST_ASSERT(cxListRemoveAndGet(list, 3, &x) == 0); 2200 CX_TEST_ASSERT(x == 10); 2201 CX_TEST_ASSERT(cxListRemoveAndGet(list, 3, &x) == 0); 2202 CX_TEST_ASSERT(x == 12); 2203 CX_TEST_ASSERT(cxListRemoveAndGet(list, 8, &x) != 0); 2204 CX_TEST_ASSERT(x == 12); 2205 2206 x = 1337; 2207 cxListClear(list); 2208 CX_TEST_ASSERT(cxListRemoveAndGet(list, 0, &x) != 0); 2209 CX_TEST_ASSERT(cxListRemoveAndGet(list, 1, &x) != 0); 2210 CX_TEST_ASSERT(cxListPop(list, &x) != 0); 2211 CX_TEST_ASSERT(cxListPopFront(list, &x) != 0); 2212 CX_TEST_ASSERT(x == 1337); 2213 } 2214 }) 2215 2216 static unsigned test_remove_array_destr_ctr; 2217 static void test_remove_array_destr(cx_attr_unused void *d) { 2218 test_remove_array_destr_ctr++; 2219 } 2220 2221 roll_out_test_combos(remove_array, { 2222 const size_t testdata_len = 32; 2223 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2224 cxDefineDestructor(list, test_remove_array_destr); 2225 test_remove_array_destr_ctr = 0; 2226 2227 // first, remove and get - no destructor must be called 2228 int targete[8]; 2229 int *targetp[8]; 2230 memset(targete, 0, sizeof(targete)); 2231 memset(targetp, 0, sizeof(targetp)); 2232 void *target = isptrlist ? (void*) targetp : targete; 2233 CX_TEST_ASSERT(8 == cxListRemoveArrayAndGet(list, 8, 8, target)); 2234 CX_TEST_ASSERT(0 == test_remove_array_destr_ctr); 2235 CX_TEST_ASSERT(24 == cxListSize(list)); 2236 for (unsigned int i = 0 ; i < 8 ; i++) { 2237 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[i]); 2238 } 2239 for (unsigned int i = 8 ; i < 24 ; i++) { 2240 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[8+i]); 2241 } 2242 for (unsigned int i = 0 ; i < 8 ; i++) { 2243 if (isptrlist) { 2244 CX_TEST_ASSERT(targetp[i] == &testdata[8 + i]); 2245 } else { 2246 CX_TEST_ASSERT(targete[i] == testdata[8 + i]); 2247 } 2248 } 2249 2250 // now, just remove - destructor must be called 2251 CX_TEST_ASSERT(8 == cxListRemoveArray(list, 8, 8)); 2252 CX_TEST_ASSERT(8 == test_remove_array_destr_ctr); 2253 CX_TEST_ASSERT(16 == cxListSize(list)); 2254 for (unsigned int i = 0 ; i < 8 ; i++) { 2255 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[i]); 2256 } 2257 for (unsigned int i = 8 ; i < 16 ; i++) { 2258 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[16+i]); 2259 } 2260 2261 // finally, remove and get out of bounds 2262 test_remove_array_destr_ctr = 0; 2263 memset(targete, 0, sizeof(targete)); 2264 memset(targetp, 0, sizeof(targetp)); 2265 CX_TEST_ASSERT(4 == cxListRemoveArrayAndGet(list, 12, 8, target)); 2266 CX_TEST_ASSERT(0 == test_remove_array_destr_ctr); 2267 CX_TEST_ASSERT(12 == cxListSize(list)); 2268 for (unsigned int i = 0 ; i < 8 ; i++) { 2269 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[i]); 2270 } 2271 for (unsigned int i = 8 ; i < 12 ; i++) { 2272 CX_TEST_ASSERT((*(int*)cxListAt(list, i)) == testdata[16+i]); 2273 } 2274 for (unsigned int i = 0 ; i < 4 ; i++) { 2275 if (isptrlist) { 2276 CX_TEST_ASSERT(targetp[i] == &testdata[28 + i]); 2277 } else { 2278 CX_TEST_ASSERT(targete[i] == testdata[28 + i]); 2279 } 2280 } 2281 for (unsigned int i = 4 ; i < 8 ; i++) { 2282 if (isptrlist) { 2283 CX_TEST_ASSERT(targetp[i] == NULL); 2284 } else { 2285 CX_TEST_ASSERT(targete[i] == 0); 2286 } 2287 } 2288 2289 free(testdata); 2290 }) 2291 2292 roll_out_test_combos(find_remove, { 2293 const size_t testdata_len = 250; 2294 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2295 2296 unsigned exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp) 2297 int val = testdata[exp]; 2298 // randomly picked number could occur earlier in list - find first position 2299 for (unsigned i = 0 ; i < exp ; i++) { 2300 if (testdata[i] == val) { 2301 exp = i; 2302 break; 2303 } 2304 } 2305 CX_TEST_ASSERT(cxListSize(list) == testdata_len); 2306 CX_TEST_ASSERT(cxListFind(list, &val) == exp); 2307 CX_TEST_ASSERT(cxListFindRemove(list, &val) == exp); 2308 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1); 2309 CX_TEST_ASSERT(cxListFind(list, &val) != exp); 2310 2311 int notinlist = -1; 2312 CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) == cxListSize(list)); 2313 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1); 2314 2315 free(testdata); 2316 }) 2317 2318 roll_out_test_combos(find_remove_sorted, { 2319 const size_t testdata_len = 250; 2320 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2321 qsort(testdata, testdata_len, sizeof(int), cx_cmp_int); 2322 cxListSort(list); 2323 2324 unsigned exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp) 2325 int val = testdata[exp]; 2326 // randomly picked number could occur earlier in list - find first position 2327 for (unsigned i = 0 ; i < exp ; i++) { 2328 if (testdata[i] == val) { 2329 exp = i; 2330 break; 2331 } 2332 } 2333 CX_TEST_ASSERT(cxListSize(list) == testdata_len); 2334 CX_TEST_ASSERT(cxListFind(list, &val) == exp); 2335 CX_TEST_ASSERT(cxListFindRemove(list, &val) == exp); 2336 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1); 2337 CX_TEST_ASSERT(cxListFind(list, &val) != exp); 2338 2339 int notinlist = -1; 2340 CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) == cxListSize(list)); 2341 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1); 2342 2343 free(testdata); 2344 }) 2345 2346 roll_out_test_combos(contains, { 2347 int a = 37; 2348 int b = 42; 2349 int c = 55; 2350 cxListAdd(list, &a); 2351 cxListAdd(list, &b); 2352 cxListAdd(list, &c); 2353 int x; 2354 x = 37; 2355 CX_TEST_ASSERT(cxListContains(list, &x)); 2356 x = 42; 2357 CX_TEST_ASSERT(cxListContains(list, &x)); 2358 x = 55; 2359 CX_TEST_ASSERT(cxListContains(list, &x)); 2360 x = 47; 2361 CX_TEST_ASSERT(!cxListContains(list, &x)); 2362 }) 2363 2364 roll_out_test_combos(clear, { 2365 int *testdata = int_test_data_added_to_list(list, isptrlist, 8); 2366 CX_TEST_ASSERT(cxListSize(list) > 0); 2367 cxListClear(list); 2368 CX_TEST_ASSERT(cxListSize(list) == 0); 2369 free(testdata); 2370 }) 2371 2372 roll_out_test_combos(at, { 2373 size_t len = 128; 2374 int *testdata = int_test_data_added_to_list(list, isptrlist, 128); 2375 CX_TEST_ASSERT(cxListSize(list) == len); 2376 for (size_t i = 0; i < len; i++) { 2377 CX_TEST_ASSERT(cxListIndexValid(list, i)); 2378 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]); 2379 } 2380 CX_TEST_ASSERT(!cxListIndexValid(list, len)); 2381 CX_TEST_ASSERT(cxListAt(list, len) == NULL); 2382 free(testdata); 2383 }) 2384 2385 roll_out_test_combos(set, { 2386 // Add some values 2387 int v1 = 42; 2388 cxListAdd(list, &v1); 2389 int v2 = 100; 2390 cxListAdd(list, &v2); 2391 int v3 = 47; 2392 cxListAdd(list, &v3); 2393 2394 // Change the first element 2395 int v1new = 99; 2396 CX_TEST_ASSERT(cxListSet(list, 0, &v1new) == 0); 2397 CX_TEST_ASSERT(*(int *) cxListFirst(list) == 99); 2398 2399 // Change the last element 2400 int v3new = 101; 2401 CX_TEST_ASSERT(cxListSet(list, 2, &v3new) == 0); 2402 CX_TEST_ASSERT(*(int *) cxListLast(list) == 101); 2403 2404 // Try index out of bounds 2405 int oob = 1337; 2406 CX_TEST_ASSERT(cxListSet(list, 3, &oob) != 0); 2407 }) 2408 2409 roll_out_test_combos_with_defaulted_funcs(swap, { 2410 int original[16] = array_init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); 2411 int swapped[16] = array_init(8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13); 2412 2413 for (size_t i = 0; i < 16; i++) { 2414 cxListAdd(list, &original[i]); 2415 } 2416 2417 CX_TEST_ASSERT(0 == cxListSwap(list, 1, 4)); 2418 CX_TEST_ASSERT(0 == cxListSwap(list, 2, 14)); 2419 CX_TEST_ASSERT(0 == cxListSwap(list, 9, 6)); 2420 CX_TEST_ASSERT(0 == cxListSwap(list, 3, 3)); 2421 CX_TEST_ASSERT(0 == cxListSwap(list, 10, 11)); 2422 CX_TEST_ASSERT(0 == cxListSwap(list, 8, 0)); 2423 CX_TEST_ASSERT(0 == cxListSwap(list, 7, 12)); 2424 CX_TEST_ASSERT(0 == cxListSwap(list, 13, 15)); 2425 2426 CX_TEST_ASSERT(0 != cxListSwap(list, 5, 16)); 2427 CX_TEST_ASSERT(0 != cxListSwap(list, 16, 6)); 2428 CX_TEST_ASSERT(0 != cxListSwap(list, 16, 17)); 2429 2430 CxIterator iter = cxListIterator(list); 2431 cx_foreach(int*, e, iter) { 2432 CX_TEST_ASSERT(*e == swapped[iter.index]); 2433 } 2434 iter = cxListBackwardsIterator(list); 2435 cx_foreach(int*, e, iter) { 2436 CX_TEST_ASSERT(*e == swapped[iter.index]); 2437 } 2438 }) 2439 2440 CX_TEST(test_list_arl_swap_no_sbo) { 2441 CxTestingAllocator talloc; 2442 cx_testing_allocator_init(&talloc); 2443 CxAllocator *alloc = &talloc.base; 2444 CX_TEST_DO { 2445 size_t item_size = 2*cx_array_swap_sbo_size; 2446 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, item_size, 8); 2447 2448 char *obj = malloc(item_size); 2449 for (char c = 'a' ; c <= 'z' ; c++) { 2450 obj[0] = c; 2451 obj[item_size-1] = c; 2452 cxListAdd(list, obj); 2453 } 2454 free(obj); 2455 2456 CX_TEST_ASSERT(((char*)cxListAt(list, 3))[0] == 'd'); 2457 CX_TEST_ASSERT(((char*)cxListAt(list, 17))[0] == 'r'); 2458 CX_TEST_ASSERT(((char*)cxListAt(list, 3))[item_size-1] == 'd'); 2459 CX_TEST_ASSERT(((char*)cxListAt(list, 17))[item_size-1] == 'r'); 2460 cxListSwap(list, 3, 17); 2461 CX_TEST_ASSERT(((char*)cxListAt(list, 17))[0] == 'd'); 2462 CX_TEST_ASSERT(((char*)cxListAt(list, 3))[0] == 'r'); 2463 CX_TEST_ASSERT(((char*)cxListAt(list, 17))[item_size-1] == 'd'); 2464 CX_TEST_ASSERT(((char*)cxListAt(list, 3))[item_size-1] == 'r'); 2465 2466 cxListFree(list); 2467 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2468 } 2469 cx_testing_allocator_destroy(&talloc); 2470 } 2471 2472 roll_out_test_combos(find, { 2473 const size_t testdata_len = 500; 2474 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2475 2476 for (size_t attempt = 0; attempt < 25; attempt++) { 2477 unsigned exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp) 2478 int val = testdata[exp]; 2479 // randomly picked number could occur earlier in list - find first position 2480 for (unsigned i = 0 ; i < exp ; i++) { 2481 if (testdata[i] == val) { 2482 exp = i; 2483 break; 2484 } 2485 } 2486 CX_TEST_ASSERT(cxListFind(list, &val) == exp); 2487 } 2488 2489 int notinlist = -1; 2490 CX_TEST_ASSERT(cxListFind(list, &notinlist) == cxListSize(list)); 2491 2492 free(testdata); 2493 }) 2494 2495 roll_out_test_combos_with_defaulted_funcs(sort, { 2496 const size_t testdata_len = 250; 2497 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2498 int *expected = malloc(testdata_len*sizeof(int)); 2499 memcpy(expected, testdata, testdata_len*sizeof(int)); 2500 qsort(expected, testdata_len, sizeof(int), cx_cmp_int); 2501 2502 cxListSort(list); 2503 for (size_t i = 0; i < testdata_len; i++) { 2504 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]); 2505 } 2506 2507 free(expected); 2508 free(testdata); 2509 }) 2510 2511 roll_out_test_combos(reverse, { 2512 const size_t testdata_len = 50; 2513 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len); 2514 cxListReverse(list); 2515 for (size_t i = 0; i < testdata_len; i++) { 2516 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[testdata_len - 1 - i]); 2517 } 2518 free(testdata); 2519 }) 2520 2521 roll_out_test_combos(iterator, { 2522 const size_t len = 50; 2523 int *testdata = int_test_data_added_to_list(list, isptrlist, len); 2524 2525 CxIterator iter = cxListIterator(list); 2526 CX_TEST_ASSERT(iter.elem_size == list->collection.elem_size); 2527 CX_TEST_ASSERT(iter.elem_count == list->collection.size); 2528 size_t i = 0; 2529 cx_foreach(int*, x, iter) { 2530 CX_TEST_ASSERT(i == iter.index); 2531 CX_TEST_ASSERT(*x == testdata[iter.index]); 2532 i++; 2533 } 2534 CX_TEST_ASSERT(i == cxListSize(list)); 2535 iter = cxListBackwardsIterator(list); 2536 cx_foreach(int*, x, iter) { 2537 CX_TEST_ASSERT(i - 1 == iter.index); 2538 CX_TEST_ASSERT(*x == testdata[iter.index]); 2539 i--; 2540 } 2541 CX_TEST_ASSERT(i == 0); 2542 i = len / 2; 2543 CxIterator mut_iter = cxListIteratorAt(list, i); 2544 CX_TEST_ASSERT(mut_iter.elem_size == list->collection.elem_size); 2545 CX_TEST_ASSERT(mut_iter.elem_count == list->collection.size); 2546 size_t j = 0; 2547 cx_foreach(int*, x, mut_iter) { 2548 CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2); 2549 CX_TEST_ASSERT(*x == testdata[i]); 2550 if (i % 2 == 1) cxIteratorFlagRemoval(mut_iter); 2551 i++; 2552 j++; 2553 } 2554 CX_TEST_ASSERT(i == len); 2555 i = len / 2; 2556 j = 0; 2557 mut_iter = cxListBackwardsIteratorAt(list, i - 1); 2558 cx_foreach(int*, x, mut_iter) { 2559 CX_TEST_ASSERT(mut_iter.index == len / 2 - 1 - j); 2560 CX_TEST_ASSERT(*x == testdata[i - 1]); 2561 if (i % 2 == 0) cxIteratorFlagRemoval(mut_iter); 2562 i--; 2563 j++; 2564 } 2565 CX_TEST_ASSERT(i == 0); 2566 CX_TEST_ASSERT(cxListSize(list) == len / 2); 2567 CX_TEST_ASSERT(mut_iter.elem_count == len / 2); 2568 for (size_t k = 0; k < len / 2; k++) { 2569 CX_TEST_ASSERT(*(int *) cxListAt(list, k) == testdata[k * 2]); 2570 } 2571 2572 free(testdata); 2573 }) 2574 2575 roll_out_test_combos(insert_with_iterator, { 2576 int fivenums[] = array_init(0, 1, 2, 3, 4); 2577 for (size_t i = 0; i < 5; i++) { 2578 cxListAdd(list, &fivenums[i]); 2579 } 2580 int newdata[] = array_init(10, 20, 30, 40, 50); 2581 2582 CxIterator iter = cxListIteratorAt(list, 2); 2583 CX_TEST_ASSERT(cxIteratorValid(iter)); 2584 CX_TEST_ASSERT(iter.index == 2); 2585 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2); 2586 CX_TEST_ASSERT(iter.elem_count == 5); 2587 cxListInsertAfter(&iter, &newdata[0]); 2588 CX_TEST_ASSERT(cxIteratorValid(iter)); 2589 CX_TEST_ASSERT(iter.index == 2); 2590 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2); 2591 CX_TEST_ASSERT(iter.elem_count == 6); 2592 cxListInsertBefore(&iter, &newdata[1]); 2593 CX_TEST_ASSERT(cxIteratorValid(iter)); 2594 CX_TEST_ASSERT(iter.index == 3); 2595 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2); 2596 CX_TEST_ASSERT(iter.elem_count == 7); 2597 2598 iter = cxListIterator(list); 2599 cxListInsertBefore(&iter, &newdata[2]); 2600 CX_TEST_ASSERT(cxIteratorValid(iter)); 2601 CX_TEST_ASSERT(iter.index == 1); 2602 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 0); 2603 CX_TEST_ASSERT(iter.elem_count == 8); 2604 iter = cxListIteratorAt(list, cxListSize(list)); 2605 cxListInsertBefore(&iter, &newdata[3]); 2606 CX_TEST_ASSERT(!cxIteratorValid(iter)); 2607 CX_TEST_ASSERT(iter.index == 9); 2608 CX_TEST_ASSERT(iter.elem_count == 9); 2609 iter = cxListIteratorAt(list, cxListSize(list)); 2610 cxListInsertAfter(&iter, &newdata[4]); 2611 CX_TEST_ASSERT(!cxIteratorValid(iter)); 2612 CX_TEST_ASSERT(iter.index == 10); 2613 CX_TEST_ASSERT(iter.elem_count == 10); 2614 2615 int expdata[] = array_init(30, 0, 1, 20, 2, 10, 3, 4, 40, 50); 2616 for (size_t j = 0; j < 10; j++) { 2617 CX_TEST_ASSERT(*(int *) cxListAt(list, j) == expdata[j]); 2618 } 2619 }) 2620 2621 static CX_TEST_SUBROUTINE(test_list_verify_compare, CxList *left, CxList *right) { 2622 CX_TEST_ASSERTM(cxListCompare(left, right) == 0, "lists don''t start identical"); 2623 int x = 42; 2624 cxListAdd(left, &x); 2625 CX_TEST_ASSERT(cxListSize(left) > cxListSize(right)); 2626 CX_TEST_ASSERT(cxListCompare(left, right) > 0); 2627 CX_TEST_ASSERT(cxListCompare(right, left) < 0); 2628 cxListAdd(right, &x); 2629 CX_TEST_ASSERT(cxListSize(left) == cxListSize(right)); 2630 CX_TEST_ASSERT(cxListCompare(left, right) == 0); 2631 int a = 5, b = 10; 2632 cxListInsert(left, 15, &a); 2633 cxListInsert(right, 15, &b); 2634 CX_TEST_ASSERT(cxListSize(left) == cxListSize(right)); 2635 CX_TEST_ASSERT(cxListCompare(left, right) < 0); 2636 CX_TEST_ASSERT(cxListCompare(right, left) > 0); 2637 *(int *) cxListAt(left, 15) = 10; 2638 CX_TEST_ASSERT(cxListCompare(left, right) == 0); 2639 } 2640 2641 #define roll_out_compare_tests(suffix, otherctr) \ 2642 roll_out_test_combos(compare_##suffix, { \ 2643 const size_t len = 47; \ 2644 int *testdata = int_test_data_added_to_list(list, isptrlist, len); \ 2645 CxList *other = otherctr; \ 2646 for (size_t i = 0; i < len; i++) cxListAdd(other, &testdata[i]); \ 2647 CX_TEST_CALL_SUBROUTINE(test_list_verify_compare, list, other); \ 2648 cxListFree(other); \ 2649 free(testdata); \ 2650 }) 2651 2652 roll_out_compare_tests( 2653 ll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)) 2654 ) 2655 2656 roll_out_compare_tests( 2657 pll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS) 2658 ) 2659 2660 roll_out_compare_tests( 2661 arl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 50) 2662 ) 2663 2664 roll_out_compare_tests( 2665 parl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 50) 2666 ) 2667 2668 roll_out_test_combos_with_defaulted_funcs(compare_unoptimized, { 2669 const size_t len = 33; 2670 int *testdata = int_test_data_added_to_list(list, isptrlist, len); 2671 CxList *other = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 50); 2672 do_set_default_class_funcs(other); 2673 for (size_t i = 0; i < len; i++) cxListAdd(other, &testdata[i]); 2674 CX_TEST_CALL_SUBROUTINE(test_list_verify_compare, list, other); 2675 cxListFree(other); 2676 free(testdata); 2677 }) 2678 2679 static unsigned destr_test_ctr; 2680 static int destr_last_value; 2681 2682 static void simple_destr_test_fun(void *data) { 2683 int *ptr = data; 2684 destr_last_value = *ptr; 2685 *ptr = destr_last_value + 1; 2686 destr_test_ctr++; 2687 } 2688 2689 static void advanced_destr_test_fun(cx_attr_unused void *u, void *data) { 2690 simple_destr_test_fun(data); 2691 } 2692 2693 static CX_TEST_SUBROUTINE(test_list_verify_destructor, CxList *list, 2694 const int *testdata, size_t testdata_len) { 2695 destr_test_ctr = 0; 2696 2697 int off = list->collection.store_pointer ? 1 : 0; 2698 2699 cxListRemove(list, 15); 2700 CX_TEST_ASSERT(1 == destr_test_ctr); 2701 CX_TEST_ASSERT(testdata[15] == destr_last_value + off); 2702 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2703 cxListRemove(list, 47); 2704 CX_TEST_ASSERT(2 == destr_test_ctr); 2705 CX_TEST_ASSERT(testdata[48] == destr_last_value + off); 2706 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2707 2708 CxIterator iter = cxListIteratorAt(list, 7); 2709 CX_TEST_ASSERT(iter.elem_count == testdata_len - 2); 2710 cxIteratorNext(iter); 2711 CX_TEST_ASSERT(2 == destr_test_ctr); 2712 CX_TEST_ASSERT(testdata[48] == destr_last_value + off); 2713 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2714 cxIteratorFlagRemoval(iter); 2715 cxIteratorNext(iter); 2716 CX_TEST_ASSERT(iter.elem_count == testdata_len - 3); 2717 CX_TEST_ASSERT(3 == destr_test_ctr); 2718 CX_TEST_ASSERT(testdata[8] == destr_last_value + off); 2719 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2720 2721 iter = cxListBackwardsIteratorAt(list, 5); 2722 cxIteratorNext(iter); 2723 CX_TEST_ASSERT(3 == destr_test_ctr); 2724 CX_TEST_ASSERT(testdata[8] == destr_last_value + off); 2725 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2726 cxIteratorFlagRemoval(iter); 2727 cxIteratorNext(iter); 2728 CX_TEST_ASSERT(iter.elem_count == testdata_len - 4); 2729 CX_TEST_ASSERT(4 == destr_test_ctr); 2730 CX_TEST_ASSERT(testdata[4] == destr_last_value + off); 2731 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list)); 2732 2733 cxListClear(list); 2734 CX_TEST_ASSERT(testdata_len == destr_test_ctr); 2735 CX_TEST_ASSERT(testdata[testdata_len - 1] == destr_last_value + off); 2736 } 2737 2738 roll_out_test_combos(simple_destr, { 2739 const size_t len = 60; 2740 int *testdata = int_test_data_added_to_list(list, isptrlist, len); 2741 cxDefineDestructor(list, simple_destr_test_fun); 2742 CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len); 2743 free(testdata); 2744 }) 2745 2746 roll_out_test_combos(advanced_destr, { 2747 const size_t len = 75; 2748 int *testdata = int_test_data_added_to_list(list, isptrlist, len); 2749 cxDefineAdvancedDestructor(list, advanced_destr_test_fun, NULL); 2750 CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len); 2751 free(testdata); 2752 }) 2753 2754 roll_out_test_combos(reserve_and_shrink, { 2755 // there is no actual observable behavior, 2756 // so we just check that the functions return zero 2757 int *td1 = int_test_data_added_to_list(list, isptrlist, 500); 2758 CX_TEST_ASSERT(0 == cxListReserve(list, 200)); 2759 CX_TEST_ASSERT(0 == cxListReserve(list, 1000)); 2760 int *td2 = int_test_data_added_to_list(list, isptrlist, 500); 2761 int *td3 = int_test_data_added_to_list(list, isptrlist, 500); 2762 CX_TEST_ASSERT(0 == cxListShrink(list)); 2763 size_t i = 0; 2764 for (size_t j = 0 ; j < 500 ; j++, i++) { 2765 CX_TEST_ASSERT(*(int*)cxListAt(list, i) == td1[j]); 2766 } 2767 for (size_t j = 0 ; j < 500 ; j++, i++) { 2768 CX_TEST_ASSERT(*(int*)cxListAt(list, i) == td2[j]); 2769 } 2770 for (size_t j = 0 ; j < 500 ; j++, i++) { 2771 CX_TEST_ASSERT(*(int*)cxListAt(list, i) == td3[j]); 2772 } 2773 free(td1); 2774 free(td2); 2775 free(td3); 2776 }) 2777 2778 static bool test_clone_func_max_enabled = false; 2779 static unsigned test_clone_func_max_clones; 2780 static void *test_clone_func(void *dest, const void *src, const CxAllocator *al, void *data) { 2781 if (test_clone_func_max_enabled) { 2782 if (test_clone_func_max_clones == 0) return NULL; 2783 test_clone_func_max_clones--; 2784 } 2785 2786 if (dest == NULL) { 2787 dest = cxMalloc(al, sizeof(int)); 2788 } 2789 2790 int z = 0; 2791 if (data == NULL) { 2792 data = &z; 2793 } 2794 2795 *((int*) dest) = *(int*) src + *(int*) data; 2796 (*(int*) data)++; 2797 2798 return dest; 2799 } 2800 2801 static CX_TEST_SUBROUTINE(verify_clone, CxList *target, CxList *source, bool target_isptrlist) { 2802 // testing allocator for the target elements if target_isptrlist is true 2803 CxTestingAllocator talloc; 2804 cx_testing_allocator_init(&talloc); 2805 CxAllocator *testing_alloc = &talloc.base; 2806 2807 // register a destructor for the target list if it is storing pointers 2808 if (target_isptrlist) { 2809 cxDefineAdvancedDestructor(target, cxFree, testing_alloc); 2810 } 2811 2812 // fill the source list 2813 int source_data[8] = array_init(1, 2, 3, 4, 5, 6, 7, 8); 2814 for (unsigned i = 0 ; i < 8 ; i++) { 2815 cxListAdd(source, &source_data[i]); 2816 } 2817 2818 // add some initial data to the target 2819 int initial_data[4] = array_init(1, 2, 3, 4); 2820 for (unsigned i = 0; i < 4; i++) { 2821 if (target_isptrlist) { 2822 int *x = cxMalloc(testing_alloc, sizeof(int)); 2823 *x = initial_data[i]; 2824 cxListAdd(target, x); 2825 } else { 2826 cxListAdd(target, &initial_data[i]); 2827 } 2828 } 2829 2830 // perform the test 2831 int expected_data[12] = array_init(1, 2, 3, 4, 1, 3, 5, 7, 9, 11, 13, 15); 2832 int c = 0; 2833 CX_TEST_ASSERT(0 == cxListClone(target, source, test_clone_func, testing_alloc, &c)); 2834 CX_TEST_ASSERT(c == 8); 2835 CX_TEST_ASSERT(cxListSize(target) == 12); 2836 CX_TEST_ASSERT(cxListSize(source) == 8); 2837 for (unsigned i = 0 ; i < 12 ; i++) { 2838 CX_TEST_ASSERT(*(int*)cxListAt(target, i) == expected_data[i]); 2839 } 2840 for (unsigned i = 0 ; i < 8 ; i++) { 2841 CX_TEST_ASSERT(*(int*)cxListAt(source, i) == source_data[i]); 2842 } 2843 cxListFree(target); 2844 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2845 cx_testing_allocator_destroy(&talloc); 2846 } 2847 2848 static CX_TEST_SUBROUTINE(verify_clone_alloc_fail, CxList *target, CxList *source, bool target_isptrlist) { 2849 // testing allocator for the target elements if target_isptrlist is true 2850 CxTestingAllocator talloc; 2851 cx_testing_allocator_init(&talloc); 2852 CxAllocator *testing_alloc = &talloc.base; 2853 2854 // register a destructor for the target list if it is storing pointers 2855 if (target_isptrlist) { 2856 cxDefineAdvancedDestructor(target, cxFree, testing_alloc); 2857 } 2858 2859 // fill the source list 2860 int source_data[8] = array_init(1, 2, 3, 4, 5, 6, 7, 8); 2861 for (unsigned i = 0 ; i < 8 ; i++) { 2862 cxListAdd(source, &source_data[i]); 2863 } 2864 2865 // add some initial data to the target 2866 int initial_data[4] = array_init(1, 2, 3, 4); 2867 for (unsigned i = 0; i < 4; i++) { 2868 if (target_isptrlist) { 2869 int *x = cxMalloc(testing_alloc, sizeof(int)); 2870 *x = initial_data[i]; 2871 cxListAdd(target, x); 2872 } else { 2873 cxListAdd(target, &initial_data[i]); 2874 } 2875 } 2876 2877 // perform the test 2878 int expected_data[9] = array_init(1, 2, 3, 4, 1, 3, 5, 7, 9); 2879 int c = 0; 2880 test_clone_func_max_enabled = true; 2881 test_clone_func_max_clones = 5; 2882 CX_TEST_ASSERT(0 != cxListClone(target, source, test_clone_func, testing_alloc, &c)); 2883 test_clone_func_max_enabled = false; 2884 CX_TEST_ASSERT(c == 5); 2885 CX_TEST_ASSERT(cxListSize(target) == 9); 2886 CX_TEST_ASSERT(cxListSize(source) == 8); 2887 for (unsigned i = 0 ; i < 9 ; i++) { 2888 CX_TEST_ASSERT(*(int*)cxListAt(target, i) == expected_data[i]); 2889 } 2890 for (unsigned i = 0 ; i < 8 ; i++) { 2891 CX_TEST_ASSERT(*(int*)cxListAt(source, i) == source_data[i]); 2892 } 2893 cxListFree(target); 2894 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2895 cx_testing_allocator_destroy(&talloc); 2896 } 2897 2898 roll_out_test_combos(clone_into_arl, { 2899 CxList *target = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 2900 CX_TEST_CALL_SUBROUTINE(verify_clone, target, list, false); 2901 }) 2902 2903 roll_out_test_combos(clone_into_ll, { 2904 CxList *target = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 2905 CX_TEST_CALL_SUBROUTINE(verify_clone, target, list, false); 2906 }) 2907 2908 roll_out_test_combos(clone_into_parl, { 2909 CxList *target = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 8); 2910 CX_TEST_CALL_SUBROUTINE(verify_clone, target, list, true); 2911 }) 2912 2913 roll_out_test_combos(clone_into_pll, { 2914 CxList *target = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 2915 CX_TEST_CALL_SUBROUTINE(verify_clone, target, list, true); 2916 }) 2917 2918 roll_out_test_combos(clone_alloc_fail_into_arl, { 2919 CxList *target = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 2920 CX_TEST_CALL_SUBROUTINE(verify_clone_alloc_fail, target, list, false); 2921 }) 2922 2923 roll_out_test_combos(clone_alloc_fail_into_ll, { 2924 CxList *target = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 2925 CX_TEST_CALL_SUBROUTINE(verify_clone_alloc_fail, target, list, false); 2926 }) 2927 2928 roll_out_test_combos(clone_alloc_fail_into_parl, { 2929 CxList *target = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 8); 2930 CX_TEST_CALL_SUBROUTINE(verify_clone_alloc_fail, target, list, true); 2931 }) 2932 2933 roll_out_test_combos(clone_alloc_fail_into_pll, { 2934 CxList *target = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 2935 CX_TEST_CALL_SUBROUTINE(verify_clone_alloc_fail, target, list, true); 2936 }) 2937 2938 static CX_TEST_SUBROUTINE(verify_difference, bool sorted, bool alloc_fail) { 2939 CxTestingAllocator talloc; 2940 cx_testing_allocator_init(&talloc); 2941 2942 CxList *dst = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 2943 cxDefineAdvancedDestructor(dst, cxFree, &talloc); 2944 CxList *minuend = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 2945 CxList *subtrahend = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 2946 2947 int dst_data[] = {47, 178, 176, 83}; 2948 int minuend_data[] = { 2949 153, 106, 171, 130, 74, 173, 150, 94, 27, 92, 70, 175, 200, 20, 29, 161, 88, 116, 71, 53, 199, 124, 32, 9, 76, 2950 151, 33, 51, 37, 65, 176, 49, 12, 162, 28, 85, 4, 177, 198, 54, 109, 188, 44, 77, 194, 63, 41, 129, 97, 83 2951 }; 2952 int subtrahend_data[] = { 2953 75, 137, 176, 111, 85, 27, 197, 141, 46, 103, 69, 146, 49, 79, 63, 130, 154, 45, 38, 139, 193, 90, 64, 142, 115, 2954 120, 78, 100, 101, 42, 21, 1, 161, 10, 114, 198, 181, 178, 136, 188, 59, 41, 73, 99, 151, 144, 118, 53, 199, 71 2955 }; 2956 2957 for (unsigned i = 0 ; i < cx_nmemb(dst_data) ; i++) { 2958 int *x = cxMalloc(&talloc.base, sizeof(int)); 2959 *x = dst_data[i]; 2960 cxListAdd(dst, x); 2961 } 2962 cxListAddArray(minuend, minuend_data, 50); 2963 cxListAddArray(subtrahend, subtrahend_data, 50); 2964 if (sorted) { 2965 cxListSort(dst); 2966 cxListSort(minuend); 2967 cxListSort(subtrahend); 2968 } 2969 2970 // expected 36 elements in the difference 2971 size_t expected_len = 40; 2972 int expected_unsorted[] = { 2973 47, 178, 176, 83, 2974 153, 106, 171, 74, 173, 150, 94, 92, 70, 175, 200, 20, 29, 88, 116, 124, 32, 9, 76, 33, 51, 37, 65, 12, 162, 2975 28, 4, 177, 54, 109, 44, 77, 194, 129, 97, 83 2976 }; 2977 int expected_sorted[] = { 2978 47, 83, 176, 178, 2979 4, 9, 12, 20, 28, 29, 32, 33, 37, 44, 51, 54, 65, 70, 74, 76, 77, 83, 88, 92, 94, 97, 106, 109, 116, 124, 129, 2980 150, 153, 162, 171, 173, 175, 177, 194, 200 2981 }; 2982 2983 if (alloc_fail) { 2984 test_clone_func_max_enabled = true; 2985 test_clone_func_max_clones = 30; 2986 expected_len = 34; 2987 } 2988 CxList *expected = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), expected_len); 2989 cxListAddArray(expected, sorted ? expected_sorted : expected_unsorted, expected_len); 2990 2991 int result = cxListDifference(dst, minuend, subtrahend, test_clone_func, &talloc.base, NULL); 2992 if (alloc_fail) { 2993 CX_TEST_ASSERT(result != 0); 2994 } else { 2995 CX_TEST_ASSERT(result == 0); 2996 } 2997 test_clone_func_max_enabled = false; 2998 CX_TEST_ASSERT(expected_len == cxListSize(dst)); 2999 CX_TEST_ASSERT(0 == cxListCompare(dst, expected)); 3000 3001 cxListFree(dst); 3002 cxListFree(minuend); 3003 cxListFree(subtrahend); 3004 cxListFree(expected); 3005 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 3006 cx_testing_allocator_destroy(&talloc); 3007 } 3008 3009 CX_TEST(test_list_difference_unsorted) { 3010 CX_TEST_DO { 3011 CX_TEST_CALL_SUBROUTINE(verify_difference, false, false); 3012 } 3013 } 3014 3015 CX_TEST(test_list_difference_sorted) { 3016 CX_TEST_DO { 3017 CX_TEST_CALL_SUBROUTINE(verify_difference, true, false); 3018 } 3019 } 3020 3021 CX_TEST(test_list_difference_unsorted_alloc_fail) { 3022 CX_TEST_DO { 3023 CX_TEST_CALL_SUBROUTINE(verify_difference, false, true); 3024 } 3025 } 3026 3027 CX_TEST(test_list_difference_sorted_alloc_fail) { 3028 CX_TEST_DO { 3029 CX_TEST_CALL_SUBROUTINE(verify_difference, true, true); 3030 } 3031 } 3032 3033 static CX_TEST_SUBROUTINE(verify_intersection, bool sorted, bool alloc_fail) { 3034 CxTestingAllocator talloc; 3035 cx_testing_allocator_init(&talloc); 3036 3037 CxList *dst = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 3038 cxDefineAdvancedDestructor(dst, cxFree, &talloc); 3039 CxList *src = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3040 CxList *other = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3041 3042 int dst_data[] = {47, 178, 176, 83}; 3043 int src_data[] = { 3044 153, 106, 171, 130, 74, 173, 150, 94, 27, 92, 70, 175, 200, 20, 29, 161, 88, 116, 71, 53, 199, 124, 32, 9, 76, 3045 151, 33, 51, 37, 65, 176, 49, 12, 162, 28, 85, 4, 177, 198, 54, 109, 188, 44, 77, 194, 63, 41, 129, 97, 83 3046 }; 3047 int other_data[] = { 3048 75, 137, 176, 111, 85, 27, 197, 141, 46, 103, 69, 146, 49, 79, 63, 130, 154, 45, 38, 139, 193, 90, 64, 142, 115, 3049 120, 78, 100, 101, 42, 21, 1, 161, 10, 114, 198, 181, 178, 136, 188, 59, 41, 73, 99, 151, 144, 118, 53, 199, 71 3050 }; 3051 3052 for (unsigned i = 0 ; i < cx_nmemb(dst_data) ; i++) { 3053 int *x = cxMalloc(&talloc.base, sizeof(int)); 3054 *x = dst_data[i]; 3055 cxListAdd(dst, x); 3056 } 3057 cxListAddArray(src, src_data, 50); 3058 cxListAddArray(other, other_data, 50); 3059 if (sorted) { 3060 cxListSort(dst); 3061 cxListSort(src); 3062 cxListSort(other); 3063 } 3064 3065 // expected 14 elements in the intersection 3066 size_t expected_len = 18; 3067 int expected_unsorted[] = { 3068 47, 178, 176, 83, 3069 130, 27, 161, 71, 53, 199, 151, 176, 49, 85, 198, 188, 63, 41 3070 }; 3071 int expected_sorted[] = { 3072 47, 83, 176, 178, 3073 27, 41, 49, 53, 63, 71, 85, 130, 151, 161, 176, 188, 198, 199 3074 }; 3075 3076 if (alloc_fail) { 3077 test_clone_func_max_enabled = true; 3078 test_clone_func_max_clones = 10; 3079 expected_len = 14; 3080 } 3081 CxList *expected = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), expected_len); 3082 cxListAddArray(expected, sorted ? expected_sorted : expected_unsorted, expected_len); 3083 3084 int result = cxListIntersection(dst, src, other, test_clone_func, &talloc.base, NULL); 3085 if (alloc_fail) { 3086 CX_TEST_ASSERT(result != 0); 3087 } else { 3088 CX_TEST_ASSERT(result == 0); 3089 } 3090 test_clone_func_max_enabled = false; 3091 CX_TEST_ASSERT(expected_len == cxListSize(dst)); 3092 CX_TEST_ASSERT(0 == cxListCompare(dst, expected)); 3093 3094 cxListFree(dst); 3095 cxListFree(src); 3096 cxListFree(other); 3097 cxListFree(expected); 3098 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 3099 cx_testing_allocator_destroy(&talloc); 3100 } 3101 3102 CX_TEST(test_list_intersection_unsorted) { 3103 CX_TEST_DO { 3104 CX_TEST_CALL_SUBROUTINE(verify_intersection, false, false); 3105 } 3106 } 3107 3108 CX_TEST(test_list_intersection_sorted) { 3109 CX_TEST_DO { 3110 CX_TEST_CALL_SUBROUTINE(verify_intersection, true, false); 3111 } 3112 } 3113 3114 CX_TEST(test_list_intersection_unsorted_alloc_fail) { 3115 CX_TEST_DO { 3116 CX_TEST_CALL_SUBROUTINE(verify_intersection, false, true); 3117 } 3118 } 3119 3120 CX_TEST(test_list_intersection_sorted_alloc_fail) { 3121 CX_TEST_DO { 3122 CX_TEST_CALL_SUBROUTINE(verify_intersection, true, true); 3123 } 3124 } 3125 3126 static CX_TEST_SUBROUTINE(verify_union, bool sorted, bool alloc_fail) { 3127 CxTestingAllocator talloc; 3128 cx_testing_allocator_init(&talloc); 3129 3130 CxList *dst = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 3131 cxDefineAdvancedDestructor(dst, cxFree, &talloc); 3132 CxList *src = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3133 CxList *other = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3134 3135 int dst_data[] = {47, 178, 176, 83}; 3136 int src_data[] = { 3137 153, 106, 171, 130, 74, 173, 150, 94, 27, 92, 70, 175, 200, 20, 29, 161, 88, 116, 71, 53, 199, 124, 32, 9, 76, 3138 151, 33, 51, 37, 65, 176, 49, 12, 162, 28, 85, 4, 177, 198, 54, 109, 188, 44, 77, 194, 63, 41, 129, 97, 83 3139 }; 3140 int other_data[] = { 3141 75, 137, 176, 111, 85, 27, 197, 141, 46, 103, 69, 146, 49, 79, 63, 130, 154, 45, 38, 139, 193, 90, 64, 142, 115, 3142 120, 78, 100, 101, 42, 21, 1, 161, 10, 114, 198, 181, 178, 136, 188, 59, 41, 73, 99, 151, 144, 118, 53, 199, 71 3143 }; 3144 3145 for (unsigned i = 0 ; i < cx_nmemb(dst_data) ; i++) { 3146 int *x = cxMalloc(&talloc.base, sizeof(int)); 3147 *x = dst_data[i]; 3148 cxListAdd(dst, x); 3149 } 3150 cxListAddArray(src, src_data, 50); 3151 cxListAddArray(other, other_data, 50); 3152 if (sorted) { 3153 cxListSort(dst); 3154 cxListSort(src); 3155 cxListSort(other); 3156 } 3157 3158 // the 14 elements from the intersection should not appear twice in the destination: 3159 // 27, 41, 49, 53, 63, 71, 85, 130, 151, 161, 176, 188, 198, 199 3160 // however, the elements that are already in dst may appear twice 3161 size_t expected_len = 90; 3162 int expected_unsorted[] = { 3163 47, 178, 176, 83, 3164 153, 106, 171, 130, 74, 173, 150, 94, 27, 92, 70, 175, 200, 20, 29, 161, 3165 88, 116, 71, 53, 199, 124, 32, 9, 76, 151, 33, 51, 37, 65, 176, 49, 12, 3166 162, 28, 85, 4, 177, 198, 54, 109, 188, 44, 77, 194, 63, 41, 129, 97, 3167 83, 75, 137, 111, 197, 141, 46, 103, 69, 146, 79, 154, 45, 38, 139, 193, 3168 90, 64, 142, 115, 120, 78, 100, 101, 42, 21, 1, 10, 114, 181, 178, 136, 3169 59, 73, 99, 144, 118 3170 }; 3171 int expected_sorted[] = { 3172 47, 83, 176, 178, 3173 1, 4, 9, 10, 12, 20, 21, 27, 28, 29, 32, 33, 37, 38, 41, 42, 44, 45, 3174 46, 49, 51, 53, 54, 59, 63, 64, 65, 69, 70, 71, 73, 74, 75, 76, 77, 78, 3175 79, 83, 85, 88, 90, 92, 94, 97, 99, 100, 101, 103, 106, 109, 111, 114, 3176 115, 116, 118, 120, 124, 129, 130, 136, 137, 139, 141, 142, 144, 146, 3177 150, 151, 153, 154, 161, 162, 171, 173, 175, 176, 177, 178, 181, 188, 3178 193, 194, 197, 198, 199, 200 3179 }; 3180 3181 if (alloc_fail) { 3182 test_clone_func_max_enabled = true; 3183 test_clone_func_max_clones = 66; 3184 expected_len = 70; 3185 } 3186 CxList *expected = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), expected_len); 3187 cxListAddArray(expected, sorted ? expected_sorted : expected_unsorted, expected_len); 3188 3189 int result = cxListUnion(dst, src, other, test_clone_func, &talloc.base, NULL); 3190 if (alloc_fail) { 3191 CX_TEST_ASSERT(result != 0); 3192 } else { 3193 CX_TEST_ASSERT(result == 0); 3194 } 3195 test_clone_func_max_enabled = false; 3196 CX_TEST_ASSERT(expected_len == cxListSize(dst)); 3197 CX_TEST_ASSERT(0 == cxListCompare(dst, expected)); 3198 3199 cxListFree(dst); 3200 cxListFree(src); 3201 cxListFree(other); 3202 cxListFree(expected); 3203 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 3204 cx_testing_allocator_destroy(&talloc); 3205 } 3206 3207 CX_TEST(test_list_union_unsorted) { 3208 CX_TEST_DO { 3209 CX_TEST_CALL_SUBROUTINE(verify_union, false, false); 3210 } 3211 } 3212 3213 CX_TEST(test_list_union_sorted) { 3214 CX_TEST_DO { 3215 CX_TEST_CALL_SUBROUTINE(verify_union, true, false); 3216 } 3217 } 3218 3219 CX_TEST(test_list_union_unsorted_alloc_fail) { 3220 CX_TEST_DO { 3221 CX_TEST_CALL_SUBROUTINE(verify_union, false, true); 3222 } 3223 } 3224 3225 CX_TEST(test_list_union_sorted_alloc_fail) { 3226 CX_TEST_DO { 3227 CX_TEST_CALL_SUBROUTINE(verify_union, true, true); 3228 } 3229 } 3230 3231 CX_TEST(test_list_simple_clones) { 3232 3233 int a[] = {1, 2, 5, 8, 10}; 3234 int b[] = {1, 3, 5, 7, 9, 11}; 3235 int c[] = {2, 4, 6, 8, 10, 12}; 3236 int d[] = {4, 8, 12}; 3237 3238 CxList *la = cxArrayListCreateSimple(sizeof(int), 8); 3239 cxCollectionCompareFunc(la, cx_cmp_int); 3240 cxListInsertSortedArray(la, a, cx_nmemb(a)); 3241 CxList *lb = cxArrayListCreateSimple(sizeof(int), 8); 3242 cxCollectionCompareFunc(lb, cx_cmp_int); 3243 cxListInsertSortedArray(lb, b, cx_nmemb(b)); 3244 CxList *lc = cxArrayListCreateSimple(sizeof(int), 8); 3245 cxCollectionCompareFunc(lc, cx_cmp_int); 3246 cxListInsertSortedArray(lc, c, cx_nmemb(c)); 3247 CxList *ld = cxArrayListCreateSimple(sizeof(int), 8); 3248 cxCollectionCompareFunc(ld, cx_cmp_int); 3249 cxListInsertSortedArray(ld, d, cx_nmemb(d)); 3250 3251 CxList *d1 = cxArrayListCreateSimple(sizeof(int), 8); 3252 cxCollectionCompareFunc(d1, cx_cmp_int); 3253 CxList *d2 = cxArrayListCreateSimple(sizeof(int), 8); 3254 cxCollectionCompareFunc(d2, cx_cmp_int); 3255 3256 CX_TEST_DO { 3257 // clone a into d1 3258 CX_TEST_ASSERT(0 == cxListCloneSimple(d1, la)); 3259 CX_TEST_ASSERT(0 == cxListCompare(d1, la)); 3260 CX_TEST_ASSERT(cxCollectionSorted(d1)); 3261 3262 // union of a (in d1) and b 3263 CX_TEST_ASSERT(0 == cxListUnionSimple(d2, d1, lb)); 3264 CX_TEST_ASSERT(cxCollectionSorted(d2)); 3265 CxList *expected_union = cxArrayListCreateSimple(sizeof(int), 8); 3266 { 3267 int expected[] = {1, 2, 3, 5, 7, 8, 9, 10, 11}; 3268 cxListAddArray(expected_union, expected, cx_nmemb(expected)); 3269 } 3270 CX_TEST_ASSERT(0 == cxListCompare(d2, expected_union)); 3271 cxListFree(expected_union); 3272 3273 // intersection of (a union b) and c 3274 cxListClear(d1); 3275 CX_TEST_ASSERT(0 == cxListIntersectionSimple(d1, d2, lc)); 3276 CX_TEST_ASSERT(cxCollectionSorted(d1)); 3277 CxList *expected_intersection = cxArrayListCreateSimple(sizeof(int), 8); 3278 { 3279 int expected[] = {2, 8, 10}; 3280 cxListAddArray(expected_intersection, expected, cx_nmemb(expected)); 3281 } 3282 CX_TEST_ASSERT(0 == cxListCompare(d1, expected_intersection)); 3283 cxListFree(expected_intersection); 3284 3285 // difference of ((a union b) intersect c) minus d 3286 cxListClear(d2); 3287 CX_TEST_ASSERT(0 == cxListDifferenceSimple(d2, d1, ld)); 3288 CX_TEST_ASSERT(cxCollectionSorted(d2)); 3289 CxList *expected_difference = cxArrayListCreateSimple(sizeof(int), 8); 3290 { 3291 int expected[] = {2, 10}; 3292 cxListAddArray(expected_difference, expected, cx_nmemb(expected)); 3293 } 3294 CX_TEST_ASSERT(0 == cxListCompare(d2, expected_difference)); 3295 cxListFree(expected_difference); 3296 } 3297 3298 cxListFree(d1); 3299 cxListFree(d2); 3300 cxListFree(la); 3301 cxListFree(lb); 3302 cxListFree(lc); 3303 cxListFree(ld); 3304 } 3305 3306 CX_TEST(test_list_pointer_list_supports_null) { 3307 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 3308 int x = 47; 3309 int y = 11; 3310 int z = 1337; 3311 int *nptr = NULL; 3312 cxListAdd(list, &x); 3313 cxListAdd(list, &y); 3314 cxListAdd(list, nptr); 3315 cxListAdd(list, &z); 3316 CX_TEST_DO { 3317 CX_TEST_ASSERT(cxListSize(list) == 4); 3318 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 47); 3319 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 11); 3320 CX_TEST_ASSERT((int *) cxListAt(list, 2) == NULL); 3321 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 1337); 3322 CX_TEST_ASSERT(cxListFind(list, nptr) == 2); 3323 3324 // when we sort the list, NULL is supposed to be smaller than any value 3325 cxListSort(list); 3326 CX_TEST_ASSERT((int *) cxListAt(list, 0) == NULL); 3327 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 11); 3328 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 47); 3329 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 1337); 3330 } 3331 cxListFree(list); 3332 } 3333 3334 CX_TEST(test_list_use_insert_unique_to_remove_duplicates) { 3335 CxList *linked_list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3336 CxList *array_list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 3337 CxList *defaulted_list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 3338 do_set_default_class_funcs(defaulted_list); 3339 int test_array[23] = { 3340 120, -13, 100, -90, 13, -56, 74, 20, 28, 80, 18, -56, 130, 12, 15, 0, 39, 100, 0, 29, 28, 85, 20 3341 }; 3342 int test_array_unique[18] = { 3343 -90, -56, -13, 0, 12, 13, 15, 18, 20, 28, 29, 39, 74, 80, 85, 100, 120, 130 3344 }; 3345 CX_TEST_DO { 3346 qsort(test_array, 23, sizeof(int), cx_cmp_int); 3347 cxListInsertUniqueArray(linked_list, test_array, 23); 3348 cxListInsertUniqueArray(array_list, test_array, 23); 3349 cxListInsertUniqueArray(defaulted_list, test_array, 23); 3350 CX_TEST_ASSERT(cxListSize(linked_list) == 18); 3351 CX_TEST_ASSERT(cxListSize(array_list) == 18); 3352 CX_TEST_ASSERT(cxListSize(defaulted_list) == 18); 3353 for (unsigned i = 0; i < 18; i++) { 3354 CX_TEST_ASSERT(*(int *) cxListAt(linked_list, i) == test_array_unique[i]); 3355 CX_TEST_ASSERT(*(int *) cxListAt(array_list, i) == test_array_unique[i]); 3356 CX_TEST_ASSERT(*(int *) cxListAt(defaulted_list, i) == test_array_unique[i]); 3357 } 3358 } 3359 cxListFree(defaulted_list); 3360 cxListFree(linked_list); 3361 cxListFree(array_list); 3362 } 3363 3364 CX_TEST(test_list_use_insert_unique_with_duplicates_in_source) { 3365 CxList *linked_list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); 3366 CxList *array_list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 3367 CxList *defaulted_list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 8); 3368 do_set_default_class_funcs(defaulted_list); 3369 int pre_filled[10] = {-13, 5, 18, 30, 40, 45, 50, 80, 85, 110}; 3370 cxListInsertSortedArray(linked_list, pre_filled, 10); 3371 cxListInsertSortedArray(array_list, pre_filled, 10); 3372 cxListInsertSortedArray(defaulted_list, pre_filled, 10); 3373 int test_array[23] = { 3374 120, -13, 100, -90, 13, -56, 74, 20, 28, 80, 18, -56, 130, 12, 15, 0, 39, 100, 0, 29, 28, 85, 20 3375 }; 3376 int test_array_unique[24] = { 3377 -90, -56, -13, 0, 5, 12, 13, 15, 18, 20, 28, 29, 30, 39, 40, 45, 50, 74, 80, 85, 100, 110, 120, 130 3378 }; 3379 CX_TEST_DO { 3380 qsort(test_array, 23, sizeof(int), cx_cmp_int); 3381 cxListInsertUniqueArray(linked_list, test_array, 23); 3382 cxListInsertUniqueArray(array_list, test_array, 23); 3383 cxListInsertUniqueArray(defaulted_list, test_array, 23); 3384 CX_TEST_ASSERT(cxListSize(linked_list) == 24); 3385 CX_TEST_ASSERT(cxListSize(array_list) == 24); 3386 CX_TEST_ASSERT(cxListSize(defaulted_list) == 24); 3387 for (unsigned i = 0; i < 24; i++) { 3388 CX_TEST_ASSERT(*(int *) cxListAt(linked_list, i) == test_array_unique[i]); 3389 CX_TEST_ASSERT(*(int *) cxListAt(array_list, i) == test_array_unique[i]); 3390 CX_TEST_ASSERT(*(int *) cxListAt(defaulted_list, i) == test_array_unique[i]); 3391 } 3392 CX_TEST_ASSERT(*(int*)cxListLast(linked_list) == 130); 3393 CX_TEST_ASSERT(*(int*)cxListLast(array_list) == 130); 3394 CX_TEST_ASSERT(*(int*)cxListLast(defaulted_list) == 130); 3395 } 3396 cxListFree(defaulted_list); 3397 cxListFree(linked_list); 3398 cxListFree(array_list); 3399 } 3400 3401 CxTestSuite *cx_test_suite_array_list(void) { 3402 CxTestSuite *suite = cx_test_suite_new("array_list"); 3403 3404 cx_test_register(suite, test_array_add); 3405 cx_test_register(suite, test_array_add8); 3406 cx_test_register(suite, test_array_add16); 3407 cx_test_register(suite, test_array_copy_unsupported_width); 3408 cx_test_register(suite, test_array_copy_overlap); 3409 cx_test_register(suite, test_array_reserve); 3410 cx_test_register(suite, test_array_reserve_unsupported_width); 3411 cx_test_register(suite, test_array_insert_sorted); 3412 cx_test_register(suite, test_array_insert_unique); 3413 cx_test_register(suite, test_array_binary_search); 3414 cx_test_register(suite, test_array_binary_search_with_duplicates); 3415 3416 cx_test_register(suite, test_list_arl_create); 3417 cx_test_register(suite, test_list_arl_create_simple); 3418 cx_test_register(suite, test_list_arl_create_simple_for_pointers); 3419 cx_test_register(suite, test_list_parl_destroy_no_destr); 3420 cx_test_register(suite, test_list_parl_destroy_simple_destr); 3421 cx_test_register(suite, test_list_parl_destroy_adv_destr); 3422 3423 cx_test_register(suite, test_list_arl_add); 3424 cx_test_register(suite, test_list_parl_add); 3425 cx_test_register(suite, test_list_arl_insert); 3426 cx_test_register(suite, test_list_parl_insert); 3427 cx_test_register(suite, test_list_arl_emplace); 3428 cx_test_register(suite, test_list_parl_emplace); 3429 cx_test_register(suite, test_list_arl_insert_array); 3430 cx_test_register(suite, test_list_parl_insert_array); 3431 cx_test_register(suite, test_list_arl_emplace_array); 3432 cx_test_register(suite, test_list_parl_emplace_array); 3433 cx_test_register(suite, test_list_arl_insert_sorted); 3434 cx_test_register(suite, test_list_parl_insert_sorted); 3435 cx_test_register(suite, test_list_arl_insert_unique); 3436 cx_test_register(suite, test_list_parl_insert_unique); 3437 cx_test_register(suite, test_list_arl_insert_unique_not_sorted); 3438 cx_test_register(suite, test_list_parl_insert_unique_not_sorted); 3439 cx_test_register(suite, test_list_arl_remove); 3440 cx_test_register(suite, test_list_parl_remove); 3441 cx_test_register(suite, test_list_arl_remove_and_get); 3442 cx_test_register(suite, test_list_parl_remove_and_get); 3443 cx_test_register(suite, test_list_arl_remove_array); 3444 cx_test_register(suite, test_list_parl_remove_array); 3445 cx_test_register(suite, test_list_arl_find_remove); 3446 cx_test_register(suite, test_list_parl_find_remove); 3447 cx_test_register(suite, test_list_arl_find_remove_sorted); 3448 cx_test_register(suite, test_list_parl_find_remove_sorted); 3449 cx_test_register(suite, test_list_arl_contains); 3450 cx_test_register(suite, test_list_parl_contains); 3451 cx_test_register(suite, test_list_arl_clear); 3452 cx_test_register(suite, test_list_parl_clear); 3453 cx_test_register(suite, test_list_arl_at); 3454 cx_test_register(suite, test_list_parl_at); 3455 cx_test_register(suite, test_list_arl_set); 3456 cx_test_register(suite, test_list_parl_set); 3457 cx_test_register(suite, test_list_arl_swap); 3458 cx_test_register(suite, test_list_parl_swap); 3459 cx_test_register(suite, test_list_arl_swap_no_sbo); 3460 cx_test_register(suite, test_list_arl_find); 3461 cx_test_register(suite, test_list_parl_find); 3462 cx_test_register(suite, test_list_arl_sort); 3463 cx_test_register(suite, test_list_parl_sort); 3464 cx_test_register(suite, test_list_arl_reverse); 3465 cx_test_register(suite, test_list_parl_reverse); 3466 cx_test_register(suite, test_list_arl_iterator); 3467 cx_test_register(suite, test_list_parl_iterator); 3468 cx_test_register(suite, test_list_arl_insert_with_iterator); 3469 cx_test_register(suite, test_list_parl_insert_with_iterator); 3470 cx_test_register(suite, test_list_arl_compare_ll); 3471 cx_test_register(suite, test_list_arl_compare_arl); 3472 cx_test_register(suite, test_list_arl_compare_pll); 3473 cx_test_register(suite, test_list_arl_compare_parl); 3474 cx_test_register(suite, test_list_parl_compare_ll); 3475 cx_test_register(suite, test_list_parl_compare_arl); 3476 cx_test_register(suite, test_list_parl_compare_pll); 3477 cx_test_register(suite, test_list_parl_compare_parl); 3478 cx_test_register(suite, test_list_arl_simple_destr); 3479 cx_test_register(suite, test_list_parl_simple_destr); 3480 cx_test_register(suite, test_list_arl_advanced_destr); 3481 cx_test_register(suite, test_list_parl_advanced_destr); 3482 cx_test_register(suite, test_list_arl_reserve_and_shrink); 3483 cx_test_register(suite, test_list_parl_reserve_and_shrink); 3484 cx_test_register(suite, test_list_arl_clone_into_arl); 3485 cx_test_register(suite, test_list_parl_clone_into_arl); 3486 cx_test_register(suite, test_list_arl_clone_into_ll); 3487 cx_test_register(suite, test_list_parl_clone_into_ll); 3488 cx_test_register(suite, test_list_arl_clone_into_parl); 3489 cx_test_register(suite, test_list_parl_clone_into_parl); 3490 cx_test_register(suite, test_list_arl_clone_into_pll); 3491 cx_test_register(suite, test_list_parl_clone_into_pll); 3492 cx_test_register(suite, test_list_arl_clone_alloc_fail_into_arl); 3493 cx_test_register(suite, test_list_parl_clone_alloc_fail_into_arl); 3494 cx_test_register(suite, test_list_arl_clone_alloc_fail_into_ll); 3495 cx_test_register(suite, test_list_parl_clone_alloc_fail_into_ll); 3496 cx_test_register(suite, test_list_arl_clone_alloc_fail_into_parl); 3497 cx_test_register(suite, test_list_parl_clone_alloc_fail_into_parl); 3498 cx_test_register(suite, test_list_arl_clone_alloc_fail_into_pll); 3499 cx_test_register(suite, test_list_parl_clone_alloc_fail_into_pll); 3500 3501 return suite; 3502 } 3503 3504 CxTestSuite *cx_test_suite_array_list_defaulted_funcs(void) { 3505 CxTestSuite *suite = cx_test_suite_new( 3506 "array_list with defaulted functions"); 3507 3508 cx_test_register(suite, test_list_arlm_insert_array); 3509 cx_test_register(suite, test_list_parlm_insert_array); 3510 cx_test_register(suite, test_list_arlm_emplace_array); 3511 cx_test_register(suite, test_list_parlm_emplace_array); 3512 cx_test_register(suite, test_list_arlm_insert_sorted); 3513 cx_test_register(suite, test_list_parlm_insert_sorted); 3514 cx_test_register(suite, test_list_arlm_insert_unique); 3515 cx_test_register(suite, test_list_parlm_insert_unique); 3516 cx_test_register(suite, test_list_arlm_insert_unique_not_sorted); 3517 cx_test_register(suite, test_list_parlm_insert_unique_not_sorted); 3518 cx_test_register(suite, test_list_arlm_swap); 3519 cx_test_register(suite, test_list_parlm_swap); 3520 cx_test_register(suite, test_list_arlm_sort); 3521 cx_test_register(suite, test_list_parlm_sort); 3522 3523 cx_test_register(suite, test_list_arl_compare_unoptimized); 3524 cx_test_register(suite, test_list_parl_compare_unoptimized); 3525 cx_test_register(suite, test_list_arlm_compare_unoptimized); 3526 cx_test_register(suite, test_list_parlm_compare_unoptimized); 3527 3528 return suite; 3529 } 3530 3531 CxTestSuite *cx_test_suite_linked_list(void) { 3532 CxTestSuite *suite = cx_test_suite_new("linked_list"); 3533 3534 cx_test_register(suite, test_linked_list_link_unlink); 3535 cx_test_register(suite, test_linked_list_at); 3536 cx_test_register(suite, test_linked_list_find); 3537 cx_test_register(suite, test_linked_list_compare); 3538 cx_test_register(suite, test_linked_list_add); 3539 cx_test_register(suite, test_linked_list_prepend); 3540 cx_test_register(suite, test_linked_list_insert); 3541 cx_test_register(suite, test_linked_list_insert_chain); 3542 cx_test_register(suite, test_linked_list_insert_sorted); 3543 cx_test_register(suite, test_linked_list_insert_unique); 3544 cx_test_register(suite, test_linked_list_first); 3545 cx_test_register(suite, test_linked_list_last); 3546 cx_test_register(suite, test_linked_list_prev); 3547 cx_test_register(suite, test_linked_list_remove); 3548 cx_test_register(suite, test_linked_list_remove_chain); 3549 cx_test_register(suite, test_linked_list_size); 3550 cx_test_register(suite, test_linked_list_sort_empty); 3551 cx_test_register(suite, test_linked_list_sort); 3552 cx_test_register(suite, test_linked_list_reverse); 3553 3554 cx_test_register(suite, test_list_ll_create); 3555 cx_test_register(suite, test_list_ll_create_simple); 3556 cx_test_register(suite, test_list_ll_create_simple_for_pointers); 3557 cx_test_register(suite, test_list_pll_destroy_no_destr); 3558 cx_test_register(suite, test_list_pll_destroy_simple_destr); 3559 cx_test_register(suite, test_list_pll_destroy_adv_destr); 3560 3561 cx_test_register(suite, test_list_ll_add); 3562 cx_test_register(suite, test_list_pll_add); 3563 cx_test_register(suite, test_list_ll_insert); 3564 cx_test_register(suite, test_list_pll_insert); 3565 cx_test_register(suite, test_list_ll_emplace); 3566 cx_test_register(suite, test_list_pll_emplace); 3567 cx_test_register(suite, test_list_ll_insert_array); 3568 cx_test_register(suite, test_list_pll_insert_array); 3569 cx_test_register(suite, test_list_ll_emplace_array); 3570 cx_test_register(suite, test_list_pll_emplace_array); 3571 cx_test_register(suite, test_list_ll_insert_sorted); 3572 cx_test_register(suite, test_list_pll_insert_sorted); 3573 cx_test_register(suite, test_list_ll_insert_unique); 3574 cx_test_register(suite, test_list_pll_insert_unique); 3575 cx_test_register(suite, test_list_ll_insert_unique_not_sorted); 3576 cx_test_register(suite, test_list_pll_insert_unique_not_sorted); 3577 cx_test_register(suite, test_list_ll_remove); 3578 cx_test_register(suite, test_list_pll_remove); 3579 cx_test_register(suite, test_list_ll_remove_and_get); 3580 cx_test_register(suite, test_list_pll_remove_and_get); 3581 cx_test_register(suite, test_list_ll_remove_array); 3582 cx_test_register(suite, test_list_pll_remove_array); 3583 cx_test_register(suite, test_list_ll_find_remove); 3584 cx_test_register(suite, test_list_pll_find_remove); 3585 cx_test_register(suite, test_list_ll_find_remove_sorted); 3586 cx_test_register(suite, test_list_pll_find_remove_sorted); 3587 cx_test_register(suite, test_list_ll_contains); 3588 cx_test_register(suite, test_list_pll_contains); 3589 cx_test_register(suite, test_list_ll_clear); 3590 cx_test_register(suite, test_list_pll_clear); 3591 cx_test_register(suite, test_list_ll_at); 3592 cx_test_register(suite, test_list_pll_at); 3593 cx_test_register(suite, test_list_ll_set); 3594 cx_test_register(suite, test_list_pll_set); 3595 cx_test_register(suite, test_list_ll_swap); 3596 cx_test_register(suite, test_list_pll_swap); 3597 cx_test_register(suite, test_list_ll_find); 3598 cx_test_register(suite, test_list_pll_find); 3599 cx_test_register(suite, test_list_ll_sort); 3600 cx_test_register(suite, test_list_pll_sort); 3601 cx_test_register(suite, test_list_ll_reverse); 3602 cx_test_register(suite, test_list_pll_reverse); 3603 cx_test_register(suite, test_list_ll_iterator); 3604 cx_test_register(suite, test_list_pll_iterator); 3605 cx_test_register(suite, test_list_ll_insert_with_iterator); 3606 cx_test_register(suite, test_list_pll_insert_with_iterator); 3607 cx_test_register(suite, test_list_ll_compare_ll); 3608 cx_test_register(suite, test_list_ll_compare_arl); 3609 cx_test_register(suite, test_list_ll_compare_pll); 3610 cx_test_register(suite, test_list_ll_compare_parl); 3611 cx_test_register(suite, test_list_pll_compare_ll); 3612 cx_test_register(suite, test_list_pll_compare_arl); 3613 cx_test_register(suite, test_list_pll_compare_pll); 3614 cx_test_register(suite, test_list_pll_compare_parl); 3615 cx_test_register(suite, test_list_ll_simple_destr); 3616 cx_test_register(suite, test_list_pll_simple_destr); 3617 cx_test_register(suite, test_list_ll_advanced_destr); 3618 cx_test_register(suite, test_list_pll_advanced_destr); 3619 cx_test_register(suite, test_list_ll_reserve_and_shrink); 3620 cx_test_register(suite, test_list_pll_reserve_and_shrink); 3621 cx_test_register(suite, test_list_ll_clone_into_arl); 3622 cx_test_register(suite, test_list_pll_clone_into_arl); 3623 cx_test_register(suite, test_list_ll_clone_into_ll); 3624 cx_test_register(suite, test_list_pll_clone_into_ll); 3625 cx_test_register(suite, test_list_ll_clone_into_parl); 3626 cx_test_register(suite, test_list_pll_clone_into_parl); 3627 cx_test_register(suite, test_list_ll_clone_into_pll); 3628 cx_test_register(suite, test_list_pll_clone_into_pll); 3629 cx_test_register(suite, test_list_ll_clone_alloc_fail_into_arl); 3630 cx_test_register(suite, test_list_pll_clone_alloc_fail_into_arl); 3631 cx_test_register(suite, test_list_ll_clone_alloc_fail_into_ll); 3632 cx_test_register(suite, test_list_pll_clone_alloc_fail_into_ll); 3633 cx_test_register(suite, test_list_ll_clone_alloc_fail_into_parl); 3634 cx_test_register(suite, test_list_pll_clone_alloc_fail_into_parl); 3635 cx_test_register(suite, test_list_ll_clone_alloc_fail_into_pll); 3636 cx_test_register(suite, test_list_pll_clone_alloc_fail_into_pll); 3637 3638 return suite; 3639 } 3640 3641 CxTestSuite *cx_test_suite_linked_list_defaulted_funcs(void) { 3642 CxTestSuite *suite = cx_test_suite_new( 3643 "linked_list with defaulted functions"); 3644 3645 cx_test_register(suite, test_list_llm_insert_array); 3646 cx_test_register(suite, test_list_pllm_insert_array); 3647 cx_test_register(suite, test_list_llm_emplace_array); 3648 cx_test_register(suite, test_list_pllm_emplace_array); 3649 cx_test_register(suite, test_list_llm_insert_sorted); 3650 cx_test_register(suite, test_list_pllm_insert_sorted); 3651 cx_test_register(suite, test_list_llm_insert_unique); 3652 cx_test_register(suite, test_list_pllm_insert_unique); 3653 cx_test_register(suite, test_list_llm_insert_unique_not_sorted); 3654 cx_test_register(suite, test_list_pllm_insert_unique_not_sorted); 3655 cx_test_register(suite, test_list_llm_swap); 3656 cx_test_register(suite, test_list_pllm_swap); 3657 cx_test_register(suite, test_list_llm_sort); 3658 cx_test_register(suite, test_list_pllm_sort); 3659 3660 cx_test_register(suite, test_list_ll_compare_unoptimized); 3661 cx_test_register(suite, test_list_pll_compare_unoptimized); 3662 cx_test_register(suite, test_list_llm_compare_unoptimized); 3663 cx_test_register(suite, test_list_pllm_compare_unoptimized); 3664 3665 return suite; 3666 } 3667 3668 CxTestSuite *cx_test_suite_kv_list(void) { 3669 CxTestSuite *suite = cx_test_suite_new("kv_list"); 3670 3671 cx_test_register(suite, test_list_kvl_add); 3672 cx_test_register(suite, test_list_pkvl_add); 3673 cx_test_register(suite, test_list_kvl_insert); 3674 cx_test_register(suite, test_list_pkvl_insert); 3675 cx_test_register(suite, test_list_kvl_emplace); 3676 cx_test_register(suite, test_list_pkvl_emplace); 3677 cx_test_register(suite, test_list_kvl_insert_array); 3678 cx_test_register(suite, test_list_pkvl_insert_array); 3679 cx_test_register(suite, test_list_kvl_emplace_array); 3680 cx_test_register(suite, test_list_pkvl_emplace_array); 3681 cx_test_register(suite, test_list_kvl_insert_sorted); 3682 cx_test_register(suite, test_list_pkvl_insert_sorted); 3683 cx_test_register(suite, test_list_kvl_insert_unique); 3684 cx_test_register(suite, test_list_pkvl_insert_unique); 3685 cx_test_register(suite, test_list_kvl_insert_unique_not_sorted); 3686 cx_test_register(suite, test_list_pkvl_insert_unique_not_sorted); 3687 cx_test_register(suite, test_list_kvl_remove); 3688 cx_test_register(suite, test_list_pkvl_remove); 3689 cx_test_register(suite, test_list_kvl_remove_and_get); 3690 cx_test_register(suite, test_list_pkvl_remove_and_get); 3691 cx_test_register(suite, test_list_kvl_remove_array); 3692 cx_test_register(suite, test_list_pkvl_remove_array); 3693 cx_test_register(suite, test_list_kvl_find_remove); 3694 cx_test_register(suite, test_list_pkvl_find_remove); 3695 cx_test_register(suite, test_list_kvl_find_remove_sorted); 3696 cx_test_register(suite, test_list_pkvl_find_remove_sorted); 3697 cx_test_register(suite, test_list_kvl_contains); 3698 cx_test_register(suite, test_list_pkvl_contains); 3699 cx_test_register(suite, test_list_kvl_clear); 3700 cx_test_register(suite, test_list_pkvl_clear); 3701 cx_test_register(suite, test_list_kvl_at); 3702 cx_test_register(suite, test_list_pkvl_at); 3703 cx_test_register(suite, test_list_kvl_set); 3704 cx_test_register(suite, test_list_pkvl_set); 3705 cx_test_register(suite, test_list_kvl_swap); 3706 cx_test_register(suite, test_list_pkvl_swap); 3707 cx_test_register(suite, test_list_kvl_find); 3708 cx_test_register(suite, test_list_pkvl_find); 3709 cx_test_register(suite, test_list_kvl_sort); 3710 cx_test_register(suite, test_list_pkvl_sort); 3711 cx_test_register(suite, test_list_kvl_reverse); 3712 cx_test_register(suite, test_list_pkvl_reverse); 3713 cx_test_register(suite, test_list_kvl_iterator); 3714 cx_test_register(suite, test_list_pkvl_iterator); 3715 cx_test_register(suite, test_list_kvl_insert_with_iterator); 3716 cx_test_register(suite, test_list_pkvl_insert_with_iterator); 3717 cx_test_register(suite, test_list_kvl_compare_ll); 3718 cx_test_register(suite, test_list_kvl_compare_arl); 3719 cx_test_register(suite, test_list_kvl_compare_pll); 3720 cx_test_register(suite, test_list_kvl_compare_parl); 3721 cx_test_register(suite, test_list_pkvl_compare_ll); 3722 cx_test_register(suite, test_list_pkvl_compare_arl); 3723 cx_test_register(suite, test_list_pkvl_compare_pll); 3724 cx_test_register(suite, test_list_pkvl_compare_parl); 3725 cx_test_register(suite, test_list_kvl_simple_destr); 3726 cx_test_register(suite, test_list_pkvl_simple_destr); 3727 cx_test_register(suite, test_list_kvl_advanced_destr); 3728 cx_test_register(suite, test_list_pkvl_advanced_destr); 3729 cx_test_register(suite, test_list_kvl_reserve_and_shrink); 3730 cx_test_register(suite, test_list_pkvl_reserve_and_shrink); 3731 // note: kv-lists also support a list clone, but that does not clone the keys 3732 cx_test_register(suite, test_list_kvl_clone_into_arl); 3733 cx_test_register(suite, test_list_pkvl_clone_into_arl); 3734 cx_test_register(suite, test_list_kvl_clone_into_ll); 3735 cx_test_register(suite, test_list_pkvl_clone_into_ll); 3736 cx_test_register(suite, test_list_kvl_clone_into_parl); 3737 cx_test_register(suite, test_list_pkvl_clone_into_parl); 3738 cx_test_register(suite, test_list_kvl_clone_into_pll); 3739 cx_test_register(suite, test_list_pkvl_clone_into_pll); 3740 cx_test_register(suite, test_list_kvl_clone_alloc_fail_into_arl); 3741 cx_test_register(suite, test_list_pkvl_clone_alloc_fail_into_arl); 3742 cx_test_register(suite, test_list_kvl_clone_alloc_fail_into_ll); 3743 cx_test_register(suite, test_list_pkvl_clone_alloc_fail_into_ll); 3744 cx_test_register(suite, test_list_kvl_clone_alloc_fail_into_parl); 3745 cx_test_register(suite, test_list_pkvl_clone_alloc_fail_into_parl); 3746 cx_test_register(suite, test_list_kvl_clone_alloc_fail_into_pll); 3747 cx_test_register(suite, test_list_pkvl_clone_alloc_fail_into_pll); 3748 3749 return suite; 3750 } 3751 3752 CxTestSuite *cx_test_suite_empty_list(void) { 3753 CxTestSuite *suite = cx_test_suite_new("empty list dummy"); 3754 3755 cx_test_register(suite, test_empty_list_size); 3756 cx_test_register(suite, test_empty_list_iterator); 3757 cx_test_register(suite, test_null_list_iterator); 3758 cx_test_register(suite, test_empty_list_noops); 3759 cx_test_register(suite, test_empty_list_at); 3760 cx_test_register(suite, test_empty_list_find); 3761 cx_test_register(suite, test_empty_list_compare); 3762 cx_test_register(suite, test_null_list_free); 3763 3764 return suite; 3765 } 3766 3767 CxTestSuite *cx_test_suite_list_set_ops(void) { 3768 CxTestSuite *suite = cx_test_suite_new("list collection operations"); 3769 3770 // we do not perform the following tests with every combination of list types 3771 cx_test_register(suite, test_list_union_unsorted); 3772 cx_test_register(suite, test_list_union_sorted); 3773 cx_test_register(suite, test_list_union_unsorted_alloc_fail); 3774 cx_test_register(suite, test_list_union_sorted_alloc_fail); 3775 cx_test_register(suite, test_list_difference_unsorted); 3776 cx_test_register(suite, test_list_difference_sorted); 3777 cx_test_register(suite, test_list_difference_unsorted_alloc_fail); 3778 cx_test_register(suite, test_list_difference_sorted_alloc_fail); 3779 cx_test_register(suite, test_list_intersection_unsorted); 3780 cx_test_register(suite, test_list_intersection_sorted); 3781 cx_test_register(suite, test_list_intersection_unsorted_alloc_fail); 3782 cx_test_register(suite, test_list_intersection_sorted_alloc_fail); 3783 cx_test_register(suite, test_list_simple_clones); 3784 3785 return suite; 3786 } 3787 3788 CxTestSuite *cx_test_suite_list_corner_cases(void) { 3789 CxTestSuite *suite = cx_test_suite_new("list corner cases"); 3790 3791 cx_test_register(suite, test_list_pointer_list_supports_null); 3792 cx_test_register(suite, test_list_use_insert_unique_with_duplicates_in_source); 3793 cx_test_register(suite, test_list_use_insert_unique_to_remove_duplicates); 3794 3795 return suite; 3796 } 3797