C 工具库4:变长数组(vector)

vector.h

#ifndef _VECTOR_H
#define _VECTOR_H

struct vector;


struct vector *vector_create(unsigned int val_size,unsigned int reserve_size);
struct vector *vector_copy_create(struct vector*);
void vector_copy(struct vector*,struct vector*);

void vector_reserve(struct vector*,unsigned int);

void vector_destroy(struct vector**);

unsigned int vector_size(struct vector*);
unsigned int vector_capability(struct vector*);
void vector_push_back(struct vector*,void*);

#ifndef VECTOR_PUSH_BACK
#define VECTOR_PUSH_BACK(TYPE,VECTOR,VAL)\
{TYPE val = VAL;vector_push_back(VECTOR,&val);}
#endif

void vector_get(struct vector*,unsigned int,void*);
void vector_set(struct vector*,unsigned int,void*);

void* vector_to_array(struct vector*);

#ifndef VECTOR_TO_ARRAY
#define VECTOR_TO_ARRAY(TYPE,VECTOR)\
({ TYPE *__result;\
do __result = (TYPE*)vector_to_array(VECTOR);\
while(0);\
__result;})
#endif

#ifndef VECTOR_GET
#define VECTOR_GET(TYPE,VECTOR,I)\
({ TYPE __result;\
do vector_get(VECTOR,I,&__result);\
while(0);\
__result;})
#endif

#ifndef VECTOR_SET
#define VECTOR_SET(TYPE,VECTOR,I,VAL)\
{TYPE val=VAL;vector_set(VECTOR,I,&val);}
#endif




#endif

vector.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "vector.h"

struct vector
{
unsigned int size;
unsigned int capability;
unsigned int val_size;
char *buf;
};

struct vector *vector_create(unsigned int val_size,unsigned int reserve_size)
{
struct vector *v = malloc(sizeof(*v));
if(v)
{
if(reserve_size)
{
v->buf = malloc(val_size*reserve_size);
if(!v->buf)
{
free(v);
return 0;
}
}
else
v->buf = 0;
v->size = v->capability = reserve_size;
v->val_size = val_size;

}
return v;
}

struct vector *vector_copy_create(struct vector *v)
{
assert(v);
if(!v->buf)
return vector_create(v->val_size,0);
struct vector *ret = malloc(sizeof(*v));
if(ret)
{
ret->buf = malloc(v->capability*v->val_size);
if(!ret->buf)
{
free(ret);
ret = 0;
}
else
{
ret->val_size = v->val_size;
ret->size = v->size;
ret->capability = v->capability;
memcpy(ret->buf,v->buf,v->val_size*v->size);
}
}
return ret;
}

void vector_copy(struct vector *v,struct vector *other)
{
assert(v);
assert(other);
if(!other->buf)
return;
if(v->val_size == other->val_size)
{
if(v->capability < other->capability)
{
unsigned int new_size = other->capability*other->val_size;
char *buf = realloc(v->buf,new_size);
if(!buf)
buf = malloc(new_size);
if(!buf)
return;
if(buf != v->buf)
{
free(v->buf);
v->buf = buf;
}
v->capability = other->capability;
}
memcpy(v->buf,other->buf,other->size*other->val_size);
v->size = other->size;
}
}

void vector_destroy(struct vector **v)
{
assert(v);
assert(*v);
if((*v)->buf)
free((*v)->buf);
free(*v);
*v = 0;
}

void vector_reserve(struct vector *v,unsigned int reserve_size)
{
assert(v);
if(v->capability > reserve_size)
{
//缩小容量的情况,不重新分配内存,仅仅将capality的值减小
v->capability = reserve_size;
if(v->size > reserve_size)
v->size = reserve_size;
}
else
{
//需要扩大内存
unsigned int new_size = v->val_size * reserve_size;
char *buf = realloc(v->buf,new_size);
if(!buf)
buf = malloc(new_size);
if(!buf)
return;

v->capability = reserve_size;
if(buf != v->buf)
{
memcpy(buf,v->buf,v->val_size*v->size);
free(v->buf);
v->buf = buf;
}
}
}

inline void *vector_get_addr_by_idx(struct vector *v,unsigned int idx)
{
return (void*)&v->buf[v->val_size*idx];
}

inline unsigned int vector_size(struct vector *v)
{
assert(v);
return v->size;
}

inline unsigned int vector_capability(struct vector *v)
{
assert(v);
return v->capability;
}

inline void* vector_to_array(struct vector *v)
{
assert(v);
return v->buf;
}

void vector_push_back(struct vector *v,void *val)
{
assert(v);
if(v->size == v->capability)
{
//扩展空间
unsigned int new_size = v->capability > 0 ? 2*(v->capability) : 32;
unsigned int capability = new_size;
new_size *= v->val_size;
char *buf = realloc(v->buf,new_size);
if(!buf)
buf = malloc(new_size);
if(!buf)
return;
if(buf != v->buf)
{
memcpy(buf,v->buf,v->val_size*v->capability);
free(v->buf);
v->buf = buf;
}
v->capability = capability;
}
memcpy(vector_get_addr_by_idx(v,v->size),val,v->val_size);
++v->size;
}


void vector_get(struct vector *v,unsigned int idx,void *val)
{
assert(v);
if(v->buf && idx < v->capability)
{
memcpy(val,vector_get_addr_by_idx(v,idx),v->val_size);
}
}

void vector_set(struct vector *v,unsigned int idx,void *val)
{
assert(v);
if(v->buf && idx < v->capability)
{
memcpy(vector_get_addr_by_idx(v,idx),val,v->val_size);
}
}

test.c

#include <stdio.h>
#include "vector.h"

int main()
{
struct vector *v = vector_create(sizeof(int),64);
int i;
for(i = 0; i < 64; ++i)
VECTOR_SET(int,v,i,i);

vector_reserve(v,32);
VECTOR_PUSH_BACK(int,v,33);
VECTOR_PUSH_BACK(int,v,34);

//VECTOR_PUSH_BACK(int,v,i);






//struct vector *other = vector_copy_create(v);
//vector_copy(other,v);
//printf("h");

int *a = VECTOR_TO_ARRAY(int,v);
for(i = 0; i < vector_size(v); ++i)
printf("%d\n",a[i]);

printf("capability :%d\n",vector_capability(v));
return 0;

}





posted @ 2012-04-02 09:03  sniperHW  阅读(1288)  评论(0编辑  收藏  举报