106 lines
2.5 KiB
C
106 lines
2.5 KiB
C
|
#ifndef HV_QUEUE_H_
|
||
|
#define HV_QUEUE_H_
|
||
|
|
||
|
/*
|
||
|
* queue
|
||
|
* FIFO: push_back,pop_front
|
||
|
* stack
|
||
|
* LIFO: push_back,pop_back
|
||
|
*/
|
||
|
|
||
|
#include <assert.h> // for assert
|
||
|
#include <stddef.h> // for NULL
|
||
|
#include <stdlib.h> // for malloc,realloc,free
|
||
|
#include <string.h> // for memset,memmove
|
||
|
|
||
|
#include "hbase.h" // for HV_ALLOC, HV_FREE
|
||
|
|
||
|
#define QUEUE_INIT_SIZE 16
|
||
|
|
||
|
// #include <deque>
|
||
|
// typedef std::deque<type> qtype;
|
||
|
#define QUEUE_DECL(type, qtype) \
|
||
|
struct qtype { \
|
||
|
type* ptr; \
|
||
|
size_t size; \
|
||
|
size_t maxsize;\
|
||
|
size_t _offset;\
|
||
|
}; \
|
||
|
typedef struct qtype qtype;\
|
||
|
\
|
||
|
static inline type* qtype##_data(qtype* p) {\
|
||
|
return p->ptr + p->_offset;\
|
||
|
}\
|
||
|
\
|
||
|
static inline int qtype##_size(qtype* p) {\
|
||
|
return p->size;\
|
||
|
}\
|
||
|
\
|
||
|
static inline int qtype##_maxsize(qtype* p) {\
|
||
|
return p->maxsize;\
|
||
|
}\
|
||
|
\
|
||
|
static inline int qtype##_empty(qtype* p) {\
|
||
|
return p->size == 0;\
|
||
|
}\
|
||
|
\
|
||
|
static inline type* qtype##_front(qtype* p) {\
|
||
|
return p->size == 0 ? NULL : p->ptr + p->_offset;\
|
||
|
}\
|
||
|
\
|
||
|
static inline type* qtype##_back(qtype* p) {\
|
||
|
return p->size == 0 ? NULL : p->ptr + p->_offset + p->size - 1;\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_init(qtype* p, int maxsize) {\
|
||
|
p->_offset = 0;\
|
||
|
p->size = 0;\
|
||
|
p->maxsize = maxsize;\
|
||
|
HV_ALLOC(p->ptr, sizeof(type) * maxsize);\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_clear(qtype* p) {\
|
||
|
p->_offset = 0;\
|
||
|
p->size = 0;\
|
||
|
memset(p->ptr, 0, sizeof(type) * p->maxsize);\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_cleanup(qtype* p) {\
|
||
|
HV_FREE(p->ptr);\
|
||
|
p->_offset = p->size = p->maxsize = 0;\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_resize(qtype* p, int maxsize) {\
|
||
|
if (maxsize == 0) maxsize = QUEUE_INIT_SIZE;\
|
||
|
p->ptr = (type*)hv_realloc(p->ptr, sizeof(type) * maxsize, sizeof(type) * p->maxsize);\
|
||
|
p->maxsize = maxsize;\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_double_resize(qtype* p) {\
|
||
|
qtype##_resize(p, p->maxsize * 2);\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_push_back(qtype* p, type* elem) {\
|
||
|
if (p->size == p->maxsize) {\
|
||
|
qtype##_double_resize(p);\
|
||
|
}\
|
||
|
else if (p->_offset + p->size == p->maxsize) {\
|
||
|
memmove(p->ptr, p->ptr + p->_offset, sizeof(type) * p->size);\
|
||
|
p->_offset = 0;\
|
||
|
}\
|
||
|
p->ptr[p->_offset + p->size] = *elem;\
|
||
|
p->size++;\
|
||
|
}\
|
||
|
static inline void qtype##_pop_front(qtype* p) {\
|
||
|
assert(p->size > 0);\
|
||
|
p->size--;\
|
||
|
if (++p->_offset == p->maxsize) p->_offset = 0;\
|
||
|
}\
|
||
|
\
|
||
|
static inline void qtype##_pop_back(qtype* p) {\
|
||
|
assert(p->size > 0);\
|
||
|
p->size--;\
|
||
|
}\
|
||
|
|
||
|
#endif // HV_QUEUE_H_
|