1 /**************************************************************************** 2 * bfs * 3 * Copyright (C) 2019-2022 Tavian Barnes <tavianator@tavianator.com> * 4 * * 5 * Permission to use, copy, modify, and/or distribute this software for any * 6 * purpose with or without fee is hereby granted. * 7 * * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * 15 ****************************************************************************/ 16 17 /** 18 * A dynamic array library. 19 * 20 * darrays are represented by a simple pointer to the array element type, like 21 * any other array. Behind the scenes, the capacity and current length of the 22 * array are stored along with it. NULL is a valid way to initialize an empty 23 * darray: 24 * 25 * int *darray = NULL; 26 * 27 * To append an element to a darray, use the DARRAY_PUSH macro: 28 * 29 * int e = 42; 30 * if (DARRAY_PUSH(&darray, &e) != 0) { 31 * // Report the error... 32 * } 33 * 34 * The length can be retrieved by darray_length(). Iterating over the array 35 * works like normal arrays: 36 * 37 * for (size_t i = 0; i < darray_length(darray); ++i) { 38 * printf("%d\n", darray[i]); 39 * } 40 * 41 * To free a darray, use darray_free(): 42 * 43 * darray_free(darray); 44 */ 45 46 #ifndef BFS_DARRAY_H 47 #define BFS_DARRAY_H 48 49 #include <stddef.h> 50 51 /** 52 * Get the length of a darray. 53 * 54 * @param da 55 * The array in question. 56 * @return 57 * The length of the array. 58 */ 59 size_t darray_length(const void *da); 60 61 /** 62 * @internal Use DARRAY_PUSH(). 63 * 64 * Push an element into a darray. 65 * 66 * @param da 67 * The array to append to. 68 * @param item 69 * The item to append. 70 * @param size 71 * The size of the item. 72 * @return 73 * The (new) location of the array. 74 */ 75 void *darray_push(void *da, const void *item, size_t size); 76 77 /** 78 * @internal Use DARRAY_PUSH(). 79 * 80 * Check if the last darray_push() call failed. 81 * 82 * @param da 83 * The darray to check. 84 * @return 85 * 0 on success, -1 on failure. 86 */ 87 int darray_check(void *da); 88 89 /** 90 * @internal Use DARRAY_POP(). 91 * 92 * Pop an element from an array. 93 * 94 * @param da 95 * The array in question. 96 * @return 97 * The (new) length of the array. 98 */ 99 size_t darray_pop(void *da); 100 101 /** 102 * Free a darray. 103 * 104 * @param da 105 * The darray to free. 106 */ 107 void darray_free(void *da); 108 109 /** 110 * Push an item into a darray. 111 * 112 * @param da 113 * The array to append to. 114 * @param item 115 * A pointer to the item to append. 116 * @return 117 * 0 on success, -1 on failure. 118 */ 119 #define DARRAY_PUSH(da, item) \ 120 (darray_check(*(da) = darray_push(*(da), (item), sizeof(**(da) = *(item))))) 121 122 /** 123 * Pop an item from a darray. 124 * 125 * @param da 126 * The array to pop from. 127 * @return 128 * The popped item. 129 */ 130 #define DARRAY_POP(da) \ 131 ((da)[darray_pop((da))]) 132 133 #endif // BFS_DARRAY_H 134