test_dynamic_array.c (17283B)
1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSys library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSys library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "dynamic_array.h" 17 #include "test_utils.h" 18 19 static const char* strs[] = { 20 "Rcvfbqr", "1,", "XARR-QRRC", "VA", "GUR", "QRNQ:\n", 21 "---------------------------------", "BAPR", "LBH", "ORNG", "GUR", "OVT", 22 "ONQNFFRF", "NAQ", "PYRNA", "BHG", "GUR", "ZBBA", "ONFR", "LBH'ER", 23 "FHCCBFRQ", "GB\n", "JVA", "NERA'G", "LBH?", "NERA'G", "LBH?", "JURER'F", 24 "LBHE", "SNG", "ERJNEQ", "NAQ", "GVPXRG", "UBZR?", "JUNG\n", "GUR", "URYY", 25 "VF", "GUVF?", "VG'F", "ABG", "FHCCBFRQ", "GB", "RAQ", "GUVF", "JNL!", "VG", 26 "FGVAXF", "YVXR", "EBGGRA", "ZRNG,", "OHG", "YBBXF", "YVXR", "GUR", "YBFG", 27 "QRVZBF", "ONFR.", "YBBXF", "YVXR\n", "LBH'ER", "FGHPX", "BA", "GUR", 28 "FUBERF", "BS", "URYY.", "GUR", "BAYL", "JNL", "BHG", "VF", "GUEBHTU.", "GB", 29 "PBAGVAHR", "GUR", "QBBZ", "RKCREVRAPR,", "CYNL", "GUR", "FUBERF", "BS", 30 "URYY", "NAQ", "VGF", "NZNMVAT\n", "FRDHRY,", "VASREAB!", 31 32 "Rcvfbqr 2, GUR FUBERF BS URYY:\n\ 33 ------------------------------\n\ 34 \n\ 35 LBH'IR QBAR VG! GUR UVQRBHF PLORE- QRZBA YBEQ GUNG EHYRQ GUR YBFG QRVZBF ZBBA\n\ 36 ONFR UNF ORRA FYNVA NAQ LBH NER GEVHZCUNAG! OHG ... JURER NER LBH? LBH\n\ 37 PYNZORE GB GUR RQTR BS GUR ZBBA NAQ YBBX QBJA GB FRR GUR NJSHY GEHGU.\n\ 38 \n", 39 40 "QRVZBF SYBNGF NOBIR URYY VGFRYS! LBH'IR ARIRE URNEQ BS NALBAR RFPNCVAT SEBZ\n\ 41 URYY, OHG LBH'YY ZNXR GUR ONFGNEQF FBEEL GURL RIRE URNEQ BS LBH! DHVPXYL, LBH\n\ 42 ENCCRY QBJA GB GUR FHESNPR BS URYY.\n\ 43 \n\ 44 ABJ, VG'F BA GB GUR SVANY PUNCGRE BS QBBZ! -- VASREAB." 45 }; 46 47 #define DARRAY_NAME str 48 #define DARRAY_DATA const char* 49 #include "dynamic_array.h" 50 51 static void 52 test_cstr(struct mem_allocator* allocator) 53 { 54 struct darray_str darray; 55 const size_t nstrs = sizeof(strs)/sizeof(const char*); 56 size_t i = 0; 57 58 darray_str_init(NULL, &darray); 59 CHK(darray_str_size_get(&darray) == 0); 60 darray_str_clear(&darray); 61 CHK(darray_str_size_get(&darray) == 0); 62 63 FOR_EACH(i, 0, 4) { 64 darray_str_push_back(&darray, strs + i); 65 } 66 CHK(darray_str_size_get(&darray) == 4); 67 darray_str_clear(&darray); 68 CHK(darray_str_size_get(&darray) == 0); 69 darray_str_release(&darray); 70 71 darray_str_init(allocator, &darray); 72 FOR_EACH(i, 0, nstrs) { 73 darray_str_push_back(&darray, strs + i); 74 } 75 FOR_EACH(i, 0, nstrs) { 76 CHK(DARRAY_BUF(&darray) == darray_str_cdata_get(&darray)); 77 CHK(DARRAY_BUF(&darray) == darray_str_data_get(&darray)); 78 CHK(DARRAY_BUF((struct darray_str*)(&darray)) == DARRAY_BUF(&darray)); 79 CHK(strcmp(darray_str_cdata_get(&darray)[i], strs[i]) == 0); 80 CHK(strcmp(DARRAY_BUF(&darray)[i], strs[i]) == 0); 81 } 82 darray_str_purge(&darray); 83 CHK(darray_str_size_get(&darray) == 0); 84 darray_str_release(&darray); 85 86 darray_str_init(allocator, &darray); 87 CHK(darray_str_size_get(&darray) == 0); 88 darray_str_resize(&darray, 8); 89 CHK(darray_str_size_get(&darray) == 8); 90 darray_str_resize(&darray, 0); 91 CHK(darray_str_size_get(&darray) == 0); 92 darray_str_resize(&darray, 33); 93 CHK(darray_str_size_get(&darray) == 33); 94 darray_str_release(&darray); 95 } 96 97 #include "str.h" 98 #define DARRAY_NAME string 99 #define DARRAY_DATA struct str 100 #define DARRAY_FUNCTOR_INIT str_init 101 #define DARRAY_FUNCTOR_COPY str_copy 102 #define DARRAY_FUNCTOR_RELEASE str_release 103 #define DARRAY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release 104 #include "dynamic_array.h" 105 106 static void 107 test_string 108 (struct mem_allocator* allocator0, 109 struct mem_allocator* allocator1) 110 { 111 struct darray_string darray, darray2; 112 const size_t nstrs = sizeof(strs)/sizeof(const char*); 113 size_t i = 0; 114 115 darray_string_init(allocator0, &darray); 116 darray_string_init(allocator1, &darray2); 117 CHK(darray_string_size_get(&darray) == 0); 118 CHK(darray_string_size_get(&darray2) == 0); 119 120 darray_string_resize(&darray, nstrs); 121 FOR_EACH(i, 0, nstrs) { 122 str_set(darray_string_data_get(&darray) + i, strs[i]); 123 } 124 CHK(darray_string_size_get(&darray) == nstrs); 125 FOR_EACH(i, 0, nstrs) { 126 const struct str* str = darray_string_cdata_get(&darray) + i; 127 CHK(strcmp(str_cget(str), strs[i]) == 0); 128 } 129 130 darray_string_copy(&darray, &darray2); 131 CHK(darray_string_size_get(&darray) == 0); 132 FOR_EACH(i, 0, nstrs) { 133 struct str str; 134 str_init(allocator1, &str); 135 str_set(&str, strs[i]); 136 darray_string_push_back(&darray, &str); 137 str_release(&str); 138 } 139 140 CHK(darray_string_size_get(&darray) == nstrs); 141 FOR_EACH(i, 0, nstrs) { 142 const struct str* str = darray_string_cdata_get(&darray) + i; 143 CHK(strcmp(str_cget(str), strs[i]) == 0); 144 } 145 146 darray_string_copy(&darray2, &darray); 147 CHK(darray_string_size_get(&darray2) == nstrs); 148 FOR_EACH(i, 0, nstrs) { 149 const struct str* str = darray_string_cdata_get(&darray) + i; 150 const struct str* str2 = darray_string_cdata_get(&darray2) + i; 151 CHK(strcmp(str_cget(str), strs[i]) == 0); 152 CHK(strcmp(str_cget(str2), strs[i]) == 0); 153 } 154 darray_string_clear(&darray2); 155 i = MEM_ALLOCATED_SIZE(allocator1); 156 darray_string_purge(&darray2); 157 CHK(MEM_ALLOCATED_SIZE(allocator1) < i); 158 CHK(darray_string_size_get(&darray2) == 0); 159 160 darray_string_copy_and_clear(&darray2, &darray); 161 CHK(darray_string_size_get(&darray2) == nstrs); 162 CHK(darray_string_size_get(&darray) == 0); 163 FOR_EACH(i, 0, nstrs) { 164 const struct str* str = darray_string_cdata_get(&darray2) + i; 165 CHK(strcmp(str_cget(str), strs[i]) == 0); 166 } 167 168 darray_string_copy_and_release(&darray, &darray2); 169 FOR_EACH(i, 0, nstrs) { 170 const struct str* str = darray_string_cdata_get(&darray) + i; 171 CHK(strcmp(str_cget(str), strs[i]) == 0); 172 } 173 174 darray_string_release(&darray); 175 } 176 177 #define DARRAY_NAME int 178 #define DARRAY_DATA int 179 #include "dynamic_array.h" 180 181 static void 182 test_swap_int 183 (struct mem_allocator* allocator0, 184 struct mem_allocator* allocator1) 185 { 186 struct darray_int a; 187 struct darray_int b; 188 int i; 189 190 #define PUSH_BACK(V, E) { \ 191 const int i__ = (E); \ 192 CHK(darray_int_push_back(&(V), &i__) == RES_OK); \ 193 } (void)0 194 195 darray_int_init(allocator0, &a); 196 darray_int_init(allocator1, &b); 197 198 PUSH_BACK(a, 1); 199 PUSH_BACK(a, 2); 200 PUSH_BACK(a, 3); 201 PUSH_BACK(b,-1); 202 PUSH_BACK(b,-2); 203 204 CHK(darray_int_swap(&a, &b) == RES_OK); 205 CHK(darray_int_size_get(&a) == 2); 206 CHK(darray_int_size_get(&b) == 3); 207 208 CHK(darray_int_cdata_get(&a)[0] == -1); 209 CHK(darray_int_cdata_get(&a)[1] == -2); 210 CHK(darray_int_cdata_get(&b)[0] == 1); 211 CHK(darray_int_cdata_get(&b)[1] == 2); 212 CHK(darray_int_cdata_get(&b)[2] == 3); 213 214 darray_int_clear(&a); 215 darray_int_clear(&b); 216 217 FOR_EACH(i, 0, 128) PUSH_BACK(a, i); 218 FOR_EACH(i, 0, 112) PUSH_BACK(b,-i); 219 220 CHK(darray_int_swap(&a, &b) == RES_OK); 221 CHK(darray_int_size_get(&a) == 112); 222 CHK(darray_int_size_get(&b) == 128); 223 FOR_EACH(i, 0, 112) CHK(darray_int_cdata_get(&a)[i] == -i); 224 FOR_EACH(i, 0, 128) CHK(darray_int_cdata_get(&b)[i] == i); 225 226 darray_int_release(&b); 227 darray_int_init(allocator1, &b); 228 PUSH_BACK(b, -1); 229 PUSH_BACK(b, -314); 230 231 CHK(darray_int_swap(&a, &b) == RES_OK); 232 CHK(darray_int_size_get(&a) == 2); 233 CHK(darray_int_size_get(&b) == 112); 234 FOR_EACH(i, 0, 112) CHK(darray_int_cdata_get(&b)[i] == -i); 235 CHK(darray_int_cdata_get(&a)[0] == -1); 236 CHK(darray_int_cdata_get(&a)[1] == -314); 237 238 darray_int_release(&a); 239 darray_int_release(&b); 240 241 #undef PUSH_BACK 242 } 243 244 static void 245 test_swap_string 246 (struct mem_allocator* allocator0, 247 struct mem_allocator* allocator1) 248 { 249 struct darray_string a; 250 struct darray_string b; 251 const size_t nstrs = sizeof(strs)/sizeof(const char*); 252 size_t i; 253 254 #define PUSH_BACK(V, CStr) { \ 255 struct str str__; \ 256 str_init(allocator1, &str__); \ 257 CHK(str_set(&str__, CStr) == RES_OK); \ 258 CHK(darray_string_push_back(&(V), &str__) == RES_OK); \ 259 str_release(&str__); \ 260 } (void)0 261 262 darray_string_init(allocator0, &a); 263 darray_string_init(allocator1, &b); 264 265 CHK(nstrs >= 3); 266 PUSH_BACK(a, strs[0]); 267 PUSH_BACK(a, strs[1]); 268 PUSH_BACK(a, strs[2]); 269 PUSH_BACK(b, strs[3]); 270 PUSH_BACK(b, strs[4]); 271 272 CHK(darray_string_swap(&a, &b) == RES_OK); 273 CHK(darray_string_size_get(&a) == 2); 274 CHK(darray_string_size_get(&b) == 3); 275 276 CHK(strcmp(str_cget(darray_string_cdata_get(&a)+0), strs[3]) == 0); 277 CHK(strcmp(str_cget(darray_string_cdata_get(&a)+1), strs[4]) == 0); 278 CHK(strcmp(str_cget(darray_string_cdata_get(&b)+0), strs[0]) == 0); 279 CHK(strcmp(str_cget(darray_string_cdata_get(&b)+1), strs[1]) == 0); 280 CHK(strcmp(str_cget(darray_string_cdata_get(&b)+2), strs[2]) == 0); 281 282 darray_string_clear(&a); 283 darray_string_clear(&b); 284 285 FOR_EACH(i, 0, nstrs/2) PUSH_BACK(a, strs[i]); 286 FOR_EACH(i, nstrs/2, nstrs) PUSH_BACK(b, strs[i]); 287 288 CHK(darray_string_swap(&a, &b) == RES_OK); 289 CHK(darray_string_size_get(&a) == nstrs/2); 290 CHK(darray_string_size_get(&b) == nstrs - nstrs/2); 291 292 FOR_EACH(i, 0, nstrs/2) { 293 CHK(strcmp(str_cget(darray_string_cdata_get(&b)+i), strs[i]) == 0); 294 } 295 FOR_EACH(i, 0, nstrs - nstrs/2) { 296 CHK(strcmp(str_cget(darray_string_cdata_get(&a)+i), strs[i+nstrs/2]) == 0); 297 } 298 299 darray_string_release(&b); 300 darray_string_init(allocator1, &b); 301 PUSH_BACK(b, strs[0]); 302 PUSH_BACK(b, strs[1]); 303 304 CHK(darray_string_swap(&a, &b) == RES_OK); 305 CHK(darray_string_size_get(&a) == 2); 306 CHK(darray_string_size_get(&b) == nstrs - nstrs/2); 307 FOR_EACH(i, 0, nstrs - nstrs/2) { 308 CHK(strcmp(str_cget(darray_string_cdata_get(&b)+i), strs[i+nstrs/2]) == 0); 309 } 310 311 CHK(strcmp(str_cget(darray_string_cdata_get(&a)+0), strs[0]) == 0); 312 CHK(strcmp(str_cget(darray_string_cdata_get(&a)+1), strs[1]) == 0); 313 314 darray_string_release(&a); 315 darray_string_release(&b); 316 317 #undef PUSH_BACK 318 } 319 320 #define DARRAY_NAME byte 321 #define DARRAY_DATA char 322 #include "dynamic_array.h" 323 324 #define DARRAY_NAME byte64 325 #define DARRAY_DATA char 326 #define DARRAY_ALIGNMENT 64 327 #include "dynamic_array.h" 328 329 #define DARRAY_NAME byte1K 330 #define DARRAY_DATA char 331 #define DARRAY_ALIGNMENT 1024 332 #include "dynamic_array.h" 333 334 static void 335 test_alignment(struct mem_allocator* allocator) 336 { 337 struct darray_byte bytes; 338 struct darray_byte64 bytes64; 339 struct darray_byte1K bytes1K; 340 341 CHK(allocator != NULL); 342 343 darray_byte_init(allocator, &bytes); 344 CHK(darray_byte_resize(&bytes, 2) == RES_OK); 345 CHK(IS_ALIGNED(darray_byte_cdata_get(&bytes), ALIGNOF(char)) == 1); 346 CHK(darray_byte_resize(&bytes, 314159) == RES_OK); 347 CHK(IS_ALIGNED(darray_byte_cdata_get(&bytes), ALIGNOF(char)) == 1); 348 darray_byte_release(&bytes); 349 350 darray_byte64_init(allocator, &bytes64); 351 CHK(darray_byte64_resize(&bytes64, 2) == RES_OK); 352 CHK(IS_ALIGNED(darray_byte64_cdata_get(&bytes64), 64) == 1); 353 CHK(darray_byte64_resize(&bytes64, 314159) == RES_OK); 354 CHK(IS_ALIGNED(darray_byte64_cdata_get(&bytes64), 64) == 1); 355 darray_byte64_release(&bytes64); 356 357 darray_byte1K_init(allocator, &bytes1K); 358 CHK(darray_byte1K_resize(&bytes1K, 2) == RES_OK); 359 CHK(IS_ALIGNED(darray_byte1K_cdata_get(&bytes1K), 1024) == 1); 360 CHK(darray_byte1K_resize(&bytes1K, 314159) == RES_OK); 361 CHK(IS_ALIGNED(darray_byte1K_cdata_get(&bytes1K), 1024) == 1); 362 darray_byte1K_release(&bytes1K); 363 } 364 365 static void 366 test_allocation_policy(struct mem_allocator* allocator) 367 { 368 struct darray_int integers; 369 struct darray_int integers2; 370 const int* mem; 371 int i; 372 373 darray_int_init(allocator, &integers); 374 darray_int_init(allocator, &integers2); 375 CHK(darray_int_capacity(&integers) == 0); 376 377 CHK(darray_int_reserve(&integers, 33) == RES_OK); 378 CHK(darray_int_capacity(&integers) == 33); 379 CHK(darray_int_size_get(&integers) == 0); 380 mem = darray_int_cdata_get(&integers); 381 382 CHK(darray_int_resize(&integers, 14) == RES_OK); 383 CHK(darray_int_capacity(&integers) == 33); 384 CHK(darray_int_size_get(&integers) == 14); 385 CHK(darray_int_cdata_get(&integers) == mem); 386 387 darray_int_clear(&integers); 388 CHK(darray_int_capacity(&integers) == 33); 389 CHK(darray_int_size_get(&integers) == 0); 390 CHK(darray_int_cdata_get(&integers) == mem); 391 392 CHK(darray_int_resize(&integers, 35) == RES_OK); 393 CHK(darray_int_capacity(&integers) == 35); 394 CHK(darray_int_size_get(&integers) == 35); 395 CHK(darray_int_cdata_get(&integers) != mem); 396 397 darray_int_purge(&integers); 398 CHK(darray_int_capacity(&integers) == 0); 399 CHK(darray_int_size_get(&integers) == 0); 400 401 i = 0; 402 CHK(darray_int_push_back(&integers, &i) == RES_OK); 403 CHK(darray_int_capacity(&integers) == 1); 404 CHK(darray_int_size_get(&integers) == 1); 405 mem = darray_int_cdata_get(&integers); 406 407 CHK(darray_int_push_back(&integers, &i) == RES_OK); 408 CHK(darray_int_capacity(&integers) == 2); 409 CHK(darray_int_size_get(&integers) == 2); 410 CHK(darray_int_cdata_get(&integers) != mem); 411 mem = darray_int_cdata_get(&integers); 412 413 CHK(darray_int_push_back(&integers, &i) == RES_OK); 414 CHK(darray_int_capacity(&integers) == 4); 415 CHK(darray_int_size_get(&integers) == 3); 416 CHK(darray_int_cdata_get(&integers) != mem); 417 mem = darray_int_cdata_get(&integers); 418 419 CHK(darray_int_push_back(&integers, &i) == RES_OK); 420 CHK(darray_int_capacity(&integers) == 4); 421 CHK(darray_int_size_get(&integers) == 4); 422 CHK(darray_int_cdata_get(&integers) == mem); 423 424 CHK(darray_int_push_back(&integers, &i) == RES_OK); 425 CHK(darray_int_capacity(&integers) == 8); 426 CHK(darray_int_size_get(&integers) == 5); 427 CHK(darray_int_cdata_get(&integers) != mem); 428 mem = darray_int_cdata_get(&integers); 429 430 darray_int_purge(&integers); 431 CHK(darray_int_capacity(&integers) == 0); 432 CHK(darray_int_size_get(&integers) == 0); 433 CHK(darray_int_cdata_get(&integers) == NULL); 434 435 FOR_EACH(i, 0, 33) { 436 CHK(darray_int_push_back(&integers, &i) == RES_OK); 437 } 438 CHK(darray_int_capacity(&integers) == 64); 439 CHK(darray_int_size_get(&integers) == 33); 440 441 darray_int_purge(&integers); 442 CHK(darray_int_capacity(&integers) == 0); 443 CHK(darray_int_size_get(&integers) == 0); 444 CHK(darray_int_cdata_get(&integers) == NULL); 445 446 CHK(darray_int_resize(&integers, 10) == RES_OK); 447 CHK(darray_int_capacity(&integers) == 10); 448 CHK(darray_int_size_get(&integers) == 10); 449 450 CHK(darray_int_push_back(&integers, &i) == RES_OK); 451 CHK(darray_int_capacity(&integers) == 20); 452 CHK(darray_int_size_get(&integers) == 11); 453 454 CHK(darray_int_push_back(&integers, &i) == RES_OK); 455 CHK(darray_int_capacity(&integers) == 20); 456 CHK(darray_int_size_get(&integers) == 12); 457 458 CHK(darray_int_resize(&integers, 17) == RES_OK); 459 CHK(darray_int_capacity(&integers) == 20); 460 CHK(darray_int_size_get(&integers) == 17); 461 462 CHK(darray_int_resize(&integers, 24) == RES_OK); 463 CHK(darray_int_capacity(&integers) == 34); 464 CHK(darray_int_size_get(&integers) == 24); 465 466 CHK(darray_int_resize(&integers, 41) == RES_OK); 467 CHK(darray_int_capacity(&integers) == 48); 468 CHK(darray_int_size_get(&integers) == 41); 469 470 CHK(darray_int_reserve(&integers, 30) == RES_OK); 471 CHK(darray_int_capacity(&integers) == 48); 472 CHK(darray_int_size_get(&integers) == 41); 473 474 CHK(darray_int_reserve(&integers, 49) == RES_OK); 475 CHK(darray_int_capacity(&integers) == 49); 476 CHK(darray_int_size_get(&integers) == 41); 477 478 CHK(darray_int_resize(&integers2, 42) == RES_OK); 479 CHK(darray_int_copy(&integers, &integers2) == RES_OK); 480 CHK(darray_int_capacity(&integers) == 49); 481 CHK(darray_int_size_get(&integers) == 42); 482 483 CHK(darray_int_copy(&integers2, &integers) == RES_OK); 484 CHK(darray_int_capacity(&integers2) == 42); 485 CHK(darray_int_size_get(&integers2) == 42); 486 487 CHK(darray_int_reserve(&integers2, 70) == RES_OK); 488 CHK(darray_int_copy(&integers, &integers2) == RES_OK); 489 CHK(darray_int_capacity(&integers) == 49); 490 CHK(darray_int_size_get(&integers) == 42); 491 492 darray_int_release(&integers); 493 darray_int_release(&integers2); 494 } 495 496 int 497 main(int argc, char** argv) 498 { 499 struct mem_allocator allocator_proxy; 500 (void)argc, (void)argv; 501 502 mem_init_proxy_allocator(&allocator_proxy, &mem_default_allocator); 503 504 test_cstr(&allocator_proxy); 505 506 test_string(&allocator_proxy, &allocator_proxy); 507 test_string(&allocator_proxy, &mem_default_allocator); 508 509 test_swap_int(&mem_default_allocator, &allocator_proxy); 510 test_swap_int(&allocator_proxy, &allocator_proxy); 511 512 test_swap_string(&mem_default_allocator, &allocator_proxy); 513 test_swap_string(&allocator_proxy, &allocator_proxy); 514 515 test_alignment(&mem_default_allocator); 516 test_allocation_policy(&mem_default_allocator); 517 518 check_memory_allocator(&allocator_proxy); 519 mem_shutdown_proxy_allocator(&allocator_proxy); 520 CHK(mem_allocated_size() == 0); 521 return 0; 522 }