YAP
7.1.0
utarray.h
1
/*
2
Copyright (c) 2008-2013, Troy D. Hanson http://uthash.sourceforge.net
3
All rights reserved.
4
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions are met:
7
8
* Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
10
11
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
12
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
15
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
*/
23
24
/* a dynamic array implementation using macros
25
* see http://uthash.sourceforge.net/utarray
26
*/
27
#ifndef UTARRAY_H
28
#define UTARRAY_H
29
30
#define UTARRAY_VERSION 1.9.7
31
32
#ifdef __GNUC__
33
#define _UNUSED_ __attribute__ ((__unused__))
34
#else
35
#define _UNUSED_
36
#endif
37
38
#include <stddef.h>
/* size_t */
39
#include <string.h>
/* memset, etc */
40
#include <stdlib.h>
/* exit */
41
42
#define oom() exit(-1)
43
44
typedef
void (ctor_f)(
void
*dst,
const
void
*src);
45
typedef
void (dtor_f)(
void
*elt);
46
typedef
void (init_f)(
void
*elt);
47
typedef
struct
{
48
size_t
sz;
49
init_f *init;
50
ctor_f *copy;
51
dtor_f *dtor;
52
}
UT_icd
;
53
54
typedef
struct
{
55
unsigned
i,n;
/* i: index of next available slot, n: num slots */
56
UT_icd
icd;
/* initializer, copy and destructor functions */
57
char
*d;
/* n slots of size icd->sz*/
58
}
UT_array
;
59
60
#define utarray_init(a,_icd) do { \
61
memset(a,0,sizeof(UT_array)); \
62
(a)->icd=*_icd; \
63
} while(0)
64
65
#define utarray_done(a) do { \
66
if ((a)->n) { \
67
if ((a)->icd.dtor) { \
68
size_t _ut_i; \
69
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
70
(a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
71
} \
72
} \
73
free((a)->d); \
74
} \
75
(a)->n=0; \
76
} while(0)
77
78
#define utarray_new(a,_icd) do { \
79
a=(UT_array*)malloc(sizeof(UT_array)); \
80
utarray_init(a,_icd); \
81
} while(0)
82
83
#define utarray_free(a) do { \
84
utarray_done(a); \
85
free(a); \
86
} while(0)
87
88
#define utarray_reserve(a,by) do { \
89
if (((a)->i+by) > ((a)->n)) { \
90
while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \
91
if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd.sz)) == NULL) oom(); \
92
} \
93
} while(0)
94
95
#define utarray_push_back(a,p) do { \
96
utarray_reserve(a,1); \
97
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \
98
else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \
99
} while(0)
100
101
#define utarray_pop_back(a) do { \
102
if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \
103
else { (a)->i--; } \
104
} while(0)
105
106
#define utarray_extend_back(a) do { \
107
utarray_reserve(a,1); \
108
if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \
109
else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \
110
(a)->i++; \
111
} while(0)
112
113
#define utarray_len(a) ((a)->i)
114
115
#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
116
#define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd.sz*(j) )))
117
118
#define utarray_insert(a,p,j) do { \
119
utarray_reserve(a,1); \
120
if (j > (a)->i) break; \
121
if ((j) < (a)->i) { \
122
memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \
123
((a)->i - (j))*((a)->icd.sz)); \
124
} \
125
if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \
126
else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \
127
(a)->i++; \
128
} while(0)
129
130
#define utarray_inserta(a,w,j) do { \
131
if (utarray_len(w) == 0) break; \
132
if (j > (a)->i) break; \
133
utarray_reserve(a,utarray_len(w)); \
134
if ((j) < (a)->i) { \
135
memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \
136
_utarray_eltptr(a,j), \
137
((a)->i - (j))*((a)->icd.sz)); \
138
} \
139
if ((a)->icd.copy) { \
140
size_t _ut_i; \
141
for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \
142
(a)->icd.copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i)); \
143
} \
144
} else { \
145
memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \
146
utarray_len(w)*((a)->icd.sz)); \
147
} \
148
(a)->i += utarray_len(w); \
149
} while(0)
150
151
#define utarray_resize(dst,num) do { \
152
size_t _ut_i; \
153
if (dst->i > (size_t)(num)) { \
154
if ((dst)->icd.dtor) { \
155
for(_ut_i=num; _ut_i < dst->i; _ut_i++) { \
156
(dst)->icd.dtor(utarray_eltptr(dst,_ut_i)); \
157
} \
158
} \
159
} else if (dst->i < (size_t)(num)) { \
160
utarray_reserve(dst,num-dst->i); \
161
if ((dst)->icd.init) { \
162
for(_ut_i=dst->i; _ut_i < num; _ut_i++) { \
163
(dst)->icd.init(utarray_eltptr(dst,_ut_i)); \
164
} \
165
} else { \
166
memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd.sz*(num-dst->i)); \
167
} \
168
} \
169
dst->i = num; \
170
} while(0)
171
172
#define utarray_concat(dst,src) do { \
173
utarray_inserta((dst),(src),utarray_len(dst)); \
174
} while(0)
175
176
#define utarray_erase(a,pos,len) do { \
177
if ((a)->icd.dtor) { \
178
size_t _ut_i; \
179
for(_ut_i=0; _ut_i < len; _ut_i++) { \
180
(a)->icd.dtor(utarray_eltptr((a),pos+_ut_i)); \
181
} \
182
} \
183
if ((a)->i > (pos+len)) { \
184
memmove( _utarray_eltptr((a),pos), _utarray_eltptr((a),pos+len), \
185
(((a)->i)-(pos+len))*((a)->icd.sz)); \
186
} \
187
(a)->i -= (len); \
188
} while(0)
189
190
#define utarray_renew(a,u) do { \
191
if (a) utarray_clear(a); \
192
else utarray_new((a),(u)); \
193
} while(0)
194
195
#define utarray_clear(a) do { \
196
if ((a)->i > 0) { \
197
if ((a)->icd.dtor) { \
198
size_t _ut_i; \
199
for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \
200
(a)->icd.dtor(utarray_eltptr(a,_ut_i)); \
201
} \
202
} \
203
(a)->i = 0; \
204
} \
205
} while(0)
206
207
#define utarray_sort(a,cmp) do { \
208
qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
209
} while(0)
210
211
#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
212
213
#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
214
#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL))
215
#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
216
#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
217
#define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (((char*)(e) - (char*)((a)->d))/(a)->icd.sz) : -1)
218
219
/* last we pre-define a few icd for common utarrays of ints and strings */
220
static
void
utarray_str_cpy(
void
*dst,
const
void
*src) {
221
char
**_src = (
char
**)src, **_dst = (
char
**)dst;
222
*_dst = (*_src == NULL) ? NULL : strdup(*_src);
223
}
224
static
void
utarray_str_dtor(
void
*elt) {
225
char
**eltc = (
char
**)elt;
226
if
(*eltc) free(*eltc);
227
}
228
static
const
UT_icd
ut_str_icd _UNUSED_ = {
sizeof
(
char
*),NULL,utarray_str_cpy,utarray_str_dtor};
229
static
const
UT_icd
ut_int_icd _UNUSED_ = {
sizeof
(int),NULL,NULL,NULL};
230
static
const
UT_icd
ut_ptr_icd _UNUSED_ = {
sizeof
(
void
*),NULL,NULL,NULL};
231
232
233
#endif
/* UTARRAY_H */
UT_array
Definition:
utarray.h:54
UT_icd
Definition:
utarray.h:47
H
utarray.h
Generated by
1.9.3