mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-05 12:57:34 +00:00
108 lines
2.9 KiB
C
108 lines
2.9 KiB
C
#ifndef R2_VECTOR_H
|
|
#define R2_VECTOR_H
|
|
|
|
#include <r_types.h>
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
Insert functions returns NULL if reallocation happens and fails,
|
|
returns the address of newly inserted element if succeeded.
|
|
|
|
Delete functions returns the deleted element.
|
|
Callers should destruct it if necessary.
|
|
|
|
Usage:
|
|
int i;
|
|
void **it;
|
|
|
|
// heap allocated RVector
|
|
RVector *v = r_vector_new ();
|
|
if (!v) goto err_new;
|
|
if (!r_vector_push (v, a)) goto err_push;
|
|
if (!r_vector_insert (v, 0, b)) goto err_insert;
|
|
for (i = 0; i < v->len; i++) {
|
|
(void)v->a[i]; // Public members a and len are encouraged to access
|
|
}
|
|
r_vector_foreach (v, it) {
|
|
(void)*it;
|
|
}
|
|
// pass function pointer `elem_free`
|
|
r_vector_free (v, NULL);
|
|
|
|
// stack allocated RVector
|
|
RVector v = {0};
|
|
// r_vector_init (&v); // v.a = NULL; v.len = v.capacity = 0;
|
|
r_vector_push (&v, (void *)1);
|
|
assert (v.len == 1 && v.capacity == 10);
|
|
// for stack allocated RVector, use r_vector_clear instead of r_vector_free
|
|
r_vector_clear (&v, NULL);
|
|
*/
|
|
|
|
typedef struct r_vector_t {
|
|
void **a;
|
|
int len;
|
|
int capacity;
|
|
} RVector;
|
|
|
|
typedef int (*RVectorComparator)(const void *a, const void *b);
|
|
|
|
R_API void r_vector_clear(RVector *vec, void (*elem_free)(void *));
|
|
R_API RVector *r_vector_clone(RVector *vec);
|
|
R_API void **r_vector_contains(RVector *vec, void *x);
|
|
R_API void *r_vector_delete_at(RVector *vec, int n);
|
|
R_API bool r_vector_empty(RVector *vec);
|
|
R_API void r_vector_fini(RVector *vec);
|
|
R_API void r_vector_free(RVector *vec, void (*elem_free)(void *));
|
|
R_API void r_vector_init(RVector *vec);
|
|
R_API void **r_vector_insert(RVector *vec, int n, void *x);
|
|
R_API void **r_vector_insert_range(RVector *vec, int n, void **first, void **last);
|
|
R_API RVector *r_vector_new(void);
|
|
R_API void *r_vector_pop(RVector *vec);
|
|
R_API void *r_vector_pop_front(RVector *vec);
|
|
R_API void **r_vector_push(RVector *vec, void *x);
|
|
R_API void **r_vector_push_front(RVector *vec, void *x);
|
|
R_API void **r_vector_reserve(RVector *vec, int capacity);
|
|
/* shrink capacity to len, NB. delete operations do not shrink space */
|
|
R_API void **r_vector_shrink(RVector *vec);
|
|
R_API void r_vector_sort(RVector *vec, RVectorComparator cmp);
|
|
|
|
#define r_vector_find(vec, it, cmp_eq) \
|
|
for (it = (vec)->a; it != (vec)->a + (vec)->len && !(cmp_eq (*it, x)); it++);
|
|
|
|
#define r_vector_foreach(vec, it) \
|
|
for (it = (vec)->a; it != (vec)->a + (vec)->len; it++)
|
|
|
|
#define r_vector_lower_bound(vec, x, i, cmp) \
|
|
do { \
|
|
int h = (vec)->len, m; \
|
|
for (i = 0; i < h; ) { \
|
|
m = i + ((h - i) >> 1); \
|
|
if ((cmp (x, (vec)->a[m])) > 0) { \
|
|
i = m + 1; \
|
|
} else { \
|
|
h = m; \
|
|
} \
|
|
} \
|
|
} while (0) \
|
|
|
|
#define r_vector_upper_bound(vec, x, i, cmp) \
|
|
do { \
|
|
int h = (vec)->len, m; \
|
|
for (i = 0; i < h; ) { \
|
|
m = i + ((h - i) >> 1); \
|
|
if (!((cmp (x, (vec)->a[m])) < 0)) { \
|
|
i = m + 1; \
|
|
} else { \
|
|
h = m; \
|
|
} \
|
|
} \
|
|
} while (0) \
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|