dvec.h (3096B)
1#pragma once 2 3#include "allocator.h" 4 5#include <sys/types.h> 6#include <stdbool.h> 7#include <stddef.h> 8 9#define DVEC_ITER(dvec, p) (p) = NULL; ((p) = dvec_iter_fwd((dvec), (p))); 10#define DVEC_ITER_BWD(dvec, p) (p) = NULL; ((p) = dvec_iter_bwd((dvec), (p))); 11 12#define DVEC_STRERR_INIT \ 13 [DVEC_OK] = "Success" 14 15#ifdef LIBDVEC_ASSERT_ARGS 16#include "stdlib.h" 17#define LIBDVEC_ABORT_ON_ARGS(cond) do { if (cond) abort(); } while (0) 18#else 19#define LIBDVEC_ABORT_ON_ARGS(cond) 20#endif 21 22#ifdef LIBDVEC_ASSERT_ALLOC 23#include "stdlib.h" 24#define LIBDVEC_ABORT_ON_ALLOC(cond) do { if (cond) abort(); } while (0) 25#else 26#define LIBDVEC_ABORT_ON_ALLOC(cond) 27#endif 28 29enum { 30 DVEC_OK = 0, 31}; 32 33struct dvec { 34 size_t dsize; 35 size_t len, cap; 36 37 void *data; 38 39 const struct allocator *allocator; 40}; 41 42typedef bool (*dvec_sort_order_fn)(const void *p1, const void *p2, void *u); 43typedef int (*dvec_search_cmp_fn)(const void *cur, void *user); 44 45int dvec_init(struct dvec *dvec, size_t dsize, size_t cap, 46 const struct allocator *allocator); 47int dvec_deinit(struct dvec *dvec); 48 49struct dvec *dvec_alloc(size_t dsize, size_t cap, 50 const struct allocator *allocator, int *rc); 51int dvec_free(struct dvec *dvec); 52 53int dvec_copy(struct dvec *dst, struct dvec *src); 54void dvec_move(struct dvec *dst, struct dvec *src); 55void dvec_swap(struct dvec *dst, struct dvec *src); 56 57void dvec_clear(struct dvec *dvec); 58int dvec_reserve(struct dvec *dvec, size_t cap); 59int dvec_shrink(struct dvec *dvec); 60 61int dvec_add(struct dvec *dvec, size_t index, size_t count); 62void dvec_rm(struct dvec *dvec, size_t index, size_t count); 63void dvec_replace(struct dvec *dvec, size_t index, 64 const void *data, size_t count); 65 66void *dvec_iter_fwd(const struct dvec *dvec, const void *p); 67void *dvec_iter_bwd(const struct dvec *dvec, const void *p); 68 69int dvec_bubble_sort(struct dvec *dvec, 70 bool reverse, dvec_sort_order_fn in_order, void *user); 71 72ssize_t dvec_binary_search(struct dvec *dvec, dvec_search_cmp_fn search_cmp, 73 void *user, ssize_t *lower, ssize_t *higher); 74 75static inline void * 76dvec_at(const struct dvec *dvec, size_t index) 77{ 78 LIBDVEC_ABORT_ON_ARGS(!dvec || index >= dvec->len); 79 80 return dvec->data + index * dvec->dsize; 81} 82 83static inline void * 84dvec_at_back(const struct dvec *dvec, size_t index) 85{ 86 LIBDVEC_ABORT_ON_ARGS(!dvec || !index || index >= dvec->len); 87 88 return dvec->data + (dvec->len - 1 - index) * dvec->dsize; 89} 90 91static inline void * 92dvec_front(const struct dvec *dvec) 93{ 94 LIBDVEC_ABORT_ON_ARGS(!dvec); 95 96 return dvec->data; 97} 98 99static inline void * 100dvec_back(const struct dvec *dvec) 101{ 102 LIBDVEC_ABORT_ON_ARGS(!dvec); 103 104 return dvec->data + (dvec->len - 1) * dvec->dsize; 105} 106 107static inline bool 108dvec_empty(const struct dvec *dvec) 109{ 110 LIBDVEC_ABORT_ON_ARGS(!dvec); 111 112 return !dvec->len; 113} 114 115static inline size_t 116dvec_len(const struct dvec *dvec) 117{ 118 LIBDVEC_ABORT_ON_ARGS(!dvec); 119 120 return dvec->len; 121} 122 123static inline int 124dvec_add_back(struct dvec *dvec, size_t count) 125{ 126 return dvec_add(dvec, dvec->len, count); 127} 128 129static inline void 130dvec_rm_back(struct dvec *dvec, size_t count) 131{ 132 dvec_rm(dvec, dvec->len - count, count); 133}