libvec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }