array: add bisect-style insert and lookup

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-06-03 11:52:38 +02:00
parent c95ba76d2f
commit f8d549139f
1 changed files with 44 additions and 2 deletions

View File

@ -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