aboutsummaryrefslogtreecommitdiffstats
path: root/src/vector.c
blob: babcd74b7f3c29a1d4a54a7b6132e24ae315ee1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "utility.h"
#include "vector.h"

#include <stdlib.h>
#include <stddef.h>
#include <string.h>

typedef struct{
    size_t size;
    uint   use_count;
    uint   mem_count;
    
    char   buf[];
} VectorHeader;

#define getHeader(X) ((VectorHeader*)(pCHAR(X)-offsetof(VectorHeader,buf)))
#define getTotal(X)  ((X)->size*(X)->mem_count+sizeof(VectorHeader))

void* ctl_vector_initX(void** ptr, size_t size, uint init_count){
    VectorHeader *tmp;
    
    int mem = 0;
    if(init_count >= 1)
        for(mem = 1; mem < init_count; mem *= 2);
    
    tmp = ctl_malloc(sizeof(VectorHeader) + (mem * size));
    
    tmp->size      = size;
    tmp->use_count = init_count;
    tmp->mem_count = mem;
    if(ptr != NULL){
        *ptr = pVOID(tmp->buf);
    }
    return pVOID(tmp->buf);
}

void* ctl_vector_freeX(void **ptr){
    free(pVOID(getHeader(*ptr)));
    return (*ptr = NULL);
}

int   ctl_vector_addBackX(void** ptr, void* entry){
    VectorHeader *tmp = getHeader(*ptr);
    
    if(tmp->use_count + 1 > tmp->mem_count){
        if(tmp->mem_count == 0) tmp->mem_count  = 1;
        else                    tmp->mem_count *= 2;
        tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp));
        *ptr = pVOID(tmp->buf);
    }
    memcpy(tmp->buf + tmp->size * tmp->use_count, entry, tmp->size);
    return ++tmp->use_count;
}
int   ctl_vector_delBackX(void** ptr){
    VectorHeader *tmp = getHeader(*ptr);
    
    if((tmp->use_count - 1) * 2 < tmp->mem_count){
        tmp->mem_count /= 2;
        tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp));
        *ptr = pVOID(tmp->buf);
    }
    
    return (--tmp->use_count);
}
int   ctl_vector_setSizeX(void** ptr, uint count){
    VectorHeader *tmp = getHeader(*ptr);
    
    int mem = 0;
    if(count >= 1)
        for(mem = 1; mem < count; mem *= 2);
    tmp->mem_count = mem;
    
    tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp));
    *ptr = pVOID(tmp->buf);
    return (tmp->use_count = count);
}
void* ctl_vector_setEntryX(void** ptr, uint index, void* data){
    VectorHeader *tmp = getHeader(*ptr);
    void* dst = pVOID(tmp->buf + tmp->size * index);
    memcpy(dst, data, tmp->size);
    return dst;
}

int   ctl_vector_getSizeX     (void** ptr){
    return getHeader(*ptr)->use_count;
}

void* ctl_vector_getEntryX    (void** ptr, uint index){
    VectorHeader *tmp = getHeader(*ptr);
    return pVOID(tmp->buf + tmp->size * index);
}

int   ctl_vector_getEntrySizeX(void** ptr){
    return getHeader(*ptr)->mem_count;
}