summaryrefslogtreecommitdiffstats
path: root/darray.h
blob: e2d0e108903970744910c3cb8f569ef5832aff48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/****************************************************************************
 * bfs                                                                      *
 * Copyright (C) 2019-2022 Tavian Barnes <tavianator@tavianator.com>        *
 *                                                                          *
 * Permission to use, copy, modify, and/or distribute this software for any *
 * purpose with or without fee is hereby granted.                           *
 *                                                                          *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
 ****************************************************************************/

/**
 * A dynamic array library.
 *
 * darrays are represented by a simple pointer to the array element type, like
 * any other array.  Behind the scenes, the capacity and current length of the
 * array are stored along with it.  NULL is a valid way to initialize an empty
 * darray:
 *
 *     int *darray = NULL;
 *
 * To append an element to a darray, use the DARRAY_PUSH macro:
 *
 *     int e = 42;
 *     if (DARRAY_PUSH(&darray, &e) != 0) {
 *             // Report the error...
 *     }
 *
 * The length can be retrieved by darray_length().  Iterating over the array
 * works like normal arrays:
 *
 *     for (size_t i = 0; i < darray_length(darray); ++i) {
 *             printf("%d\n", darray[i]);
 *     }
 *
 * To free a darray, use darray_free():
 *
 *     darray_free(darray);
 */

#ifndef BFS_DARRAY_H
#define BFS_DARRAY_H

#include <stddef.h>

/**
 * Get the length of a darray.
 *
 * @param da
 *         The array in question.
 * @return
 *         The length of the array.
 */
size_t darray_length(const void *da);

/**
 * @internal Use DARRAY_PUSH().
 *
 * Push an element into a darray.
 *
 * @param da
 *         The array to append to.
 * @param item
 *         The item to append.
 * @param size
 *         The size of the item.
 * @return
 *         The (new) location of the array.
 */
void *darray_push(void *da, const void *item, size_t size);

/**
 * @internal Use DARRAY_PUSH().
 *
 * Check if the last darray_push() call failed.
 *
 * @param da
 *         The darray to check.
 * @return
 *         0 on success, -1 on failure.
 */
int darray_check(void *da);

/**
 * @internal Use DARRAY_POP().
 *
 * Pop an element from an array.
 *
 * @param da
 *         The array in question.
 * @return
 *         The (new) length of the array.
 */
size_t darray_pop(void *da);

/**
 * Free a darray.
 *
 * @param da
 *         The darray to free.
 */
void darray_free(void *da);

/**
 * Push an item into a darray.
 *
 * @param da
 *         The array to append to.
 * @param item
 *         A pointer to the item to append.
 * @return
 *         0 on success, -1 on failure.
 */
#define DARRAY_PUSH(da, item) \
	(darray_check(*(da) = darray_push(*(da), (item), sizeof(**(da) = *(item)))))

/**
 * Pop an item from a darray.
 *
 * @param da
 *         The array to pop from.
 * @return
 *         The popped item.
 */
#define DARRAY_POP(da) \
	((da)[darray_pop((da))])

#endif // BFS_DARRAY_H