array: add bisect-style insert and lookup
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
c95ba76d2f
commit
f8d549139f
|
@ -23,8 +23,11 @@
|
||||||
#ifndef AWESOME_COMMON_ARRAY_H
|
#ifndef AWESOME_COMMON_ARRAY_H
|
||||||
#define AWESOME_COMMON_ARRAY_H
|
#define AWESOME_COMMON_ARRAY_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
|
/** Common array type */
|
||||||
#define ARRAY_TYPE(type_t, pfx) \
|
#define ARRAY_TYPE(type_t, pfx) \
|
||||||
typedef struct pfx##_array_t { \
|
typedef struct pfx##_array_t { \
|
||||||
type_t *tab; \
|
type_t *tab; \
|
||||||
|
@ -40,7 +43,8 @@
|
||||||
(var = &(array).tab[__foreach_index_##var]); \
|
(var = &(array).tab[__foreach_index_##var]); \
|
||||||
++__foreach_index_##var)
|
++__foreach_index_##var)
|
||||||
|
|
||||||
#define ARRAY_FUNCS(type_t, pfx, dtor) \
|
/** Common array functions */
|
||||||
|
#define ARRAY_COMMON_FUNCS(type_t, pfx, dtor) \
|
||||||
static inline pfx##_array_t * pfx##_array_new(void) { \
|
static inline pfx##_array_t * pfx##_array_new(void) { \
|
||||||
return p_new(pfx##_array_t, 1); \
|
return p_new(pfx##_array_t, 1); \
|
||||||
} \
|
} \
|
||||||
|
@ -89,7 +93,11 @@
|
||||||
static inline type_t pfx##_array_remove(pfx##_array_t *arr, type_t *e) \
|
static inline type_t pfx##_array_remove(pfx##_array_t *arr, type_t *e) \
|
||||||
{ \
|
{ \
|
||||||
return pfx##_array_take(arr, pfx##_array_indexof(arr, e)); \
|
return pfx##_array_take(arr, pfx##_array_indexof(arr, e)); \
|
||||||
} \
|
}
|
||||||
|
|
||||||
|
/** Non-ordered array functions */
|
||||||
|
#define ARRAY_FUNCS(type_t, pfx, dtor) \
|
||||||
|
ARRAY_COMMON_FUNCS(type_t, pfx, dtor) \
|
||||||
static inline void \
|
static inline void \
|
||||||
pfx##_array_push(pfx##_array_t *arr, type_t e) \
|
pfx##_array_push(pfx##_array_t *arr, type_t e) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -97,11 +105,45 @@
|
||||||
} \
|
} \
|
||||||
static inline void pfx##_array_append(pfx##_array_t *arr, type_t e) { \
|
static inline void pfx##_array_append(pfx##_array_t *arr, type_t e) { \
|
||||||
pfx##_array_splice(arr, arr->len, 0, &e, 1); \
|
pfx##_array_splice(arr, arr->len, 0, &e, 1); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
/** Binary ordered array functions */
|
||||||
|
#define BARRAY_FUNCS(type_t, pfx, dtor, cmp) \
|
||||||
|
ARRAY_COMMON_FUNCS(type_t, pfx, dtor) \
|
||||||
|
static inline void \
|
||||||
|
pfx##_array_insert(pfx##_array_t *arr, type_t e) \
|
||||||
|
{ \
|
||||||
|
int l = 0, r = arr->len; \
|
||||||
|
while(l < r) \
|
||||||
|
{ \
|
||||||
|
int i = (r + l) / 2; \
|
||||||
|
switch(cmp(&e, &arr->tab[i])) \
|
||||||
|
{ \
|
||||||
|
case -1: \
|
||||||
|
r = i; \
|
||||||
|
break; \
|
||||||
|
case 0: \
|
||||||
|
return; \
|
||||||
|
case 1: \
|
||||||
|
l = i + 1; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
pfx##_array_splice(arr, r, 0, &e, 1); \
|
||||||
|
} \
|
||||||
|
static inline type_t * \
|
||||||
|
pfx##_array_lookup(pfx##_array_t *arr, type_t *e) \
|
||||||
|
{ \
|
||||||
|
return bsearch(e, arr->tab, arr->len, sizeof(type_t), cmp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ARRAY(type_t, pfx, dtor) \
|
#define DO_ARRAY(type_t, pfx, dtor) \
|
||||||
ARRAY_TYPE(type_t, pfx) \
|
ARRAY_TYPE(type_t, pfx) \
|
||||||
ARRAY_FUNCS(type_t, pfx, dtor)
|
ARRAY_FUNCS(type_t, pfx, dtor)
|
||||||
|
|
||||||
|
#define DO_BARRAY(type_t, pfx, dtor, cmp) \
|
||||||
|
ARRAY_TYPE(type_t, pfx) \
|
||||||
|
BARRAY_FUNCS(type_t, pfx, dtor, cmp)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue