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
|
#include "array.h"
#include <string.h>
#include "internal.h"
#define META_CNT ARY_META_CNT
#define DATA_SZ sizeof(int) * META_CNT
void **ary_new_i(int type_size, int init_capa)
{
void **ary;
if (init_capa <= 0) {
init_capa = ARY_INIT_CAPA;
}
ary = (void **)&(((int *)ecalloc(DATA_SZ +
init_capa * type_size))[META_CNT]);
ary_type_size(ary) = type_size;
ary_capa(ary) = init_capa;
return ary;
}
INLINE void ary_resize_i(void ***ary, int size)
{
size++;
if (size > ary_sz(*ary)) {
int capa = ary_capa(*ary);
if (size >= capa) {
int *ary_start = &((int *)*ary)[-META_CNT];
while (size >= capa) {
capa <<= 1;
}
ary_start = (int *)erealloc(ary_start,
DATA_SZ + capa * ary_type_size(*ary));
*ary = (void **)&(ary_start[META_CNT]);
memset(((char *)*ary) + ary_type_size(*ary) * ary_sz(*ary), 0,
(capa - ary_sz(*ary)) * ary_type_size(*ary));
ary_capa(*ary) = capa;
}
ary_sz(*ary) = size;
}
}
void ary_set_i(void ***ary, int index, void *value)
{
if (index < 0) {
index += ary_sz(*ary);
if (index < 0) {
RAISE(INDEX_ERROR, "index %d out array", index);
}
}
ary_resize_i(ary, index);
(*ary)[index] = value;
}
void *ary_get_i(void **ary, int index)
{
if (index < 0) {
index += ary_sz(ary);
}
if (index >= 0 && index < ary_sz(ary)) {
return ary[index];
}
else {
return NULL;
}
}
void ary_push_i(void ***ary, void *value)
{
int size = ary_sz(*ary);
ary_resize_i(ary, size);
(*ary)[size] = value;
}
void *ary_pop_i(void **ary)
{
void *val = ary[--ary_sz(ary)];
ary[ary_sz(ary)] = NULL;
return val;
}
void ary_unshift_i(void ***ary, void *value)
{
int size = ary_sz(*ary);
ary_resize_i(ary, size);
memmove(*ary + 1, *ary, size * sizeof(void *));
(*ary)[0] = value;
}
void *ary_shift_i(void **ary)
{
void *val = ary[0];
int size = --ary_sz(ary);
memmove(ary, ary + 1, size * sizeof(void *));
ary[size] = NULL;
return val;
}
void *ary_remove_i(void **ary, int index)
{
if (index >= 0 && index < ary_sz(ary)) {
void *val = ary[index];
memmove(ary + index, ary + index + 1,
(ary_sz(ary) - index + 1) * sizeof(void *));
ary_sz(ary)--;
return val;
}
else {
return NULL;
}
}
void ary_delete_i(void **ary, int index, void (*free_elem)(void *p))
{
free_elem(ary_remove(ary, index));
}
void ary_destroy_i(void **ary, void (*free_elem)(void *p))
{
int i;
for (i = ary_sz(ary) - 1; i >= 0; i--) {
free_elem(ary[i]);
}
ary_free(ary);
}
|