1 /*************************************************************************************************** 2 3 Zyan Core Library (Zycore-C) 4 5 Original Author : Florian Bernd 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 25 ***************************************************************************************************/ 26 27 /** 28 * @file 29 * Implements the vector container class. 30 */ 31 32 #ifndef ZYCORE_VECTOR_H 33 #define ZYCORE_VECTOR_H 34 35 #include <Zycore/Allocator.h> 36 #include <Zycore/Comparison.h> 37 #include <Zycore/Object.h> 38 #include <Zycore/Status.h> 39 #include <Zycore/Types.h> 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /* ============================================================================================== */ 46 /* Constants */ 47 /* ============================================================================================== */ 48 49 /** 50 * The initial minimum capacity (number of elements) for all dynamically allocated vector 51 * instances. 52 */ 53 #define ZYAN_VECTOR_MIN_CAPACITY 1 54 55 /** 56 * The default growth factor for all vector instances. 57 */ 58 #define ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR 2 59 60 /** 61 * The default shrink threshold for all vector instances. 62 */ 63 #define ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD 4 64 65 /* ============================================================================================== */ 66 /* Enums and types */ 67 /* ============================================================================================== */ 68 69 /** 70 * Defines the `ZyanVector` struct. 71 * 72 * All fields in this struct should be considered as "private". Any changes may lead to unexpected 73 * behavior. 74 */ 75 typedef struct ZyanVector_ 76 { 77 /** 78 * The memory allocator. 79 */ 80 ZyanAllocator* allocator; 81 /** 82 * The growth factor. 83 */ 84 ZyanU8 growth_factor; 85 /** 86 * The shrink threshold. 87 */ 88 ZyanU8 shrink_threshold; 89 /** 90 * The current number of elements in the vector. 91 */ 92 ZyanUSize size; 93 /** 94 * The maximum capacity (number of elements). 95 */ 96 ZyanUSize capacity; 97 /** 98 * The size of a single element in bytes. 99 */ 100 ZyanUSize element_size; 101 /** 102 * The element destructor callback. 103 */ 104 ZyanMemberProcedure destructor; 105 /** 106 * The data pointer. 107 */ 108 void* data; 109 } ZyanVector; 110 111 /* ============================================================================================== */ 112 /* Macros */ 113 /* ============================================================================================== */ 114 115 /* ---------------------------------------------------------------------------------------------- */ 116 /* General */ 117 /* ---------------------------------------------------------------------------------------------- */ 118 119 /** 120 * Defines an uninitialized `ZyanVector` instance. 121 */ 122 #define ZYAN_VECTOR_INITIALIZER \ 123 { \ 124 /* allocator */ ZYAN_NULL, \ 125 /* growth_factor */ 0, \ 126 /* shrink_threshold */ 0, \ 127 /* size */ 0, \ 128 /* capacity */ 0, \ 129 /* element_size */ 0, \ 130 /* destructor */ ZYAN_NULL, \ 131 /* data */ ZYAN_NULL \ 132 } 133 134 /* ---------------------------------------------------------------------------------------------- */ 135 /* Helper macros */ 136 /* ---------------------------------------------------------------------------------------------- */ 137 138 /** 139 * Returns the value of the element at the given `index`. 140 * 141 * @param type The desired value type. 142 * @param vector A pointer to the `ZyanVector` instance. 143 * @param index The element index. 144 * 145 * @result The value of the desired element in the vector. 146 * 147 * Note that this function is unsafe and might dereference a null-pointer. 148 */ 149 #ifdef __cplusplus 150 #define ZYAN_VECTOR_GET(type, vector, index) \ 151 (*reinterpret_cast<const type*>(ZyanVectorGet(vector, index))) 152 #else 153 #define ZYAN_VECTOR_GET(type, vector, index) \ 154 (*(const type*)ZyanVectorGet(vector, index)) 155 #endif 156 157 /** 158 * Loops through all elements of the vector. 159 * 160 * @param type The desired value type. 161 * @param vector A pointer to the `ZyanVector` instance. 162 * @param item_name The name of the iterator item. 163 * @param body The body to execute for each item in the vector. 164 */ 165 #define ZYAN_VECTOR_FOREACH(type, vector, item_name, body) \ 166 { \ 167 const ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name) = (vector)->size; \ 168 for (ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) = 0; \ 169 ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) < \ 170 ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name); \ 171 ++ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)) \ 172 { \ 173 const type item_name = ZYAN_VECTOR_GET(type, vector, \ 174 ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)); \ 175 body \ 176 } \ 177 } 178 179 /** 180 * Loops through all elements of the vector. 181 * 182 * @param type The desired value type. 183 * @param vector A pointer to the `ZyanVector` instance. 184 * @param item_name The name of the iterator item. 185 * @param body The body to execute for each item in the vector. 186 */ 187 #define ZYAN_VECTOR_FOREACH_MUTABLE(type, vector, item_name, body) \ 188 { \ 189 const ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name) = (vector)->size; \ 190 for (ZyanUSize ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) = 0; \ 191 ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name) < \ 192 ZYAN_MACRO_CONCAT_EXPAND(size_d50d3303, item_name); \ 193 ++ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)) \ 194 { \ 195 type* const item_name = ZyanVectorGetMutable(vector, \ 196 ZYAN_MACRO_CONCAT_EXPAND(i_bfd62679, item_name)); \ 197 body \ 198 } \ 199 } 200 201 /* ---------------------------------------------------------------------------------------------- */ 202 203 /* ============================================================================================== */ 204 /* Exported functions */ 205 /* ============================================================================================== */ 206 207 /* ---------------------------------------------------------------------------------------------- */ 208 /* Constructor and destructor */ 209 /* ---------------------------------------------------------------------------------------------- */ 210 211 #ifndef ZYAN_NO_LIBC 212 213 /** 214 * Initializes the given `ZyanVector` instance. 215 * 216 * @param vector A pointer to the `ZyanVector` instance. 217 * @param element_size The size of a single element in bytes. 218 * @param capacity The initial capacity (number of elements). 219 * @param destructor A destructor callback that is invoked every time an item is deleted, or 220 * `ZYAN_NULL` if not needed. 221 * 222 * @return A zyan status code. 223 * 224 * The memory for the vector elements is dynamically allocated by the default allocator using the 225 * default growth factor and the default shrink threshold. 226 * 227 * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. 228 */ 229 ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorInit(ZyanVector* vector, 230 ZyanUSize element_size, ZyanUSize capacity, ZyanMemberProcedure destructor); 231 232 #endif // ZYAN_NO_LIBC 233 234 /** 235 * Initializes the given `ZyanVector` instance and sets a custom `allocator` and memory 236 * allocation/deallocation parameters. 237 * 238 * @param vector A pointer to the `ZyanVector` instance. 239 * @param element_size The size of a single element in bytes. 240 * @param capacity The initial capacity (number of elements). 241 * @param destructor A destructor callback that is invoked every time an item is deleted, 242 * or `ZYAN_NULL` if not needed. 243 * @param allocator A pointer to a `ZyanAllocator` instance. 244 * @param growth_factor The growth factor. 245 * @param shrink_threshold The shrink threshold. 246 * 247 * @return A zyan status code. 248 * 249 * A growth factor of `1` disables overallocation and a shrink threshold of `0` disables 250 * dynamic shrinking. 251 * 252 * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. 253 */ 254 ZYCORE_EXPORT ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size, 255 ZyanUSize capacity, ZyanMemberProcedure destructor, ZyanAllocator* allocator, 256 ZyanU8 growth_factor, ZyanU8 shrink_threshold); 257 258 /** 259 * Initializes the given `ZyanVector` instance and configures it to use a custom user 260 * defined buffer with a fixed size. 261 * 262 * @param vector A pointer to the `ZyanVector` instance. 263 * @param element_size The size of a single element in bytes. 264 * @param buffer A pointer to the buffer that is used as storage for the elements. 265 * @param capacity The maximum capacity (number of elements) of the buffer. 266 * @param destructor A destructor callback that is invoked every time an item is deleted, or 267 * `ZYAN_NULL` if not needed. 268 * 269 * @return A zyan status code. 270 * 271 * Finalization is not required for instances created by this function. 272 */ 273 ZYCORE_EXPORT ZyanStatus ZyanVectorInitCustomBuffer(ZyanVector* vector, ZyanUSize element_size, 274 void* buffer, ZyanUSize capacity, ZyanMemberProcedure destructor); 275 276 /** 277 * Destroys the given `ZyanVector` instance. 278 * 279 * @param vector A pointer to the `ZyanVector` instance.. 280 * 281 * @return A zyan status code. 282 */ 283 ZYCORE_EXPORT ZyanStatus ZyanVectorDestroy(ZyanVector* vector); 284 285 /* ---------------------------------------------------------------------------------------------- */ 286 /* Duplication */ 287 /* ---------------------------------------------------------------------------------------------- */ 288 289 #ifndef ZYAN_NO_LIBC 290 291 /** 292 * Initializes a new `ZyanVector` instance by duplicating an existing vector. 293 * 294 * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. 295 * @param source A pointer to the source vector. 296 * @param capacity The initial capacity (number of elements). 297 * 298 * This value is automatically adjusted to the size of the source vector, if 299 * a smaller value was passed. 300 * 301 * @return A zyan status code. 302 * 303 * The memory for the vector is dynamically allocated by the default allocator using the default 304 * growth factor and the default shrink threshold. 305 * 306 * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. 307 */ 308 ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorDuplicate(ZyanVector* destination, 309 const ZyanVector* source, ZyanUSize capacity); 310 311 #endif // ZYAN_NO_LIBC 312 313 /** 314 * Initializes a new `ZyanVector` instance by duplicating an existing vector and sets a 315 * custom `allocator` and memory allocation/deallocation parameters. 316 * 317 * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. 318 * @param source A pointer to the source vector. 319 * @param capacity The initial capacity (number of elements). 320 321 * This value is automatically adjusted to the size of the source 322 * vector, if a smaller value was passed. 323 * @param allocator A pointer to a `ZyanAllocator` instance. 324 * @param growth_factor The growth factor. 325 * @param shrink_threshold The shrink threshold. 326 * 327 * @return A zyan status code. 328 * 329 * A growth factor of `1` disables overallocation and a shrink threshold of `0` disables 330 * dynamic shrinking. 331 * 332 * Finalization with `ZyanVectorDestroy` is required for all instances created by this function. 333 */ 334 ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source, 335 ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold); 336 337 /** 338 * Initializes a new `ZyanVector` instance by duplicating an existing vector and 339 * configures it to use a custom user defined buffer with a fixed size. 340 * 341 * @param destination A pointer to the (uninitialized) destination `ZyanVector` instance. 342 * @param source A pointer to the source vector. 343 * @param buffer A pointer to the buffer that is used as storage for the elements. 344 * @param capacity The maximum capacity (number of elements) of the buffer. 345 346 * This function will fail, if the capacity of the buffer is less than the 347 * size of the source vector. 348 * 349 * @return A zyan status code. 350 * 351 * Finalization is not required for instances created by this function. 352 */ 353 ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateCustomBuffer(ZyanVector* destination, 354 const ZyanVector* source, void* buffer, ZyanUSize capacity); 355 356 /* ---------------------------------------------------------------------------------------------- */ 357 /* Element access */ 358 /* ---------------------------------------------------------------------------------------------- */ 359 360 /** 361 * Returns a constant pointer to the element at the given `index`. 362 * 363 * @param vector A pointer to the `ZyanVector` instance. 364 * @param index The element index. 365 * 366 * @return A constant pointer to the desired element in the vector or `ZYAN_NULL`, if an error 367 * occurred. 368 * 369 * Note that the returned pointer might get invalid when the vector is resized by either a manual 370 * call to the memory-management functions or implicitly by inserting or removing elements. 371 * 372 * Take a look at `ZyanVectorGetPointer` instead, if you need a function that returns a zyan status 373 * code. 374 */ 375 ZYCORE_EXPORT const void* ZyanVectorGet(const ZyanVector* vector, ZyanUSize index); 376 377 /** 378 * Returns a mutable pointer to the element at the given `index`. 379 * 380 * @param vector A pointer to the `ZyanVector` instance. 381 * @param index The element index. 382 * 383 * @return A mutable pointer to the desired element in the vector or `ZYAN_NULL`, if an error 384 * occurred. 385 * 386 * Note that the returned pointer might get invalid when the vector is resized by either a manual 387 * call to the memory-management functions or implicitly by inserting or removing elements. 388 * 389 * Take a look at `ZyanVectorGetPointerMutable` instead, if you need a function that returns a 390 * zyan status code. 391 */ 392 ZYCORE_EXPORT void* ZyanVectorGetMutable(const ZyanVector* vector, ZyanUSize index); 393 394 /** 395 * Returns a constant pointer to the element at the given `index`. 396 * 397 * @param vector A pointer to the `ZyanVector` instance. 398 * @param index The element index. 399 * @param value Receives a constant pointer to the desired element in the vector. 400 * 401 * Note that the returned pointer might get invalid when the vector is resized by either a manual 402 * call to the memory-management functions or implicitly by inserting or removing elements. 403 * 404 * @return A zyan status code. 405 */ 406 ZYCORE_EXPORT ZyanStatus ZyanVectorGetPointer(const ZyanVector* vector, ZyanUSize index, 407 const void** value); 408 409 /** 410 * Returns a mutable pointer to the element at the given `index`. 411 * 412 * @param vector A pointer to the `ZyanVector` instance. 413 * @param index The element index. 414 * @param value Receives a mutable pointer to the desired element in the vector. 415 * 416 * Note that the returned pointer might get invalid when the vector is resized by either a manual 417 * call to the memory-management functions or implicitly by inserting or removing elements. 418 * 419 * @return A zyan status code. 420 */ 421 ZYCORE_EXPORT ZyanStatus ZyanVectorGetPointerMutable(const ZyanVector* vector, ZyanUSize index, 422 void** value); 423 424 /** 425 * Assigns a new value to the element at the given `index`. 426 * 427 * @param vector A pointer to the `ZyanVector` instance. 428 * @param index The value index. 429 * @param value The value to assign. 430 * 431 * @return A zyan status code. 432 */ 433 ZYCORE_EXPORT ZyanStatus ZyanVectorSet(ZyanVector* vector, ZyanUSize index, 434 const void* value); 435 436 /* ---------------------------------------------------------------------------------------------- */ 437 /* Insertion */ 438 /* ---------------------------------------------------------------------------------------------- */ 439 440 /** 441 * Adds a new `element` to the end of the vector. 442 * 443 * @param vector A pointer to the `ZyanVector` instance. 444 * @param element A pointer to the element to add. 445 * 446 * @return A zyan status code. 447 */ 448 ZYCORE_EXPORT ZyanStatus ZyanVectorPushBack(ZyanVector* vector, const void* element); 449 450 /** 451 * Inserts an `element` at the given `index` of the vector. 452 * 453 * @param vector A pointer to the `ZyanVector` instance. 454 * @param index The insert index. 455 * @param element A pointer to the element to insert. 456 * 457 * @return A zyan status code. 458 */ 459 ZYCORE_EXPORT ZyanStatus ZyanVectorInsert(ZyanVector* vector, ZyanUSize index, 460 const void* element); 461 462 /** 463 * Inserts multiple `elements` at the given `index` of the vector. 464 * 465 * @param vector A pointer to the `ZyanVector` instance. 466 * @param index The insert index. 467 * @param elements A pointer to the first element. 468 * @param count The number of elements to insert. 469 * 470 * @return A zyan status code. 471 */ 472 ZYCORE_EXPORT ZyanStatus ZyanVectorInsertRange(ZyanVector* vector, ZyanUSize index, 473 const void* elements, ZyanUSize count); 474 475 /** 476 * Constructs an `element` in-place at the end of the vector. 477 * 478 * @param vector A pointer to the `ZyanVector` instance. 479 * @param element Receives a pointer to the new element. 480 * @param constructor The constructor callback or `ZYAN_NULL`. The new element will be in 481 * undefined state, if no constructor was passed. 482 * 483 * @return A zyan status code. 484 */ 485 ZYCORE_EXPORT ZyanStatus ZyanVectorEmplace(ZyanVector* vector, void** element, 486 ZyanMemberFunction constructor); 487 488 /** 489 * Constructs an `element` in-place and inserts it at the given `index` of the vector. 490 * 491 * @param vector A pointer to the `ZyanVector` instance. 492 * @param index The insert index. 493 * @param element Receives a pointer to the new element. 494 * @param constructor The constructor callback or `ZYAN_NULL`. The new element will be in 495 * undefined state, if no constructor was passed. 496 * 497 * @return A zyan status code. 498 */ 499 ZYCORE_EXPORT ZyanStatus ZyanVectorEmplaceEx(ZyanVector* vector, ZyanUSize index, 500 void** element, ZyanMemberFunction constructor); 501 502 /* ---------------------------------------------------------------------------------------------- */ 503 /* Utils */ 504 /* ---------------------------------------------------------------------------------------------- */ 505 506 /** 507 * Swaps the element at `index_first` with the element at `index_second`. 508 * 509 * @param vector A pointer to the `ZyanVector` instance. 510 * @param index_first The index of the first element. 511 * @param index_second The index of the second element. 512 * 513 * @return A zyan status code. 514 * 515 * This function requires the vector to have spare capacity for one temporary element. Call 516 * `ZyanVectorReserve` before this function to increase capacity, if needed. 517 */ 518 ZYCORE_EXPORT ZyanStatus ZyanVectorSwapElements(ZyanVector* vector, ZyanUSize index_first, 519 ZyanUSize index_second); 520 521 /* ---------------------------------------------------------------------------------------------- */ 522 /* Deletion */ 523 /* ---------------------------------------------------------------------------------------------- */ 524 525 /** 526 * Deletes the element at the given `index` of the vector. 527 * 528 * @param vector A pointer to the `ZyanVector` instance. 529 * @param index The element index. 530 * 531 * @return A zyan status code. 532 */ 533 ZYCORE_EXPORT ZyanStatus ZyanVectorDelete(ZyanVector* vector, ZyanUSize index); 534 535 /** 536 * Deletes multiple elements from the given vector, starting at `index`. 537 * 538 * @param vector A pointer to the `ZyanVector` instance. 539 * @param index The index of the first element to delete. 540 * @param count The number of elements to delete. 541 * 542 * @return A zyan status code. 543 */ 544 ZYCORE_EXPORT ZyanStatus ZyanVectorDeleteRange(ZyanVector* vector, ZyanUSize index, 545 ZyanUSize count); 546 547 /** 548 * Removes the last element of the vector. 549 * 550 * @param vector A pointer to the `ZyanVector` instance. 551 * 552 * @return A zyan status code. 553 */ 554 ZYCORE_EXPORT ZyanStatus ZyanVectorPopBack(ZyanVector* vector); 555 556 /** 557 * Erases all elements of the given vector. 558 * 559 * @param vector A pointer to the `ZyanVector` instance. 560 * 561 * @return A zyan status code. 562 */ 563 ZYCORE_EXPORT ZyanStatus ZyanVectorClear(ZyanVector* vector); 564 565 /* ---------------------------------------------------------------------------------------------- */ 566 /* Searching */ 567 /* ---------------------------------------------------------------------------------------------- */ 568 569 /** 570 * Sequentially searches for the first occurrence of `element` in the given vector. 571 * 572 * @param vector A pointer to the `ZyanVector` instance. 573 * @param element A pointer to the element to search for. 574 * @param found_index A pointer to a variable that receives the index of the found element. 575 * @param comparison The comparison function to use. 576 * 577 * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic 578 * zyan status code if an error occurred. 579 * 580 * The `found_index` is set to `-1`, if the element was not found. 581 */ 582 ZYCORE_EXPORT ZyanStatus ZyanVectorFind(const ZyanVector* vector, const void* element, 583 ZyanISize* found_index, ZyanEqualityComparison comparison); 584 585 /** 586 * Sequentially searches for the first occurrence of `element` in the given vector. 587 * 588 * @param vector A pointer to the `ZyanVector` instance. 589 * @param element A pointer to the element to search for. 590 * @param found_index A pointer to a variable that receives the index of the found element. 591 * @param comparison The comparison function to use. 592 * @param index The start index. 593 * @param count The maximum number of elements to iterate, beginning from the start `index`. 594 * 595 * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic 596 * zyan status code if an error occurred. 597 * 598 * The `found_index` is set to `-1`, if the element was not found. 599 */ 600 ZYCORE_EXPORT ZyanStatus ZyanVectorFindEx(const ZyanVector* vector, const void* element, 601 ZyanISize* found_index, ZyanEqualityComparison comparison, ZyanUSize index, ZyanUSize count); 602 603 /** 604 * Searches for the first occurrence of `element` in the given vector using a binary- 605 * search algorithm. 606 * 607 * @param vector A pointer to the `ZyanVector` instance. 608 * @param element A pointer to the element to search for. 609 * @param found_index A pointer to a variable that receives the index of the found element. 610 * @param comparison The comparison function to use. 611 * 612 * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic 613 * zyan status code if an error occurred. 614 * 615 * If found, `found_index` contains the zero-based index of `element`. If not found, `found_index` 616 * contains the index of the first entry larger than `element`. 617 * 618 * This function requires all elements in the vector to be strictly ordered (sorted). 619 */ 620 ZYCORE_EXPORT ZyanStatus ZyanVectorBinarySearch(const ZyanVector* vector, const void* element, 621 ZyanUSize* found_index, ZyanComparison comparison); 622 623 /** 624 * Searches for the first occurrence of `element` in the given vector using a binary- 625 * search algorithm. 626 * 627 * @param vector A pointer to the `ZyanVector` instance. 628 * @param element A pointer to the element to search for. 629 * @param found_index A pointer to a variable that receives the index of the found element. 630 * @param comparison The comparison function to use. 631 * @param index The start index. 632 * @param count The maximum number of elements to iterate, beginning from the start `index`. 633 * 634 * @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic 635 * zyan status code if an error occurred. 636 * 637 * If found, `found_index` contains the zero-based index of `element`. If not found, `found_index` 638 * contains the index of the first entry larger than `element`. 639 * 640 * This function requires all elements in the vector to be strictly ordered (sorted). 641 */ 642 ZYCORE_EXPORT ZyanStatus ZyanVectorBinarySearchEx(const ZyanVector* vector, const void* element, 643 ZyanUSize* found_index, ZyanComparison comparison, ZyanUSize index, ZyanUSize count); 644 645 /* ---------------------------------------------------------------------------------------------- */ 646 /* Memory management */ 647 /* ---------------------------------------------------------------------------------------------- */ 648 649 /** 650 * Resizes the given `ZyanVector` instance. 651 * 652 * @param vector A pointer to the `ZyanVector` instance. 653 * @param size The new size of the vector. 654 * 655 * @return A zyan status code. 656 */ 657 ZYCORE_EXPORT ZyanStatus ZyanVectorResize(ZyanVector* vector, ZyanUSize size); 658 659 /** 660 * Resizes the given `ZyanVector` instance. 661 * 662 * @param vector A pointer to the `ZyanVector` instance. 663 * @param size The new size of the vector. 664 * @param initializer A pointer to a value to be used as initializer for new items. 665 * 666 * @return A zyan status code. 667 */ 668 ZYCORE_EXPORT ZyanStatus ZyanVectorResizeEx(ZyanVector* vector, ZyanUSize size, 669 const void* initializer); 670 671 /** 672 * Changes the capacity of the given `ZyanVector` instance. 673 * 674 * @param vector A pointer to the `ZyanVector` instance. 675 * @param capacity The new minimum capacity of the vector. 676 * 677 * @return A zyan status code. 678 */ 679 ZYCORE_EXPORT ZyanStatus ZyanVectorReserve(ZyanVector* vector, ZyanUSize capacity); 680 681 /** 682 * Shrinks the capacity of the given vector to match it's size. 683 * 684 * @param vector A pointer to the `ZyanVector` instance. 685 * 686 * @return A zyan status code. 687 */ 688 ZYCORE_EXPORT ZyanStatus ZyanVectorShrinkToFit(ZyanVector* vector); 689 690 /* ---------------------------------------------------------------------------------------------- */ 691 /* Information */ 692 /* ---------------------------------------------------------------------------------------------- */ 693 694 /** 695 * Returns the current capacity of the vector. 696 * 697 * @param vector A pointer to the `ZyanVector` instance. 698 * @param capacity Receives the size of the vector. 699 * 700 * @return A zyan status code. 701 */ 702 ZYCORE_EXPORT ZyanStatus ZyanVectorGetCapacity(const ZyanVector* vector, ZyanUSize* capacity); 703 704 /** 705 * Returns the current size of the vector. 706 * 707 * @param vector A pointer to the `ZyanVector` instance. 708 * @param size Receives the size of the vector. 709 * 710 * @return A zyan status code. 711 */ 712 ZYCORE_EXPORT ZyanStatus ZyanVectorGetSize(const ZyanVector* vector, ZyanUSize* size); 713 714 /* ---------------------------------------------------------------------------------------------- */ 715 716 /* ============================================================================================== */ 717 718 #ifdef __cplusplus 719 } 720 #endif 721 722 #endif /* ZYCORE_VECTOR_H */ 723