void* _vector_pop(vector_t* v) { if(v->length==0)return NULL; void* value=v->data+v->element_size*(v->length-1); v->length--; if(v->size>2 && v->length<v->size/2)_vector_resize(v,v->length+v->length/2); // value should still be allocated return value; }
void vector_append(vector_t* v,vector_t* u) { #ifdef DEBUG if(v->element_size!=u->element_size)warn("vector_append(%p,%p), different element size (%zd!=%zd)",v,u,v->element_size,u->element_size); #endif if(v->length+u->length>=v->size)_vector_resize(v,(v->length+u->length)*VECTOR_RESIZE_FACTOR+1); memmove(v->data+v->element_size*v->length,u->data,v->element_size*(u->length)); v->length+=u->length; }
void @TYPE@_vector_buffer_fread(@TYPE@_vector_type * vector , buffer_type * buffer) { @TYPE@ default_value; int size = buffer_fread_int( buffer ); buffer_fread( buffer , &default_value , sizeof default_value , 1 ); @TYPE@_vector_set_default( vector , default_value ); @TYPE@_vector_resize( vector , size ); buffer_fread( buffer , vector->data , sizeof * vector->data , size ); vector->size = size; }
void* _vector_remove_element(vector_t* v, size_t index) { #ifdef DEBUG if(index>=v->length) warn("vector_remove_element(%zd), out-of-bounds, index>=%zd", index, v->length); #endif void* element=v->data+index*v->element_size; if(index!=v->length-1) memmove(v->data+index*v->element_size,v->data+(index+1)*v->element_size,v->element_size*(v->length-index-1)); v->length--; if(v->size>2 && v->length<v->size/2)_vector_resize(v,v->length+v->length/2); return element; }
void vector_remove(vector_t* v, size_t from, size_t to) { if(from<0)from=0; if(to>v->length)to=v->length; if(to<=from)return; if(to!=v->length) { memmove(v->data+v->element_size*from,v->data+v->element_size*to,v->element_size*(to-from)); } v->length-=to-from; if(v->length<v->size/2)_vector_resize(v,v->length+v->length/2); }
void _vector_insert_element(vector_t* v, int index, void* value) { if(index<0) _vector_unshift(v, value); else if(index>=v->length) _vector_push(v, value); else { if(v->length>=v->size) _vector_resize(v,v->size*VECTOR_RESIZE_FACTOR+1); memmove(v->data+v->element_size*(index+1),v->data+v->element_size*index,v->element_size*(v->length-index-1)); v->length++; memcpy(v->data+v->element_size*index,value,v->element_size); } }
void _vector_push(vector_t* v, void* data) { if(v->length>=v->size) { int newSize=v->size*VECTOR_RESIZE_FACTOR+1; #ifdef VECTOR_RESIZE_LIMIT if((newSize*v->element_size)/VECTOR_RESIZE_LIMIT>=(v->element_size*v->size)/VECTOR_RESIZE_LIMIT+1) newSize = (((v->element_size*v->size)/VECTOR_RESIZE_LIMIT+1)*VECTOR_RESIZE_LIMIT)/v->element_size; #endif _vector_resize(v,newSize); //_vector_resize(v,v->size*VECTOR_RESIZE_FACTOR+1); } memcpy(v->data+v->length*v->element_size,data,v->element_size); v->length++; }
vector_t* _vector_new(size_t initialSize, size_t element_size) { vector_t* v=MALLOC(sizeof(vector_t)); if(v==NULL)return NULL; v->data=NULL;//MALLOC(v->element_size*initialSize); v->size=0; v->element_size=element_size; v->length=0; _vector_resize(v,initialSize); if(v->data==NULL) { FREE(v); return NULL; } return v; }
void vector_insert(vector_t* v, size_t index, vector_t* peer) { #ifdef DEBUG if(v->element_size!=peer->element_size)warn("vector_insert(%p,%zd,%p), different element size (%zd!=%zd)",v,index,peer, v->element_size,peer->element_size); #endif if(index<0) vector_prepend(v, peer); else if(index>=v->length) vector_append(v, peer); else { if(v->length+peer->length>=v->size) { _vector_resize(v,v->size+peer->size*VECTOR_RESIZE_FACTOR+1); } memmove(v->data+v->element_size*(index+peer->length),v->data+v->element_size*(index),v->element_size*(v->length-index-1)); v->length+=peer->length; memcpy(v->data+v->element_size*index,peer->data,peer->length*v->element_size); } }
void vector_optimize(vector_t* v) { _vector_resize(v,v->length); }