]>
diplodocus.org Git - nmh/blob - sbr/vector.c
2 * vector.c -- dynamically sized vectors
4 * This code is Copyright (c) 2013, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
10 * This file defines several kinds of vectors:
12 * svector: vector of char arrays
13 * ivector: vector of ints
15 * The interfaces provide only the capabilities needed by nmh. The
16 * implementations rely on dynamic allocation, so that a vector
17 * can be as large as needed, as long as it fits in (virtual) memory.
23 #define VEC_INIT_SIZE 256
26 * These try to hide the type of the "bits" member of bvector. But if
27 * that is changed to a type that's wider than unsigned long, the 1ul
28 * constants in the code below must also be changed to a 1 that's at
29 * least as wide as the new type.
34 #define BVEC_WORD(vec, max) ((max) / (sizeof *vec->bits * Nbby))
35 #define BVEC_OFFSET(vec, max) ((max) % (sizeof *vec->bits * Nbby))
36 #define BVEC_BYTES(vec, n) \
37 ((BVEC_WORD (vec, n) + (BVEC_OFFSET (vec, n) == 0 ? 0 : 1)) * \
45 static void bvector_resize (bvector_t
, size_t);
48 bvector_create (size_t init_size
) {
49 bvector_t vec
= mh_xmalloc (sizeof *vec
);
50 size_t bytes
= BVEC_BYTES (vec
, init_size
? init_size
: VEC_INIT_SIZE
);
52 vec
->bits
= mh_xmalloc (bytes
);
53 memset (vec
->bits
, 0, bytes
);
54 vec
->maxsize
= bytes
* Nbby
;
60 bvector_copy (bvector_t dest
, bvector_t src
) {
61 size_t bytes
= BVEC_BYTES (dest
, src
->maxsize
);
64 dest
->bits
= mh_xmalloc (bytes
);
65 memcpy (dest
->bits
, src
->bits
, bytes
);
66 dest
->maxsize
= src
->maxsize
;
70 bvector_free (bvector_t vec
) {
76 bvector_clear (bvector_t vec
, size_t n
) {
77 size_t word
= BVEC_WORD (vec
,n
);
78 size_t offset
= BVEC_OFFSET (vec
, n
);
80 if (n
>= vec
->maxsize
) bvector_resize (vec
, n
);
82 assert (sizeof *vec
->bits
<= sizeof 1ul);
83 vec
->bits
[word
] &= ~(1ul << offset
);
88 bvector_clear_all (bvector_t vec
) {
89 memset (vec
->bits
, 0, BVEC_BYTES (vec
, vec
->maxsize
));
94 bvector_set (bvector_t vec
, size_t n
) {
95 size_t word
= BVEC_WORD (vec
, n
);
96 size_t offset
= BVEC_OFFSET (vec
, n
);
98 if (n
>= vec
->maxsize
) bvector_resize (vec
, n
);
99 assert (sizeof *vec
->bits
<= sizeof 1ul);
100 vec
->bits
[word
] |= 1ul << offset
;
104 bvector_at (bvector_t vec
, size_t i
) {
105 size_t word
= BVEC_WORD (vec
, i
);
106 size_t offset
= BVEC_OFFSET (vec
, i
);
108 assert (sizeof *vec
->bits
<= sizeof 1ul);
109 return i
< vec
->maxsize
110 ? (vec
->bits
[word
] & (1ul << offset
) ? 1 : 0)
115 bvector_resize (bvector_t vec
, size_t maxsize
) {
116 size_t old_maxsize
= vec
->maxsize
;
120 while ((vec
->maxsize
*= 2) < maxsize
) continue;
121 bytes
= BVEC_BYTES (vec
, vec
->maxsize
);
122 vec
->bits
= mh_xrealloc (vec
->bits
, bytes
);
123 for (i
= old_maxsize
; i
< vec
->maxsize
; ++i
) bvector_clear (vec
, i
);
126 const unsigned long *
127 bvector_bits (bvector_t vec
) {
132 bvector_maxsize (bvector_t vec
) {
143 static void svector_resize (svector_t
, size_t);
146 svector_create (size_t init_size
) {
147 svector_t vec
= mh_xmalloc (sizeof *vec
);
150 vec
->maxsize
= init_size
? init_size
: VEC_INIT_SIZE
;
151 bytes
= vec
->maxsize
* sizeof (char *);
152 vec
->strs
= mh_xmalloc (bytes
);
153 memset (vec
->strs
, 0, bytes
);
160 svector_free (svector_t vec
) {
166 svector_push_back (svector_t vec
, char *s
) {
167 if (++vec
->size
>= vec
->maxsize
) svector_resize (vec
, vec
->size
);
168 return vec
->strs
[vec
->size
-1] = s
;
172 svector_at (svector_t vec
, size_t i
) {
173 if (i
>= vec
->maxsize
) svector_resize (vec
, i
);
178 * Return address of first element that stringwise matches s.
179 * The caller can replace the contents of the return address.
182 svector_find (svector_t vec
, const char *s
) {
184 char **str
= vec
->strs
;
186 for (i
= 0; i
< vec
->size
; ++i
, ++str
) {
187 if (*str
&& ! strcmp(*str
, s
)) {
196 svector_strs (svector_t vec
) {
201 svector_size (svector_t vec
) {
206 svector_resize (svector_t vec
, size_t maxsize
) {
207 size_t old_maxsize
= vec
->maxsize
;
210 while ((vec
->maxsize
*= 2) < maxsize
) continue;
211 vec
->strs
= mh_xrealloc (vec
->strs
, vec
->maxsize
* sizeof (char *));
212 for (i
= old_maxsize
; i
< vec
->maxsize
; ++i
) vec
->strs
[i
] = NULL
;
222 static void ivector_resize (ivector_t
, size_t);
225 ivector_create (size_t init_size
) {
226 ivector_t vec
= mh_xmalloc (sizeof *vec
);
229 vec
->maxsize
= init_size
? init_size
: VEC_INIT_SIZE
;
230 bytes
= vec
->maxsize
* sizeof (int);
231 vec
->ints
= mh_xmalloc (bytes
);
232 memset (vec
->ints
, 0, bytes
);
239 ivector_free (ivector_t vec
) {
245 ivector_push_back (ivector_t vec
, int n
) {
246 if (++vec
->size
>= vec
->maxsize
) ivector_resize (vec
, vec
->size
);
247 return vec
->ints
[vec
->size
-1] = n
;
251 ivector_at (ivector_t vec
, size_t i
) {
252 if (i
>= vec
->maxsize
) ivector_resize (vec
, i
);
257 ivector_atp (ivector_t vec
, size_t i
) {
258 if (i
>= vec
->maxsize
) ivector_resize (vec
, i
);
259 return &vec
->ints
[i
];
263 ivector_size (ivector_t vec
) {
268 ivector_resize (ivector_t vec
, size_t maxsize
) {
269 size_t old_maxsize
= vec
->maxsize
;
272 while ((vec
->maxsize
*= 2) < maxsize
) continue;
273 vec
->ints
= mh_xrealloc (vec
->ints
, vec
->maxsize
* sizeof (int));
274 for (i
= old_maxsize
; i
< vec
->maxsize
; ++i
) vec
->ints
[i
] = 0;