1279546Sbapt/* The MIT License
2279546Sbapt
3279546Sbapt   Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
4279546Sbapt
5279546Sbapt   Permission is hereby granted, free of charge, to any person obtaining
6279546Sbapt   a copy of this software and associated documentation files (the
7279546Sbapt   "Software"), to deal in the Software without restriction, including
8279546Sbapt   without limitation the rights to use, copy, modify, merge, publish,
9279546Sbapt   distribute, sublicense, and/or sell copies of the Software, and to
10279546Sbapt   permit persons to whom the Software is furnished to do so, subject to
11279546Sbapt   the following conditions:
12279546Sbapt
13279546Sbapt   The above copyright notice and this permission notice shall be
14279546Sbapt   included in all copies or substantial portions of the Software.
15279546Sbapt
16279546Sbapt   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17279546Sbapt   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18279546Sbapt   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19279546Sbapt   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20279546Sbapt   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21279546Sbapt   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22279546Sbapt   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23279546Sbapt   SOFTWARE.
24279546Sbapt*/
25279546Sbapt
26279546Sbapt/*
27279546Sbapt  An example:
28279546Sbapt
29279546Sbapt#include "kvec.h"
30279546Sbaptint main() {
31279546Sbapt	kvec_t(int) array;
32279546Sbapt	kv_init(array);
33279546Sbapt	kv_push(int, array, 10); // append
34279546Sbapt	kv_a(int, array, 20) = 5; // dynamic
35279546Sbapt	kv_A(array, 20) = 4; // static
36279546Sbapt	kv_destroy(array);
37279546Sbapt	return 0;
38279546Sbapt}
39279546Sbapt*/
40279546Sbapt
41279546Sbapt/*
42279546Sbapt  2008-09-22 (0.1.0):
43279546Sbapt
44279546Sbapt	* The initial version.
45279546Sbapt
46279546Sbapt*/
47279546Sbapt
48279546Sbapt#ifndef AC_KVEC_H
49279546Sbapt#define AC_KVEC_H
50279546Sbapt
51279546Sbapt#include <stdlib.h>
52279546Sbapt
53279546Sbapt#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
54279546Sbapt
55279546Sbapt#define kvec_t(type) struct { size_t n, m; type *a; }
56279546Sbapt#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
57279546Sbapt#define kv_destroy(v) free((v).a)
58279546Sbapt#define kv_A(v, i) ((v).a[(i)])
59279546Sbapt#define kv_pop(v) ((v).a[--(v).n])
60279546Sbapt#define kv_size(v) ((v).n)
61279546Sbapt#define kv_max(v) ((v).m)
62279546Sbapt
63279546Sbapt#define kv_resize(type, v, s)  ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m))
64279546Sbapt#define kv_grow_factor 1.5
65279546Sbapt#define kv_grow(type, v)  ((v).m = ((v).m > 1 ? (v).m * kv_grow_factor : 2), \
66279546Sbapt		(v).a = (type*)realloc((v).a, sizeof(type) * (v).m))
67279546Sbapt
68279546Sbapt#define kv_copy(type, v1, v0) do {											\
69279546Sbapt		if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n);					\
70279546Sbapt		(v1).n = (v0).n;													\
71279546Sbapt		memcpy((v1).a, (v0).a, sizeof(type) * (v0).n);						\
72279546Sbapt	} while (0)																\
73279546Sbapt
74279546Sbapt#define kv_push(type, v, x) do {											\
75279546Sbapt		if ((v).n == (v).m) {												\
76279546Sbapt			kv_grow(type, v);												\
77279546Sbapt		}																	\
78279546Sbapt		(v).a[(v).n++] = (x);												\
79279546Sbapt	} while (0)
80279546Sbapt
81279546Sbapt#define kv_prepend(type, v, x) do {											\
82279546Sbapt	if ((v).n == (v).m) {													\
83279546Sbapt		kv_grow(type, v);													\
84279546Sbapt	}																		\
85279546Sbapt	memmove((v).a + 1, (v).a, sizeof(type) * (v).n);							\
86279546Sbapt	(v).a[0] = (x);															\
87279546Sbapt	(v).n ++;																\
88279546Sbapt} while (0)
89279546Sbapt
90279546Sbapt#define kv_concat(type, v1, v0) do {										\
91279546Sbapt	if ((v1).m < (v0).n + (v1).n) kv_resize(type, v1, (v0).n + (v1).n);		\
92290071Sbapt		memcpy((v1).a + (v1).n, (v0).a, sizeof(type) * (v0).n);	\
93279546Sbapt		(v1).n = (v0).n + (v1).n;											\
94279546Sbapt	} while (0)
95279546Sbapt
96279546Sbapt#define kv_del(type, v, i) do {												\
97279546Sbapt	if ((i) < (v).n) {														\
98279546Sbapt		memmove((v).a + (i), (v).a + ((i) + 1), sizeof(type) * ((v).n - (i) - 1)); \
99279546Sbapt		(v).n --;															\
100279546Sbapt	}																		\
101279546Sbapt} while (0)
102279546Sbapt
103279546Sbapt#endif
104