#ifndef PACKAGE__PROG__PRJLIBS__VEC_H #define PACKAGE__PROG__PRJLIBS__VEC_H #include #include #include #include "types.h" #include "warn.h" typedef struct { unsigned char* s; /* pointer to allocated bytes */ size_t len; /* count of bytes exposed to the caller */ size_t a; /* count of allocated bytes */ } vec_type; /* These might belong somewhere else... */ enum { vec_size_bits=sizeof (size_t)*CHAR_BIT }; #define VEC_ALIGN(type) offsetof(struct { char c; type t; }, t) #define VEC_SIZE_UP(sz0, sz1) \ ((WARN_CAST(size_t, sz0)+(WARN_CAST(size_t, sz1)-1u)) \ /(size_t)(sz1)*(size_t)(sz1)) #define VEC_T(type) union { vec_type generic_vector; type* typecheck; } #define VEC_TD(type, name) typedef VEC_T(type) name #define VEC_0(type) { { (unsigned char*)NULL, 0, 0 } } #define VEC_GV(type, vec) \ (WARN_TYPE(vec_type, (vec)->generic_vector), \ WARN_TYPE(type*, (vec)->typecheck), \ &(vec)->generic_vector) #define VEC_GV_S( type, vec) (VEC_GV(type, vec)->s) #define VEC_GV_LEN(type, vec) (VEC_GV(type, vec)->len) typedef void vec_ftype_vop1(void*); typedef void vec_ftype_vop2(void*, void*); extern vec_ftype_vop1 vec_init; #define VEC_INIT(type, vec) vec_init(VEC_GV(type, vec)) extern vec_ftype_vop1 vec_free; #define VEC_FREE(type, vec) vec_free(VEC_GV(type, vec)) #define VEC_LEN_(typesize, vec) \ (WARN_CAST(vec_type*, vec)->len/WARN_CAST(size_t, typesize)) #define VEC_BLEN(type, vec) VEC_GV_LEN(type, vec) #define VEC_LEN(type, vec) (VEC_GV_LEN(type, vec)/sizeof (type)) extern type_status vec_trunc(size_t, vec_type*, size_t); #define VEC_TRUNC(type, vec, n) \ vec_trunc(sizeof (type), VEC_GV(type, vec), (n)) /*\ (VEC_LEN(type, vec)=VEC_LEN(type, vec) \ ? (type*)NULL \ : &VEC_ELTS(type, vec)[(size_t)(i)]) extern size_t vec_diffi(size_t, vec_type const*, vec_type const*); #define VEC_DIFFI(type, vec0, vec1) \ vec_diffi(sizeof (type), VEC_GV(type, vec0), VEC_GV(type, vec1)) #define VEC_EQ(type, vec0, vec1) \ (VEC_GV_LEN(type, vec0)==VEC_GV_LEN(type, vec1) && \ VEC_LEN(type, vec0)==VEC_DIFFI(type, vec0, vec1)) extern type_status vec_insn(size_t, vec_type*, size_t, void const*, size_t); #define VEC_INSN(type, vec, i, d, n) \ vec_insn(sizeof (type), VEC_GV(type, vec), (i), \ WARN_CAST(type const*, d), (n)) #define VEC_INSA(type, vec, i, arr, trim) \ /* XXX: check that arr is a (const or non-const) array, not a pointer */ \ VEC_INSN(type, vec, i, arr, \ sizeof (arr)/sizeof (type)-(WARN_CAST(type_bool, trim)!=0)) #define VEC_INS1(type, vec, i, value) \ (VEC_INSN(type, vec, i, (type*)NULL, 1)==0 \ ? ((void)(VEC_ELTS(type, vec)[(size_t)(i)]=(value)), 0) \ : -1) #define VEC_PUSHN(type, vec, d, n) \ VEC_INSN(type, vec, VEC_LEN(type, vec), d, n) #define VEC_PUSHA(type, vec, arr, trim) \ VEC_INSA(type, vec, VEC_LEN(type, vec), arr, trim) #define VEC_PUSH1(type, vec, value) \ (VEC_PUSHN(type, vec, (type*)NULL, 1)==0 \ ? ((void)(VEC_ELTS(type, vec)[VEC_LEN(type, vec)-1]=(value)), 0) \ : -1) #define VEC_UNSHIFTN(type, vec, d, n) VEC_INSN(type, vec, 0, d, n) #define VEC_UNSHIFTA(type, vec, arr, trim) VEC_INSA(type, vec, 0, arr, trim) #define VEC_UNSHIFT1(type, vec, value) VEC_INS1(type, vec, 0, value) extern type_status vec_cutn(size_t, vec_type*, size_t, void*, size_t); #define VEC_CUTN(type, vec, i, d, n) \ vec_cutn(sizeof (type), VEC_GV(type, vec), (i), WARN_CAST(type*, d), (n)) #define VEC_CUT1(type, vec, i, d) VEC_CUTN(type, vec, i, d, 1) #define VEC_POPN(type, vec, n) \ (VEC_LEN(type, vec)