xref: /haiku/headers/libs/zydis/Zycore/Vector.h (revision caed67a8cba83913b9c21ac2b06ebc6bd1cb3111)
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