libcstl
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1/*!
2 * @file
3 */
4
5#ifndef CSTL_VECTOR_H
6#define CSTL_VECTOR_H
7
8/*!
9 * @defgroup vector Vector
10 * @ingroup highlevel
11 * @brief Variable-sized array
12 */
13/*!
14 * @addtogroup vector
15 * @{
16 */
17
18#include "cstl/common.h"
19
20#include <sys/types.h>
21
22/*!
23 * @brief Vector object
24 *
25 * Callers declare or allocate an object of this type to instantiate
26 * a vector. Users are encouraged to declare (and initialize) this
27 * object with the DECLARE_CSTL_VECTOR() macro. Any other declaration or
28 * allocation must be initialized via cstl_vector_init().
29 */
30typedef struct cstl_vector
31{
32 /*! @privatesection */
33 struct
34 {
35 /*! @privatesection */
36 void * base;
37 size_t size;
38
39 struct
40 {
41 /*! @privatesection */
42 cstl_xtor_func_t * cons, * dest;
43 void * priv;
44 } xtor;
45 } elem;
46 size_t count, cap;
48
49/*!
50 * @brief Constant initialization of a vector object
51 *
52 * @param TYPE The type of object that the vector will hold
53 */
54#define CSTL_VECTOR_INITIALIZER(TYPE) \
55 { \
56 .elem = { \
57 .base = NULL, \
58 .size = sizeof(TYPE), \
59 .xtor = { \
60 .cons = NULL, \
61 .dest = NULL, \
62 .priv = NULL, \
63 }, \
64 }, \
65 .count = 0, \
66 .cap = 0, \
67 }
68/*!
69 * @brief (Statically) declare and initialize a vector
70 *
71 * @param NAME The name of the variable being declared
72 * @param TYPE The type of object that the vector will hold
73 */
74#define DECLARE_CSTL_VECTOR(NAME, TYPE) \
75 struct cstl_vector NAME = CSTL_VECTOR_INITIALIZER(TYPE)
76
77/*!
78 * @brief Initialize a vector object
79 *
80 * This function is used when construction and/or destruction of
81 * objects in the vector, as they go in and out of scope, is
82 * necessary. Any or all of the construction/destruction parameters
83 * may be NULL.
84 *
85 * Construction and/or destruction takes place (only) during a resize
86 * of the vector and only affects elements coming into or going out
87 * of scope, where in-scope refers to elements at locations less than
88 * the "count" of the number of elements in the vector. In other words,
89 * elements that exist between the size of the vector and the capacity
90 * of the vector are considered uninitialized, either because they have
91 * not yet been "constructed" or because they were "destroyed".
92 *
93 * @param[in,out] v A pointer to the vector object
94 * @param[in] sz The size of the type of object that will be
95 * stored in the vector
96 * @param[in] cons A pointer to a function to call for each element as
97 * it comes into scope
98 * @param[in] dest A pointer to a function to call for each element as
99 * it goes out of scope
100 * @param[in] priv A pointer to be passed to each call to @p cons or @p dest
101 */
102static inline void cstl_vector_init_complex(
103 struct cstl_vector * const v, const size_t sz,
104 cstl_xtor_func_t * const cons, cstl_xtor_func_t * const dest,
105 void * const priv)
106{
107 v->elem.base = NULL;
108 v->elem.size = sz;
109
110 v->elem.xtor.cons = cons;
111 v->elem.xtor.dest = dest;
112 v->elem.xtor.priv = priv;
113
114 v->count = 0;
115 v->cap = 0;
116}
117
118/*!
119 * @brief Initialize a vector object
120 *
121 * @param[in,out] v A pointer to the vector object
122 * @param[in] sz The size of the type of object that will be
123 * stored in the vector
124 */
125static inline void cstl_vector_init(
126 struct cstl_vector * const v, const size_t sz)
127{
128 cstl_vector_init_complex(v, sz, NULL, NULL, NULL);
129}
130
131/*!
132 * @brief Get the number of elements in the vector
133 *
134 * @param[in] v A pointer to the vector object
135 *
136 * @return The number of elements in the vector
137 */
138static inline size_t cstl_vector_size(const struct cstl_vector * const v)
139{
140 return v->count;
141}
142
143/*!
144 * @brief Get the number of elements the vector can hold
145 *
146 * The capacity of the vector can be changed, but the current capacity
147 * indicates the number of elements that the vector can hold without
148 * a memory reallocation
149 *
150 * @param[in] v A pointer to the vector object
151 *
152 * @return The number of elements the vector can hold
153 */
154static inline size_t cstl_vector_capacity(const struct cstl_vector * const v)
155{
156 return v->cap;
157}
158
159/*!
160 * @brief Get a pointer to the start of the vector data
161 *
162 * @param[in] v A pointer to the vector object
163 *
164 * @return A pointer to the start of the vector data
165 */
166static inline void * cstl_vector_data(struct cstl_vector * const v)
167{
168 return v->elem.base;
169}
170
171/*!
172 * @brief Get a pointer to an element in the vector
173 *
174 * @param[in] v A pointer to the vector
175 * @param[in] i The 0-based index of the desired element in the vector
176 *
177 * @return A pointer to the element indicated by the index
178 *
179 * @note The code will cause an abort if the index is outside the range
180 * of valid elements it the vector
181 */
182void * cstl_vector_at(struct cstl_vector * v, size_t i);
183/*!
184 * @brief Get a const pointer to an element from a const vector
185 *
186 * @param[in] v A pointer to the vector
187 * @param[in] i The 0-based index of the desired element in the vector
188 *
189 * @return A pointer to the element indicated by the index
190 *
191 * @note The code will cause an abort if the index is outside the range
192 * of valid elements it the vector
193 */
194const void * cstl_vector_at_const(const struct cstl_vector * v, size_t i);
195
196/*!
197 * @brief Request to increase the capacity of the vector
198 *
199 * @param[in] v A pointer to the vector object
200 * @param[in] sz The number of elements the vector should be able to hold
201 *
202 * Requests to decrease the capacity are ignored. Requests to increase
203 * the capacity that fail do so quietly
204 */
205void cstl_vector_reserve(struct cstl_vector * v, size_t sz);
206/*!
207 * @brief Request to decrease the capacity of the vector
208 *
209 * @param[in] v A pointer to the vector object
210 *
211 * The function attempts to decrease the capacity of the vector
212 * to only that required to hold the current number of valid elements.
213 * The function may fail and will do so without error.
214 */
216
217/*!
218 * @brief Change the number of valid elements in the vector
219 *
220 * @param[in] v A pointer to the vector
221 * @param[in] sz The number of elements desired in the vector
222 *
223 * The function attempts to set the number of valid elements to the
224 * number indicated. If the number is less than or equal to the
225 * current capacity of the vector, the function always succeeds. If
226 * the number exceeds the capacity, and the function cannot increase
227 * the capacity, the function will cause an abort.
228 */
229void cstl_vector_resize(struct cstl_vector * v, size_t sz);
230
231/*!
232 * @brief Sort the elements in the vector
233 *
234 * @param[in] v A pointer to the vector
235 * @param[in] cmp A pointer to a function to use to compare elements
236 * @param[in] priv A pointer to be passed to each invocation
237 * of the comparison function
238 * @param[in] swap A function to be used to swap elements within the vector.
239 * @param[in] algo The algorithm to use for the sort
240 */
241void __cstl_vector_sort(struct cstl_vector * v,
242 cstl_compare_func_t * cmp, void * priv,
243 cstl_swap_func_t * swap,
245
246/*!
247 * @brief Sort the elements in the vector
248 *
249 * @param[in] v A pointer to the vector
250 * @param[in] cmp A pointer to a function to use to compare elements
251 * @param[in] priv A pointer to be passed to each invocation
252 * of the comparison function
253 *
254 * @note Elements within the vector will be rearranged via a "simple copy".
255 */
256static inline void cstl_vector_sort(
257 struct cstl_vector * const v,
258 cstl_compare_func_t * const cmp, void * const priv)
259{
261}
262
263/*!
264 * @brief Perform a binary search of the vector
265 *
266 * @param[in] v A pointer to a vector
267 * @param[in] e A pointer to an object having the same value as the sought
268 * object according to the provided comparison function
269 * @param[in] cmp A pointer to a function use to compare objects
270 * @param[in] priv A pointer to be passed to each invocation of the
271 * comparison function
272 *
273 * The behavior is undefined if the vector is not sorted.
274 *
275 * @return The index of the sought element
276 * @retval -1 if the sought value is not found
277 */
278ssize_t cstl_vector_search(const struct cstl_vector * v,
279 const void * e,
280 cstl_compare_func_t * cmp, void * priv);
281
282/*!
283 * @brief Perform a linear search of the vector
284 *
285 * @param[in] v A pointer to a vector
286 * @param[in] e A pointer to an object having the same value as the sought
287 * object according to the provided comparison function
288 * @param[in] cmp A pointer to a function use to compare objects
289 * @param[in] priv A pointer to be passed to each invocation of the
290 * comparison function
291 *
292 * @return The index of the sought element
293 * @retval -1 if the sought value is not found
294 */
295ssize_t cstl_vector_find(const struct cstl_vector * v,
296 const void * e,
297 cstl_compare_func_t * cmp, void * priv);
298
299/*!
300 * @brief Reverse the current order of the elements
301 *
302 * @param[in] v A pointer to the vector
303 * @param[in] swap A function to be used to swap elements within the vector.
304 */
305void __cstl_vector_reverse(struct cstl_vector * v, cstl_swap_func_t * swap);
306
307/*!
308 * @brief Reverse the current order of the elements
309 *
310 * @param[in] v A pointer to the vector
311 *
312 * @note Elements within the vector will be rearranged via a "simple copy".
313 */
314static inline void cstl_vector_reverse(struct cstl_vector * const v)
315{
317}
318
319/*!
320 * @brief Swap the vector objects at the two given locations
321 *
322 * @param[in,out] a A pointer to a vector
323 * @param[in,out] b A pointer to a(nother) vector
324 *
325 * The vectors at the given locations will be swapped such that upon return,
326 * @p a will contain the vector previously pointed to by @p b and vice versa.
327 */
328void cstl_vector_swap(struct cstl_vector * a, struct cstl_vector * b);
329
330/*!
331 * @brief Return a vector to its initialized state
332 *
333 * @param[in] v A pointer to a vector
334 */
335void cstl_vector_clear(struct cstl_vector * v);
336
337/*!
338 * @}
339 */
340
341#endif
cstl_sort_algorithm_t
Enumeration indicating the desired sort algorithm.
Definition common.h:24
@ CSTL_SORT_ALGORITHM_DEFAULT
Unspecified default algorithm.
Definition common.h:35
static void cstl_swap(void *const x, void *const y, void *const t, const size_t sz)
Swap values at two memory locations via use of a third.
Definition common.h:137
void cstl_xtor_func_t(void *obj, void *priv)
Type for functions called to construct, clear, or destroy an object.
Definition common.h:97
void cstl_swap_func_t(void *a, void *b, void *t, size_t len)
Type of function called to swap two objects.
Definition common.h:118
int cstl_compare_func_t(const void *obj1, const void *obj2, void *priv)
Function type for comparing (in)equality of two objects.
Definition common.h:49
void cstl_vector_resize(struct cstl_vector *v, size_t sz)
Change the number of valid elements in the vector.
Definition vector.c:73
void cstl_vector_reserve(struct cstl_vector *v, size_t sz)
Request to increase the capacity of the vector.
Definition vector.c:59
void * cstl_vector_at(struct cstl_vector *v, size_t i)
Get a pointer to an element in the vector.
Definition vector.c:28
struct cstl_vector cstl_vector_t
Vector object.
static size_t cstl_vector_size(const struct cstl_vector *const v)
Get the number of elements in the vector.
Definition vector.h:138
static void cstl_vector_init_complex(struct cstl_vector *const v, const size_t sz, cstl_xtor_func_t *const cons, cstl_xtor_func_t *const dest, void *const priv)
Initialize a vector object.
Definition vector.h:102
static size_t cstl_vector_capacity(const struct cstl_vector *const v)
Get the number of elements the vector can hold.
Definition vector.h:154
void cstl_vector_swap(struct cstl_vector *a, struct cstl_vector *b)
Swap the vector objects at the two given locations.
Definition vector.c:158
static void * cstl_vector_data(struct cstl_vector *const v)
Get a pointer to the start of the vector data.
Definition vector.h:166
static void cstl_vector_init(struct cstl_vector *const v, const size_t sz)
Initialize a vector object.
Definition vector.h:125
void cstl_vector_shrink_to_fit(struct cstl_vector *v)
Request to decrease the capacity of the vector.
Definition vector.c:66
static void cstl_vector_sort(struct cstl_vector *const v, cstl_compare_func_t *const cmp, void *const priv)
Sort the elements in the vector.
Definition vector.h:256
ssize_t cstl_vector_search(const struct cstl_vector *v, const void *e, cstl_compare_func_t *cmp, void *priv)
Perform a binary search of the vector.
Definition vector.c:128
const void * cstl_vector_at_const(const struct cstl_vector *v, size_t i)
Get a const pointer to an element from a const vector.
Definition vector.c:18
void cstl_vector_clear(struct cstl_vector *v)
Return a vector to its initialized state.
Definition vector.c:107
static void cstl_vector_reverse(struct cstl_vector *const v)
Reverse the current order of the elements.
Definition vector.h:314
ssize_t cstl_vector_find(const struct cstl_vector *v, const void *e, cstl_compare_func_t *cmp, void *priv)
Perform a linear search of the vector.
Definition vector.c:139
void __cstl_vector_reverse(struct cstl_vector *v, cstl_swap_func_t *swap)
Reverse the current order of the elements.
Definition vector.c:150
void __cstl_vector_sort(struct cstl_vector *v, cstl_compare_func_t *cmp, void *priv, cstl_swap_func_t *swap, cstl_sort_algorithm_t algo)
Sort the elements in the vector.
Definition vector.c:116
Vector object.
Definition vector.h:31