xvect.h is now based on kvec.h
This commit is contained in:
parent
9af074d803
commit
f7d506cd35
|
@ -17,6 +17,10 @@
|
|||
# error enable PIC_NONE_IS_FALSE
|
||||
#endif
|
||||
|
||||
typedef xvect_t(pic_sym *) xvect;
|
||||
|
||||
#define xv_push_sym(v, x) xv_push(pic_sym *, (v), (x))
|
||||
|
||||
/**
|
||||
* scope object
|
||||
*/
|
||||
|
@ -94,7 +98,7 @@ new_analyze_state(pic_state *pic)
|
|||
push_scope(state, pic_nil_value());
|
||||
|
||||
pic_dict_for_each (sym, pic->globals, it) {
|
||||
xv_push(&state->scope->locals, &sym);
|
||||
xv_push_sym(state->scope->locals, sym);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -119,7 +123,7 @@ analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *
|
|||
return false;
|
||||
}
|
||||
sym = pic_sym_ptr(t);
|
||||
xv_push(args, &sym);
|
||||
xv_push_sym(*args, sym);
|
||||
}
|
||||
if (pic_nil_p(v)) {
|
||||
*varg = false;
|
||||
|
@ -127,7 +131,7 @@ analyze_args(pic_state *pic, pic_value formals, bool *varg, xvect *args, xvect *
|
|||
else if (pic_sym_p(v)) {
|
||||
*varg = true;
|
||||
sym = pic_sym_ptr(v);
|
||||
xv_push(locals, &sym);
|
||||
xv_push_sym(*locals, sym);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
@ -144,9 +148,9 @@ push_scope(analyze_state *state, pic_value formals)
|
|||
bool varg;
|
||||
xvect args, locals, captures;
|
||||
|
||||
xv_init(&args, sizeof(pic_sym *));
|
||||
xv_init(&locals, sizeof(pic_sym *));
|
||||
xv_init(&captures, sizeof(pic_sym *));
|
||||
xv_init(args);
|
||||
xv_init(locals);
|
||||
xv_init(captures);
|
||||
|
||||
if (analyze_args(pic, formals, &varg, &args, &locals)) {
|
||||
scope = pic_alloc(pic, sizeof(analyze_scope));
|
||||
|
@ -163,8 +167,8 @@ push_scope(analyze_state *state, pic_value formals)
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
xv_destroy(&args);
|
||||
xv_destroy(&locals);
|
||||
xv_destroy(args);
|
||||
xv_destroy(locals);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -172,12 +176,13 @@ push_scope(analyze_state *state, pic_value formals)
|
|||
static void
|
||||
pop_scope(analyze_state *state)
|
||||
{
|
||||
pic_state *pic = state->pic;
|
||||
analyze_scope *scope;
|
||||
|
||||
scope = state->scope;
|
||||
xv_destroy(&scope->args);
|
||||
xv_destroy(&scope->locals);
|
||||
xv_destroy(&scope->captures);
|
||||
xv_destroy(scope->args);
|
||||
xv_destroy(scope->locals);
|
||||
xv_destroy(scope->captures);
|
||||
|
||||
scope = scope->up;
|
||||
pic_free(state->pic, state->scope);
|
||||
|
@ -187,38 +192,33 @@ pop_scope(analyze_state *state)
|
|||
static bool
|
||||
lookup_scope(analyze_scope *scope, pic_sym *sym)
|
||||
{
|
||||
pic_sym **arg, **local;
|
||||
size_t i;
|
||||
|
||||
/* args */
|
||||
for (i = 0; i < xv_size(&scope->args); ++i) {
|
||||
arg = xv_get(&scope->args, i);
|
||||
if (*arg == sym)
|
||||
for (i = 0; i < xv_size(scope->args); ++i) {
|
||||
if (xv_A(scope->args, i) == sym)
|
||||
return true;
|
||||
}
|
||||
/* locals */
|
||||
for (i = 0; i < xv_size(&scope->locals); ++i) {
|
||||
local = xv_get(&scope->locals, i);
|
||||
if (*local == sym)
|
||||
for (i = 0; i < xv_size(scope->locals); ++i) {
|
||||
if (xv_A(scope->locals, i) == sym)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
capture_var(analyze_scope *scope, pic_sym *sym)
|
||||
capture_var(pic_state *pic, analyze_scope *scope, pic_sym *sym)
|
||||
{
|
||||
pic_sym **var;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < xv_size(&scope->captures); ++i) {
|
||||
var = xv_get(&scope->captures, i);
|
||||
if (*var == sym) {
|
||||
for (i = 0; i < xv_size(scope->captures); ++i) {
|
||||
if (xv_A(scope->captures, i) == sym) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == xv_size(&scope->captures)) {
|
||||
xv_push(&scope->captures, &sym);
|
||||
if (i == xv_size(scope->captures)) {
|
||||
xv_push_sym(scope->captures, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ find_var(analyze_state *state, pic_sym *sym)
|
|||
while (scope) {
|
||||
if (lookup_scope(scope, sym)) {
|
||||
if (depth > 0) {
|
||||
capture_var(scope, sym);
|
||||
capture_var(state->pic, scope, sym);
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ define_var(analyze_state *state, pic_sym *sym)
|
|||
return;
|
||||
}
|
||||
|
||||
xv_push(&scope->locals, &sym);
|
||||
xv_push_sym(scope->locals, sym);
|
||||
}
|
||||
|
||||
static pic_value analyze_node(analyze_state *, pic_value, bool);
|
||||
|
@ -373,13 +373,11 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
|||
|
||||
if (push_scope(state, formals)) {
|
||||
analyze_scope *scope = state->scope;
|
||||
pic_sym **var;
|
||||
size_t i;
|
||||
|
||||
args = pic_nil_value();
|
||||
for (i = xv_size(&scope->args); i > 0; --i) {
|
||||
var = xv_get(&scope->args, i - 1);
|
||||
pic_push(pic, pic_obj_value(*var), args);
|
||||
for (i = xv_size(scope->args); i > 0; --i) {
|
||||
pic_push(pic, pic_obj_value(xv_A(scope->args, i - 1)), args);
|
||||
}
|
||||
|
||||
varg = scope->varg
|
||||
|
@ -392,15 +390,13 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
|||
analyze_deferred(state);
|
||||
|
||||
locals = pic_nil_value();
|
||||
for (i = xv_size(&scope->locals); i > 0; --i) {
|
||||
var = xv_get(&scope->locals, i - 1);
|
||||
pic_push(pic, pic_obj_value(*var), locals);
|
||||
for (i = xv_size(scope->locals); i > 0; --i) {
|
||||
pic_push(pic, pic_obj_value(xv_A(scope->locals, i - 1)), locals);
|
||||
}
|
||||
|
||||
captures = pic_nil_value();
|
||||
for (i = xv_size(&scope->captures); i > 0; --i) {
|
||||
var = xv_get(&scope->captures, i - 1);
|
||||
pic_push(pic, pic_obj_value(*var), captures);
|
||||
for (i = xv_size(scope->captures); i > 0; --i) {
|
||||
pic_push(pic, pic_obj_value(xv_A(scope->captures, i - 1)), captures);
|
||||
}
|
||||
|
||||
pop_scope(state);
|
||||
|
@ -925,27 +921,24 @@ create_activation(codegen_context *cxt)
|
|||
{
|
||||
size_t i, n;
|
||||
xhash regs;
|
||||
pic_sym **var;
|
||||
size_t offset;
|
||||
|
||||
xh_init_ptr(®s, sizeof(size_t));
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < xv_size(&cxt->args); ++i) {
|
||||
var = xv_get(&cxt->args, i);
|
||||
for (i = 0; i < xv_size(cxt->args); ++i) {
|
||||
n = i + offset;
|
||||
xh_put_ptr(®s, *var, &n);
|
||||
xh_put_ptr(®s, xv_A(cxt->args, i), &n);
|
||||
}
|
||||
offset += i;
|
||||
for (i = 0; i < xv_size(&cxt->locals); ++i) {
|
||||
var = xv_get(&cxt->locals, i);
|
||||
for (i = 0; i < xv_size(cxt->locals); ++i) {
|
||||
n = i + offset;
|
||||
xh_put_ptr(®s, *var, &n);
|
||||
xh_put_ptr(®s, xv_A(cxt->locals, i), &n);
|
||||
}
|
||||
|
||||
for (i = 0; i < xv_size(&cxt->captures); ++i) {
|
||||
var = xv_get(&cxt->captures, i);
|
||||
if ((n = xh_val(xh_get_ptr(®s, *var), size_t)) <= xv_size(&cxt->args) || (cxt->varg && n == xv_size(&cxt->args) + 1)) {
|
||||
for (i = 0; i < xv_size(cxt->captures); ++i) {
|
||||
n = xh_val(xh_get_ptr(®s, xv_A(cxt->captures, i)), size_t);
|
||||
if (n <= xv_size(cxt->args) || (cxt->varg && n == xv_size(cxt->args) + 1)) {
|
||||
/* copy arguments to capture variable area */
|
||||
cxt->code[cxt->clen].insn = OP_LREF;
|
||||
cxt->code[cxt->clen].u.i = (int)n;
|
||||
|
@ -966,7 +959,6 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
|||
pic_state *pic = state->pic;
|
||||
codegen_context *cxt;
|
||||
pic_value var, it;
|
||||
pic_sym *sym;
|
||||
|
||||
assert(pic_sym_p(name) || pic_false_p(name));
|
||||
|
||||
|
@ -977,21 +969,18 @@ push_codegen_context(codegen_state *state, pic_value name, pic_value args, pic_v
|
|||
: pic_sym_ptr(name);
|
||||
cxt->varg = varg;
|
||||
|
||||
xv_init(&cxt->args, sizeof(pic_sym *));
|
||||
xv_init(&cxt->locals, sizeof(pic_sym *));
|
||||
xv_init(&cxt->captures, sizeof(pic_sym *));
|
||||
xv_init(cxt->args);
|
||||
xv_init(cxt->locals);
|
||||
xv_init(cxt->captures);
|
||||
|
||||
pic_for_each (var, args, it) {
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->args, &sym);
|
||||
xv_push_sym(cxt->args, pic_sym_ptr(var));
|
||||
}
|
||||
pic_for_each (var, locals, it) {
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->locals, &sym);
|
||||
xv_push_sym(cxt->locals, pic_sym_ptr(var));
|
||||
}
|
||||
pic_for_each (var, captures, it) {
|
||||
sym = pic_sym_ptr(var);
|
||||
xv_push(&cxt->captures, &sym);
|
||||
xv_push_sym(cxt->captures, pic_sym_ptr(var));
|
||||
}
|
||||
|
||||
cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));
|
||||
|
@ -1026,9 +1015,9 @@ pop_codegen_context(codegen_state *state)
|
|||
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
|
||||
irep->name = state->cxt->name;
|
||||
irep->varg = state->cxt->varg;
|
||||
irep->argc = (int)xv_size(&state->cxt->args) + 1;
|
||||
irep->localc = (int)xv_size(&state->cxt->locals);
|
||||
irep->capturec = (int)xv_size(&state->cxt->captures);
|
||||
irep->argc = (int)xv_size(state->cxt->args) + 1;
|
||||
irep->localc = (int)xv_size(state->cxt->locals);
|
||||
irep->capturec = (int)xv_size(state->cxt->captures);
|
||||
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
|
||||
irep->clen = state->cxt->clen;
|
||||
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
|
||||
|
@ -1039,9 +1028,9 @@ pop_codegen_context(codegen_state *state)
|
|||
irep->slen = state->cxt->slen;
|
||||
|
||||
/* finalize */
|
||||
xv_destroy(&cxt->args);
|
||||
xv_destroy(&cxt->locals);
|
||||
xv_destroy(&cxt->captures);
|
||||
xv_destroy(cxt->args);
|
||||
xv_destroy(cxt->locals);
|
||||
xv_destroy(cxt->captures);
|
||||
|
||||
/* destroy context */
|
||||
cxt = cxt->up;
|
||||
|
@ -1056,15 +1045,13 @@ index_capture(codegen_state *state, pic_sym *sym, int depth)
|
|||
{
|
||||
codegen_context *cxt = state->cxt;
|
||||
size_t i;
|
||||
pic_sym **var;
|
||||
|
||||
while (depth-- > 0) {
|
||||
cxt = cxt->up;
|
||||
}
|
||||
|
||||
for (i = 0; i < xv_size(&cxt->captures); ++i) {
|
||||
var = xv_get(&cxt->captures, i);
|
||||
if (*var == sym)
|
||||
for (i = 0; i < xv_size(cxt->captures); ++i) {
|
||||
if (xv_A(cxt->captures, i) == sym)
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
|
@ -1075,18 +1062,15 @@ index_local(codegen_state *state, pic_sym *sym)
|
|||
{
|
||||
codegen_context *cxt = state->cxt;
|
||||
size_t i, offset;
|
||||
pic_sym **var;
|
||||
|
||||
offset = 1;
|
||||
for (i = 0; i < xv_size(&cxt->args); ++i) {
|
||||
var = xv_get(&cxt->args, i);
|
||||
if (*var == sym)
|
||||
for (i = 0; i < xv_size(cxt->args); ++i) {
|
||||
if (xv_A(cxt->args, i) == sym)
|
||||
return (int)(i + offset);
|
||||
}
|
||||
offset += i;
|
||||
for (i = 0; i < xv_size(&cxt->locals); ++i) {
|
||||
var = xv_get(&cxt->locals, i);
|
||||
if (*var == sym)
|
||||
for (i = 0; i < xv_size(cxt->locals); ++i) {
|
||||
if (xv_A(cxt->locals, i) == sym)
|
||||
return (int)(i + offset);
|
||||
}
|
||||
return -1;
|
||||
|
@ -1145,7 +1129,7 @@ codegen(codegen_state *state, pic_value obj)
|
|||
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
||||
if ((i = index_capture(state, name, 0)) != -1) {
|
||||
cxt->code[cxt->clen].insn = OP_LREF;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1;
|
||||
cxt->clen++;
|
||||
return;
|
||||
}
|
||||
|
@ -1191,7 +1175,7 @@ codegen(codegen_state *state, pic_value obj)
|
|||
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
||||
if ((i = index_capture(state, name, 0)) != -1) {
|
||||
cxt->code[cxt->clen].insn = OP_LSET;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(&cxt->args) + (int)xv_size(&cxt->locals) + 1;
|
||||
cxt->code[cxt->clen].u.i = i + (int)xv_size(cxt->args) + (int)xv_size(cxt->locals) + 1;
|
||||
cxt->clen++;
|
||||
cxt->code[cxt->clen].insn = OP_PUSHNONE;
|
||||
cxt->clen++;
|
||||
|
|
|
@ -704,20 +704,20 @@ static void
|
|||
gc_sweep_symbols(pic_state *pic)
|
||||
{
|
||||
xh_entry *it;
|
||||
xvect xv;
|
||||
xvect_t(xh_entry *) xv;
|
||||
size_t i;
|
||||
char *cstr;
|
||||
|
||||
xv_init(&xv, sizeof(xh_entry *));
|
||||
xv_init(xv);
|
||||
|
||||
for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) {
|
||||
if (! gc_obj_is_marked((struct pic_object *)xh_val(it, pic_sym *))) {
|
||||
xv_push(&xv, &it);
|
||||
xv_push(xh_entry *, xv, it);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < xv_size(&xv); ++i) {
|
||||
cstr = xh_key(*(xh_entry **)xv_get(&xv, i), char *);
|
||||
for (i = 0; i < xv_size(xv); ++i) {
|
||||
cstr = xh_key(xv_A(xv, i), char *);
|
||||
|
||||
xh_del_str(&pic->syms, cstr);
|
||||
|
||||
|
|
|
@ -1,202 +1,76 @@
|
|||
#ifndef XVECT_H__
|
||||
#define XVECT_H__
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 by Yuichi Nishiwaki <yuichi@idylls.jp>
|
||||
*/
|
||||
/* The MIT License
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
|
||||
Copyright (c) 2014, by Yuichi Nishiwaki <yuichi@idylls.jp>
|
||||
|
||||
typedef struct xvect {
|
||||
char *data;
|
||||
size_t size, mask, head, tail, width;
|
||||
} xvect;
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
static inline void xv_init(xvect *, size_t);
|
||||
static inline void xv_destroy(xvect *);
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
static inline size_t xv_size(xvect *);
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
static inline void xv_reserve(xvect *, size_t);
|
||||
static inline void xv_shrink(xvect *, size_t);
|
||||
#define xv_realloc(P,Z) pic_realloc(pic,P,Z)
|
||||
#define xv_free(P) pic_free(pic,P)
|
||||
|
||||
static inline void *xv_get(xvect *, size_t);
|
||||
static inline void xv_set(xvect *, size_t, void *);
|
||||
#define xv_roundup32(x) \
|
||||
(--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
|
||||
static inline void xv_push(xvect *, void *);
|
||||
static inline void *xv_pop(xvect *);
|
||||
#define xvect_t(type) struct { size_t n, m; type *a; }
|
||||
#define xv_init(v) ((v).n = (v).m = 0, (v).a = 0)
|
||||
#define xv_destroy(v) xv_free((v).a)
|
||||
#define xv_A(v, i) ((v).a[(i)])
|
||||
#define xv_pop(v) ((v).a[--(v).n])
|
||||
#define xv_size(v) ((v).n)
|
||||
#define xv_max(v) ((v).m)
|
||||
|
||||
static inline void *xv_shift(xvect *);
|
||||
static inline void xv_unshift(xvect *, void *);
|
||||
#define xv_resize(type, v, s) \
|
||||
((v).m = (s), (v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m))
|
||||
|
||||
static inline void xv_splice(xvect *, size_t, size_t);
|
||||
static inline void xv_insert(xvect *, size_t, void *);
|
||||
#define xv_copy(type, v1, v0) \
|
||||
do { \
|
||||
if ((v1).m < (v0).n) xv_resize(type, v1, (v0).n); \
|
||||
(v1).n = (v0).n; \
|
||||
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
|
||||
} while (0) \
|
||||
|
||||
static inline void
|
||||
xv_init(xvect *x, size_t width)
|
||||
{
|
||||
x->data = NULL;
|
||||
x->width = width;
|
||||
x->size = 0;
|
||||
x->mask = (size_t)-1;
|
||||
x->head = 0;
|
||||
x->tail = 0;
|
||||
}
|
||||
#define xv_push(type, v, x) \
|
||||
do { \
|
||||
if ((v).n == (v).m) { \
|
||||
(v).m = (v).m? (v).m<<1 : 2; \
|
||||
(v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m); \
|
||||
} \
|
||||
(v).a[(v).n++] = (x); \
|
||||
} while (0)
|
||||
|
||||
static inline void
|
||||
xv_destroy(xvect *x)
|
||||
{
|
||||
free(x->data);
|
||||
}
|
||||
#define xv_pushp(type, v) \
|
||||
(((v).n == (v).m)? \
|
||||
((v).m = ((v).m? (v).m<<1 : 2), \
|
||||
(v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m), 0) \
|
||||
: 0), ((v).a + ((v).n++))
|
||||
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
||||
static inline void *
|
||||
xv_get(xvect *x, size_t i)
|
||||
{
|
||||
assert(i < xv_size(x));
|
||||
|
||||
return x->data + ((x->head + i) & x->mask) * x->width;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xv_set(xvect *x, size_t i, void *src)
|
||||
{
|
||||
memcpy(xv_get(x, i), src, x->width);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xv_push(xvect *x, void *src)
|
||||
{
|
||||
xv_reserve(x, xv_size(x) + 1);
|
||||
x->tail = (x->tail + 1) & x->mask;
|
||||
xv_set(x, xv_size(x) - 1, src);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
xv_pop(xvect *x)
|
||||
{
|
||||
void *dat;
|
||||
|
||||
assert(xv_size(x) >= 1);
|
||||
|
||||
dat = xv_get(x, xv_size(x) - 1);
|
||||
x->tail = (x->tail - 1) & x->mask;
|
||||
return dat;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
xv_shift(xvect *x)
|
||||
{
|
||||
void *dat;
|
||||
|
||||
assert(xv_size(x) >= 1);
|
||||
|
||||
dat = xv_get(x, 0);
|
||||
x->head = (x->head + 1) & x->mask;
|
||||
return dat;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xv_unshift(xvect *x, void *src)
|
||||
{
|
||||
xv_reserve(x, xv_size(x) + 1);
|
||||
x->head = (x->head - 1) & x->mask;
|
||||
xv_set(x, 0, src);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xv_splice(xvect *x, size_t i, size_t j)
|
||||
{
|
||||
assert(i <= j && j < xv_size(x));
|
||||
|
||||
xv_rotate(x);
|
||||
memmove(xv_get(x, i), xv_get(x, j), (xv_size(x) - j) * x->width);
|
||||
x->tail = (x->tail - j + i) & x->mask;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xv_insert(xvect *x, size_t i, void *src)
|
||||
{
|
||||
assert(i <= xv_size(x));
|
||||
|
||||
xv_reserve(x, xv_size(x) + 1);
|
||||
xv_rotate(x);
|
||||
x->tail = (x->tail + 1) & x->mask;
|
||||
|
||||
if (xv_size(x) - 1 != i) {
|
||||
memmove(xv_get(x, i + 1), xv_get(x, i), (xv_size(x) - 1 - i) * x->width);
|
||||
}
|
||||
xv_set(x, i, src);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#define xv_a(type, v, i) \
|
||||
(((v).m <= (size_t)(i)? \
|
||||
((v).m = (v).n = (i) + 1, xv_roundup32((v).m), \
|
||||
(v).a = (type*)xv_realloc((v).a, sizeof(type) * (v).m), 0) \
|
||||
: (v).n <= (size_t)(i)? (v).n = (i) + 1 \
|
||||
: 0), (v).a[(i)])
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue