Mercurial > MadButterfly
diff include/mb_tools.h @ 186:530bb7728546 include_mb_test
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
This is the solution that I dicussed with FourDollars, last night.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 05 Nov 2008 15:24:01 +0800 |
parents | include/mb/tools.h@c7e5b8779bb5 |
children | 65cabbdd5284 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_tools.h Wed Nov 05 15:24:01 2008 +0800 @@ -0,0 +1,136 @@ +#ifndef __TOOLS_H_ +#define __TOOLS_H_ + +typedef struct _elmpool elmpool_t; + +extern elmpool_t *elmpool_new(int elm_sz, int inc_num); +extern void *elmpool_elm_alloc(elmpool_t *pool); +extern void elmpool_elm_free(elmpool_t *pool, void *elm); +extern void elmpool_free(elmpool_t *pool); + + +#define STAILQ(type) \ + struct { \ + type *head; \ + type *tail; \ + } +#define STAILQ_INIT(q) \ + do { \ + (q).head = (q).tail = NULL; \ + } while(0) +#define STAILQ_CLEAN(q) STAILQ_INIT(q) +#define STAILQ_HEAD(q) ((q).head) +#define STAILQ_TAIL(q) ((q).tail) +#define STAILQ_NEXT(type, field, elm) ((elm)->field) +#define STAILQ_INS(q, type, field, elm) \ + do { \ + (elm)->field = (q).head; \ + (q).head = elm; \ + if((q).tail == NULL) \ + (q).tail = elm; \ + } while(0) +#define STAILQ_INS_TAIL(q, type, field, elm) \ + do { \ + (elm)->field = NULL; \ + if((q).tail != NULL) \ + (q).tail->field = elm; \ + (q).tail = elm; \ + if((q).head == NULL) \ + (q).head = elm; \ + } while(0) +#define STAILQ_INS_AFTER(type, field, follow, elm) \ + do { \ + (follow)->field = (elm)->field; \ + (elm)->field = follow; \ + } while(0) +#define STAILQ_REMOVE(q, type, field, elm) \ + do { \ + if((elm) == (q).head) { \ + (q).head = (elm)->field; \ + if((q).head == NULL) \ + (q).tail = NULL; \ + } else { \ + type *_stailq_cur = (q).head; \ + while(_stailq_cur != NULL && \ + _stailq_cur->field != (elm)) \ + _stailq_cur = _stailq_cur->field; \ + if(_stailq_cur != NULL) { \ + _stailq_cur->field = (elm)->field; \ + if((q).tail == (elm)) \ + (q).tail = _stailq_cur; \ + } \ + } \ + } while(0) + +/*! \defgroup darray Dynamic Array + * + * DARRAY is a dynamic sized array/list, it's length is a variable. + * It is extended, automatically, if it is full and more elemnts are + * putted in. + * + * Users of DARRAY must declare a new type to store data. The way to + * declear a new type is to invoke DARRAY() with paramters of name of + * type and type of data to be stored in. The new storage type is named + * with foo_t where foo is the name you pass in. + * + * DARRAY_DEFINE() is inovked to define foo_add() function; foo is name + * of storage type. You can call foo_add() to add a data element + * into a storage object. + * + * Get ith element in a storage object, use + * \code + * obj->ds[i] + * \endcode + * + * To loop over elements in a storage object, us + * \code + * for(i = 0; i < obj->num; i++) { + * v = obj->ds[i]; + * ...... + * } + * \endcode + * @{ + */ +/*! \brief Declare a DARRAY storage type. + * + * \param name is name of storage type. + * \param type is type of data elements that will be stored in. + * + * Type of <name>_t is defined by the macro. It is used to define a + * storage object to contain data elements. + */ +#define DARRAY(name, type) \ + struct _ ## name { \ + int max, num; \ + type *ds; \ + }; \ + typedef struct _ ## name name ## _t +#define DARRAY_DEFINE(name, type) \ + static int name ## _add(name ## _t *da, type v) { \ + type *new_ds; \ + int max; \ + if(da->num >= (da)->max) { \ + max = (da)->max + 32; \ + new_ds = realloc(da->ds, \ + max * sizeof(type)); \ + if(new_ds == NULL) return -1; \ + da->ds = new_ds; \ + da->max = max; \ + } \ + da->ds[da->num++] = v; \ + return 0; \ + } +#define DARRAY_CLEAN(da) do { (da)->num = 0; } while(0) +#define DARRAY_INIT(da) do { (da)->num = (da)->max = 0; (da)->ds = NULL; } +#define DARRAY_DESTROY(da) do { if((da)->ds) free((da)->ds); } while(0) +/* @} */ + +#include <stdlib.h> + +#define O_ALLOC(type) ((type *)malloc(sizeof(type))) + +#define OFFSET(type, mem) (((void *)&((type *)NULL)->mem) - NULL) +#define MEM2OBJ(var, type, mem) ((type *)((void *)var - OFFSET(type, mem))) +#define OFF2TYPE(obj, off, type) (*(type *)((void *)(obj) + (off))) + +#endif /* __TOOLS_H_ */