1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
/*
util.h - (c) 2004 Tom Schouten.
this software is in the public domain.
This is supposed to be my low-level data structures toolbox.
Defined as inline static to avoid version and symbol clashes.
*/
#ifndef ZL_UTIL_H
#define ZL_UTIL_H
#include <stdlib.h>
// linkage
#define INLINE inline static
// growable array object
typedef struct {
int size;
int elements;
void **data;
} buf_t;
// fixed 2^n size queue object
typedef struct {
void **data;
unsigned int mask;
unsigned int read;
unsigned int write;
} queue_t;
typedef buf_t fifo_t; // same
/* small utils */
INLINE int imax(int x, int y){return (x > y) ? x : y;}
INLINE int imin(int x, int y){return (x < y) ? x : y;}
/* protos */
INLINE buf_t *buf_new(int size); ///< create a new growable array
INLINE void buf_add(buf_t *x, void *thing); ///< add an element
INLINE int buf_lookup(buf_t *x, void *thing); ///< lookup element and return index
INLINE int buf_add_to_set(buf_t *x, void *thing); ///< add if not already present
INLINE void buf_clear(buf_t *x);
INLINE void buf_free(buf_t *x);
INLINE void buf_remove(buf_t *x, void *thing);
INLINE int buf_allot(buf_t *x, int bytes); ///< allocate memory and return cell index
INLINE void stack_clear(fifo_t *x);
INLINE void stack_free(fifo_t *x);
INLINE int stack_elements(fifo_t *x);
INLINE void stack_push(fifo_t *x, void *data);
INLINE void *stack_pop(fifo_t *x);
INLINE void stack_clear(fifo_t *x);
INLINE void stack_free(fifo_t *x);
INLINE fifo_t *stack_new(int elements);
/* code */
INLINE buf_t *buf_new(int size){
buf_t *x = malloc(sizeof(*x));
x->size = size;
x->elements = 0;
x->data = malloc(sizeof(void *) * size);
return x;
}
INLINE void buf_add(buf_t *x, void *thing){
if (x->elements == x->size){
x->size *= 2;
x->data = realloc(x->data, x->size * sizeof(void *));
}
x->data[x->elements++] = thing;
}
INLINE int buf_lookup(buf_t *x, void *thing){
int i;
for (i=0; i<x->elements; i++){
if (x->data[i] == thing) return i; // found
}
return -1; // not found
}
// add if not in there
INLINE int buf_add_to_set(buf_t *x, void *thing){
int indx = buf_lookup(x, thing);
if (indx < 0){ // add if not found
indx = x->elements;
buf_add(x, thing);
}
return indx;
}
INLINE void buf_remove(buf_t *x, void *thing){
int indx = buf_lookup(x, thing);
if (indx < 0) return; // not here
x->elements--;
x->data[indx] = x->data[x->elements];
}
INLINE void buf_clear(buf_t *x){x->elements = 0;}
INLINE void buf_free(buf_t *x){free (x->data); free(x);}
INLINE int buf_allot(buf_t *x, int bytes){
int words = ((bytes-1) / sizeof(int)) - 1;
int indx = x->elements;
while(words--) buf_add(x, 0);
return indx;
}
INLINE fifo_t *stack_new(int nb_elements){
fifo_t *x = buf_new(nb_elements);
return x;
}
INLINE int stack_elements(fifo_t *x){return x->elements;}
INLINE void stack_push(fifo_t *x, void *data){buf_add(x, data);}
INLINE void *stack_pop(fifo_t *x){
if (!x->elements) return 0;
return x->data[--x->elements];
}
INLINE void stack_clear(fifo_t *x){buf_clear(x);}
INLINE void stack_free(fifo_t *x){buf_free(x);}
#if 0 // FIXME: name conflicts with queue in leaf/queue.h
INLINE queue_t *queue_new(int logsize);
INLINE void queue_free(queue_t *queue);
INLINE void queue_write(queue_t *queue, void *thing);
INLINE void *queue_read(queue_t *queue);
INLINE unsigned int queue_elements(queue_t *queue);
INLINE int queue_full(queue_t *queue);
INLINE queue_t *queue_new(int logsize){
queue_t *x = malloc(sizeof(*x));
x->data = malloc(1<<logsize * sizeof(void *));
x->mask = (1<<logsize) - 1;
x->read = 0;
x->write = 0;
return x;
}
INLINE void queue_free(queue_t *x){
free(x->data);
free(x);
}
INLINE unsigned int queue_elements(queue_t *x){
return (x->write - x->read) & x->mask;
}
INLINE int queue_full(queue_t *x){
return (x->mask == queue_elements(x));
}
INLINE void queue_write(queue_t *x, void *thing){
int i = x->write;
x->data[i++] = thing;
x->write = i & x->mask;
}
INLINE void *queue_read(queue_t *x){
int i = x->read;
void *thing = x->data[i++];
x->write = i & x->mask;
return thing;
}
#endif
#endif
|