vec.c (1755B)
1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 #include "vec.h" 6 7 typedef unsigned char uchar; 8 typedef unsigned short ushort; 9 typedef unsigned long ulong; 10 11 static void* 12 emalloc(ulong n) 13 { 14 void* p; 15 16 p = malloc(n); 17 if (p == NULL) { 18 perror("libvec vec.c:emalloc()"); 19 abort(); 20 } 21 return p; 22 } 23 24 static void* 25 erealloc(void* p, ulong n) 26 { 27 p = realloc(p, n); 28 if (p == NULL) { 29 perror("libvec vec.c:erealloc()"); 30 abort(); 31 } 32 return p; 33 } 34 35 Vector* 36 Vec(void* p) 37 { 38 return (Vector*)p - 1; 39 } 40 41 void* 42 Vecadd_(void** p) 43 { 44 Vector* v; 45 46 Vecinsure(p, Vecsiz(*p) + 1); 47 v = Vec(*p); 48 if (v->init != NULL) 49 v->init((char*)*p + v->n * v->ms); 50 return (char*)*p + v->n++ * v->ms; 51 } 52 53 void 54 Vecclose_(void** p) 55 { 56 Vector* v; 57 58 v = Vec(*p); 59 if (v->close != NULL) 60 for (;v->n;) 61 v->close((char*)*p + --v->n * v->ms); 62 free(v); 63 *p = NULL; 64 } 65 66 void 67 Vecdel_(void** p, ulong n) 68 { 69 Vector* v; 70 char* q; 71 72 v = Vec(*p); 73 if (!v->n) 74 return; 75 q = (char*)p + n * v->ms; 76 if (v->close != NULL) 77 v->close(q); 78 memmove(q, q + v->ms, (--v->n - n) * v->ms); 79 memset(q + v->ms, 0, v->n * v->ms); 80 } 81 82 void 83 Vecinit_(void** p, ulong ms, void (*init)(), void (*close)()) 84 { 85 Vector* v; 86 87 v = emalloc(sizeof(*v)); 88 v->init = init; 89 v->close = close; 90 v->ms = ms; 91 v->n = 0; 92 v->size = 0; 93 *p = v + 1; 94 } 95 96 void 97 Vecinsure_(void** p, ulong n) 98 { 99 Vector* v; 100 101 v = Vec(*p); 102 if (v->size >= n) 103 return; 104 if (!v->size) 105 v->size = n; 106 else 107 for (; n > v->size; v->size *= 2); 108 v = erealloc(v, sizeof(*v) + v->size * v->ms); 109 *p = v + 1; 110 } 111 112 ulong 113 Vecsiz(void* p) 114 { 115 return Vec(p)->n; 116 } 117 118 void 119 Veczero_(void** p) 120 { 121 Vector* v; 122 123 v = Vec(*p); 124 if (v->close != NULL) 125 for (;v->n;) 126 v->close((char*)*p + --v->n * v->ms); 127 v = erealloc(v, sizeof(*v)); 128 v->size = 0; 129 *p = v + 1; 130 }