diff --git a/include/picrin/xvect.h b/include/picrin/xvect.h index bd72070e..ec68a2cb 100644 --- a/include/picrin/xvect.h +++ b/include/picrin/xvect.h @@ -2,51 +2,40 @@ #define XVECT_H__ /* - * Copyright (c) 2014 by Yuichi Nishiwaki + * Copyright (c) 2014 by Yuichi Nishiwaki */ #if defined(__cplusplus) extern "C" { #endif -#include #include #include typedef struct xvect { char *data; - size_t size, mask, head, tail, width; + size_t size, capa, width; } xvect; static inline void xv_init(xvect *, size_t); static inline void xv_destroy(xvect *); -static inline size_t xv_size(xvect *); - static inline void xv_reserve(xvect *, size_t); -static inline void xv_shrink(xvect *, size_t); static inline void *xv_get(xvect *, size_t); static inline void xv_set(xvect *, size_t, void *); static inline void xv_push(xvect *, void *); +static inline void *xv_peek(xvect *); static inline void *xv_pop(xvect *); -static inline void *xv_shift(xvect *); -static inline void xv_unshift(xvect *, void *); - -static inline void xv_splice(xvect *, size_t, ptrdiff_t); -static inline void xv_insert(xvect *, size_t, void *); - static inline void xv_init(xvect *x, size_t width) { x->data = NULL; - x->width = width; x->size = 0; - x->mask = -1; - x->head = 0; - x->tail = 0; + x->capa = 0; + x->width = width; } static inline void @@ -55,127 +44,44 @@ xv_destroy(xvect *x) free(x->data); } -static inline size_t -xv_size(xvect *x) -{ - return x->tail < x->head - ? x->tail + x->size - x->head - : x->tail - x->head; -} - -static inline size_t -xv_round2(size_t x) -{ - x -= 1; - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - x |= (x >> 32); - x++; - return x; -} - static inline void -xv_rotate(xvect *x) +xv_reserve(xvect *x, size_t newcapa) { - if (x->tail < x->head) { - char buf[x->size * x->width]; - - /* perform rotation */ - memcpy(buf, x->data, sizeof buf); - memcpy(x->data, buf + x->head * x->width, (x->size - x->head) * x->width); - memcpy(x->data + (x->size - x->head) * x->width, buf, x->tail * x->width); - x->tail = x->size - x->head + x->tail; - x->head = 0; - } -} - -static inline void -xv_adjust(xvect *x, size_t size) -{ - size = xv_round2(size); - if (size != x->size) { - xv_rotate(x); - x->data = realloc(x->data, size * x->width); - x->size = size; - x->mask = size - 1; - } -} - -static inline void -xv_reserve(xvect *x, size_t mincapa) -{ - if (x->size < mincapa + 1) { - xv_adjust(x, mincapa + 1); /* capa == size - 1 */ - } -} - -static inline void -xv_shrink(xvect *x, size_t maxcapa) -{ - if (x->size > maxcapa + 1) { - xv_adjust(x, maxcapa + 1); /* capa == size - 1 */ - } + x->data = realloc(x->data, newcapa * x->width); + x->capa = newcapa; } static inline void * xv_get(xvect *x, size_t i) { - return x->data + ((x->head + x->size + i) & x->mask) * x->width; + return x->data + i * x->width; } static inline void xv_set(xvect *x, size_t i, void *src) { - memcpy(xv_get(x, i), src, x->width); + memcpy(x->data + i * x->width, src, x->width); } static inline void xv_push(xvect *x, void *src) { - xv_reserve(x, xv_size(x) + 1); - xv_set(x, xv_size(x), src); - x->tail = (x->tail + 1) & x->mask; + if (x->capa <= x->size + 1) { + xv_reserve(x, x->size * 2 + 1); + } + xv_set(x, x->size++, src); +} + +static inline void * +xv_peek(xvect *x) +{ + return xv_get(x, x->size); } static inline void * xv_pop(xvect *x) { - x->tail = (x->tail + x->size - 1) & x->mask; - return xv_get(x, xv_size(x)); -} - -static inline void * -xv_shift(xvect *x) -{ - x->head = (x->head + 1) & x->mask; - return xv_get(x, -1); -} - -static inline void -xv_unshift(xvect *x, void *src) -{ - xv_reserve(x, xv_size(x) + 1); - xv_set(x, -1, src); - x->head = (x->head + x->size - 1) & x->mask; -} - -static inline void -xv_splice(xvect *x, size_t i, ptrdiff_t c) -{ - xv_reserve(x, xv_size(x) - c); - xv_rotate(x); - memmove(xv_get(x, i), xv_get(x, i + c), (xv_size(x) - i - c) * x->width); - x->tail -= c; -} - -static inline void -xv_insert(xvect *x, size_t i, void *src) -{ - xv_splice(x, i, -1); - xv_set(x, i, src); + return xv_get(x, --x->size); } #if defined(__cplusplus)