-
Notifications
You must be signed in to change notification settings - Fork 1
/
dodvec.h
160 lines (143 loc) · 5.74 KB
/
dodvec.h
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#ifndef DOD_VECT_H
#define DOD_VECT_H
#include "dodbytes.h"
// Constructor and destructor
#define dodvec_new(t, n) dodvec_newl(sizeof(t), n)
#define dodvec_free(v) \
do { \
if ((v) != NULL) \
dodbytes_free((v)->b); \
free(v); \
} while (0)
#define dodvec_find(v, val) dodvec_findl(v, val, (v)->szmem)
// Iterators
#define dodvec_begin(v) dodvec_data(v)
#define dodvec_end(v) (((v)->l == 0) ? dodvec_begin(v) : (dodvec_data(v) + ((v)->l * (v)->szmem)))
// capacity
#define dodvec_size(v) ((v)->l)
#define dodvec_max_size(v) (SIZE_MAX / (v)->szmem)
#define dodvec_capacity(v) (dodbytes_capacity((v)->b) / (v)->szmem)
#define dodvec_empty(v) ((v)->l == 0)
#define dodvec_reserve(v, n) dodbytes_reserve(&(v)->b, (n) * (v)->szmem)
#define dodvec_shrink_to_fit(v) \
dodbytes_shrink(&(v)->b, (v)->l *(v)->szmem)
// Element access
#define dodvec_data(v) dodbytes_data((v)->b)
#define dodvec_at(v, pos) (dodvec_data(v) + (pos * (v)->szmem))
#define dodvec_front(v) dodvec_begin(v)
#define dodvec_back(v) (dodvec_end(v) == dodvec_begin(v) ? dodvec_front(v) : (dodvec_end(v) - (v)->szmem))
// Modifiers
#define dodvec_push_back(v, val) dodvec_push_backl(v, val, (v)->szmem)
#define dodvec_pop_back(v) \
do { \
if ((v)->l) { \
(v)->l--; \
(v)->b->sz -= (v)->szmem; \
} \
} while (0)
#define dodvec_swap(v1, v2) \
do { \
dodbytes_t *_b_ = (v1)->b; \
size_t _l_ = (v1)->l; \
size_t _szmem_ = (v1)->szmem; \
(v1)->b = (v2)->b; \
(v1)->l = (v2)->l; \
(v1)->szmem = (v2)->szmem; \
(v2)->b = _b_; \
(v2)->l = _l_; \
(v2)->szmem = _szmem_; \
} while (0)
#define dodvec_clear(v) \
do { \
(v)->l = 0; \
dodbytes_clear((v)->b); \
} while (0)
typedef struct {
dodbytes_t *b;
size_t l;
size_t szmem;
} dodvec_t;
static inline dodvec_t *dodvec_newl(size_t tsz, size_t n) {
dodvec_t *v = malloc(sizeof(*v));
if (v) {
v->b = dodbytes_new(tsz * n);
if (!v->b) {
free(v);
return NULL;
}
v->l = 0;
v->szmem = tsz;
}
return v;
}
static inline dodret_t dodvec_push_backl(dodvec_t *v, const void *val, size_t l) {
v->l++;
return dodbytes_writel_(&v->b, val, l);
}
static inline size_t dodvec_findl(const dodvec_t *v, const void *val, size_t l) {
for (size_t i = 0; i < v->l; i++)
if (!memcmp(dodvec_data(v) + (i * l), val, l))
return i;
return v->l + 1;
}
static inline dodret_t dodvec_erase(dodvec_t *v, size_t pos) {
if (!v->l || pos >= dodbytes_size(v->b))
return DODRET_EPARAM;
size_t li = dodbytes_size(v->b) - v->szmem;
memmove(dodvec_data(v) + (pos * v->szmem),
dodvec_data(v) + (pos * v->szmem) + v->szmem, li);
v->l--;
dodbytes_set_size(v->b, dodbytes_size(v->b) - v->szmem);
return DODRET_OK;
}
static inline dodret_t dodvec_resize(dodvec_t *v, size_t nsz, const void *val) {
if (nsz == v->l) {
return DODRET_OK;
} else if (nsz > v->l) {
size_t dl = nsz - v->l;
while (dl--)
if (dodvec_push_back(v, val) < 0)
return DODRET_ENOMEM;
} else {
while (nsz--)
dodvec_pop_back(v);
}
return DODRET_OK;
}
static inline dodret_t dodvec_assign_range(dodvec_t *v, const void *start,
const void *end) {
if (!start || !end || (start > end))
return DODRET_EPARAM;
dodvec_clear(v);
uintptr_t p = (uintptr_t) start;
while (p < (uintptr_t) end) {
if (dodvec_push_backl(v, (void *) p, v->szmem) < 0)
return DODRET_ENOMEM;
p += v->szmem;
}
return DODRET_OK;
}
static inline dodret_t dodvec_assign_fill(dodvec_t *v, size_t n, const void *val) {
dodvec_clear(v);
while (n--)
if (dodvec_push_backl(v, val, v->szmem) < 0)
return DODRET_ENOMEM;
return DODRET_OK;
}
static inline dodret_t dodvec_insert_range(dodvec_t *v, const void *pos,
const void *start, const void *end) {
size_t l = ((uintptr_t) end - (uintptr_t) start) / v->szmem;
dodret_t r = dodbytes_write_range_atl_(&v->b, pos, start, end);
if (r < 0)
return r;
v->l += l;
return DODRET_OK;
}
static inline dodret_t dodvec_insert(dodvec_t *v, const void *pos,
const void *val) {
if (dodbytes_write_atl_(&v->b, pos, val, v->szmem) < 0)
return DODRET_ENOMEM;
v->l++;
return DODRET_OK;
}
#endif // DOD_VECT_H