18e3b1ab2SBaptiste Daroussin /* The MIT License 28e3b1ab2SBaptiste Daroussin 38e3b1ab2SBaptiste Daroussin Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk> 48e3b1ab2SBaptiste Daroussin 58e3b1ab2SBaptiste Daroussin Permission is hereby granted, free of charge, to any person obtaining 68e3b1ab2SBaptiste Daroussin a copy of this software and associated documentation files (the 78e3b1ab2SBaptiste Daroussin "Software"), to deal in the Software without restriction, including 88e3b1ab2SBaptiste Daroussin without limitation the rights to use, copy, modify, merge, publish, 98e3b1ab2SBaptiste Daroussin distribute, sublicense, and/or sell copies of the Software, and to 108e3b1ab2SBaptiste Daroussin permit persons to whom the Software is furnished to do so, subject to 118e3b1ab2SBaptiste Daroussin the following conditions: 128e3b1ab2SBaptiste Daroussin 138e3b1ab2SBaptiste Daroussin The above copyright notice and this permission notice shall be 148e3b1ab2SBaptiste Daroussin included in all copies or substantial portions of the Software. 158e3b1ab2SBaptiste Daroussin 168e3b1ab2SBaptiste Daroussin THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 178e3b1ab2SBaptiste Daroussin EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 188e3b1ab2SBaptiste Daroussin MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 198e3b1ab2SBaptiste Daroussin NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 208e3b1ab2SBaptiste Daroussin BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 218e3b1ab2SBaptiste Daroussin ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 228e3b1ab2SBaptiste Daroussin CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 238e3b1ab2SBaptiste Daroussin SOFTWARE. 248e3b1ab2SBaptiste Daroussin */ 258e3b1ab2SBaptiste Daroussin 268e3b1ab2SBaptiste Daroussin /* 278e3b1ab2SBaptiste Daroussin An example: 288e3b1ab2SBaptiste Daroussin 298e3b1ab2SBaptiste Daroussin #include "kvec.h" 308e3b1ab2SBaptiste Daroussin int main() { 318e3b1ab2SBaptiste Daroussin kvec_t(int) array; 328e3b1ab2SBaptiste Daroussin kv_init(array); 33*a0409676SBaptiste Daroussin kv_push_safe(int, array, 10, e0); // append 348e3b1ab2SBaptiste Daroussin kv_a(int, array, 20) = 5; // dynamic 358e3b1ab2SBaptiste Daroussin kv_A(array, 20) = 4; // static 368e3b1ab2SBaptiste Daroussin kv_destroy(array); 378e3b1ab2SBaptiste Daroussin return 0; 38*a0409676SBaptiste Daroussin e0: 39*a0409676SBaptiste Daroussin return 1; 408e3b1ab2SBaptiste Daroussin } 418e3b1ab2SBaptiste Daroussin */ 428e3b1ab2SBaptiste Daroussin 438e3b1ab2SBaptiste Daroussin /* 448e3b1ab2SBaptiste Daroussin 2008-09-22 (0.1.0): 458e3b1ab2SBaptiste Daroussin 468e3b1ab2SBaptiste Daroussin * The initial version. 478e3b1ab2SBaptiste Daroussin 488e3b1ab2SBaptiste Daroussin */ 498e3b1ab2SBaptiste Daroussin 508e3b1ab2SBaptiste Daroussin #ifndef AC_KVEC_H 518e3b1ab2SBaptiste Daroussin #define AC_KVEC_H 528e3b1ab2SBaptiste Daroussin 538e3b1ab2SBaptiste Daroussin #include <stdlib.h> 548e3b1ab2SBaptiste Daroussin 558e3b1ab2SBaptiste Daroussin #define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) 568e3b1ab2SBaptiste Daroussin 578e3b1ab2SBaptiste Daroussin #define kvec_t(type) struct { size_t n, m; type *a; } 588e3b1ab2SBaptiste Daroussin #define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) 598e3b1ab2SBaptiste Daroussin #define kv_destroy(v) free((v).a) 608e3b1ab2SBaptiste Daroussin #define kv_A(v, i) ((v).a[(i)]) 618e3b1ab2SBaptiste Daroussin #define kv_pop(v) ((v).a[--(v).n]) 628e3b1ab2SBaptiste Daroussin #define kv_size(v) ((v).n) 638e3b1ab2SBaptiste Daroussin #define kv_max(v) ((v).m) 648e3b1ab2SBaptiste Daroussin 65*a0409676SBaptiste Daroussin #define kv_resize_safe(type, v, s, el) do { \ 66*a0409676SBaptiste Daroussin type *_tp = (type*)realloc((v).a, sizeof(type) * (s)); \ 67*a0409676SBaptiste Daroussin if (_tp == NULL) { \ 68*a0409676SBaptiste Daroussin goto el; \ 69*a0409676SBaptiste Daroussin } else { \ 70*a0409676SBaptiste Daroussin (v).a = _tp; \ 71*a0409676SBaptiste Daroussin (v).m = (s); \ 72*a0409676SBaptiste Daroussin } \ 73*a0409676SBaptiste Daroussin } while (0) 74*a0409676SBaptiste Daroussin 758e3b1ab2SBaptiste Daroussin #define kv_grow_factor 1.5 76*a0409676SBaptiste Daroussin #define kv_grow_safe(type, v, el) do { \ 77*a0409676SBaptiste Daroussin size_t _ts = ((v).m > 1 ? (v).m * kv_grow_factor : 2); \ 78*a0409676SBaptiste Daroussin type *_tp = (type*)realloc((v).a, sizeof(type) * _ts); \ 79*a0409676SBaptiste Daroussin if (_tp == NULL) { \ 80*a0409676SBaptiste Daroussin goto el; \ 81*a0409676SBaptiste Daroussin } else { \ 82*a0409676SBaptiste Daroussin (v).a = _tp; \ 83*a0409676SBaptiste Daroussin (v).m = _ts; \ 84*a0409676SBaptiste Daroussin } \ 85*a0409676SBaptiste Daroussin } while (0) 86*a0409676SBaptiste Daroussin 87*a0409676SBaptiste Daroussin #define kv_copy_safe(type, v1, v0, el) do { \ 88*a0409676SBaptiste Daroussin if ((v1).m < (v0).n) kv_resize_safe(type, v1, (v0).n, el); \ 89*a0409676SBaptiste Daroussin (v1).n = (v0).n; \ 90*a0409676SBaptiste Daroussin memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ 91*a0409676SBaptiste Daroussin } while (0) 92*a0409676SBaptiste Daroussin 93*a0409676SBaptiste Daroussin #define kv_push_safe(type, v, x, el) do { \ 94*a0409676SBaptiste Daroussin if ((v).n == (v).m) { \ 95*a0409676SBaptiste Daroussin kv_grow_safe(type, v, el); \ 96*a0409676SBaptiste Daroussin } \ 97*a0409676SBaptiste Daroussin (v).a[(v).n++] = (x); \ 98*a0409676SBaptiste Daroussin } while (0) 99*a0409676SBaptiste Daroussin 100*a0409676SBaptiste Daroussin #define kv_prepend_safe(type, v, x, el) do { \ 101*a0409676SBaptiste Daroussin if ((v).n == (v).m) { \ 102*a0409676SBaptiste Daroussin kv_grow_safe(type, v, el); \ 103*a0409676SBaptiste Daroussin } \ 104*a0409676SBaptiste Daroussin memmove((v).a + 1, (v).a, sizeof(type) * (v).n); \ 105*a0409676SBaptiste Daroussin (v).a[0] = (x); \ 106*a0409676SBaptiste Daroussin (v).n ++; \ 107*a0409676SBaptiste Daroussin } while (0) 108*a0409676SBaptiste Daroussin 109*a0409676SBaptiste Daroussin #define kv_concat_safe(type, v1, v0, el) do { \ 110*a0409676SBaptiste Daroussin if ((v1).m < (v0).n + (v1).n) \ 111*a0409676SBaptiste Daroussin kv_resize_safe(type, v1, (v0).n + (v1).n, el); \ 112*a0409676SBaptiste Daroussin memcpy((v1).a + (v1).n, (v0).a, sizeof(type) * (v0).n); \ 113*a0409676SBaptiste Daroussin (v1).n = (v0).n + (v1).n; \ 114*a0409676SBaptiste Daroussin } while (0) 115*a0409676SBaptiste Daroussin 116*a0409676SBaptiste Daroussin #define kv_del(type, v, i) do { \ 117*a0409676SBaptiste Daroussin if ((i) < (v).n) { \ 118*a0409676SBaptiste Daroussin memmove((v).a + (i), (v).a + ((i) + 1), sizeof(type) * ((v).n - (i) - 1)); \ 119*a0409676SBaptiste Daroussin (v).n --; \ 120*a0409676SBaptiste Daroussin } \ 121*a0409676SBaptiste Daroussin } while (0) 122*a0409676SBaptiste Daroussin 123*a0409676SBaptiste Daroussin /* 124*a0409676SBaptiste Daroussin * Old (ENOMEM-unsafe) version of kv_xxx macros. Compat-only, not for use in 125*a0409676SBaptiste Daroussin * the new library code. 126*a0409676SBaptiste Daroussin */ 127*a0409676SBaptiste Daroussin 128*a0409676SBaptiste Daroussin #define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) 129*a0409676SBaptiste Daroussin 1308e3b1ab2SBaptiste Daroussin #define kv_grow(type, v) ((v).m = ((v).m > 1 ? (v).m * kv_grow_factor : 2), \ 1318e3b1ab2SBaptiste Daroussin (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) 1328e3b1ab2SBaptiste Daroussin 1338e3b1ab2SBaptiste Daroussin #define kv_copy(type, v1, v0) do { \ 1348e3b1ab2SBaptiste Daroussin if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ 1358e3b1ab2SBaptiste Daroussin (v1).n = (v0).n; \ 1368e3b1ab2SBaptiste Daroussin memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ 1378e3b1ab2SBaptiste Daroussin } while (0) \ 1388e3b1ab2SBaptiste Daroussin 1398e3b1ab2SBaptiste Daroussin #define kv_push(type, v, x) do { \ 1408e3b1ab2SBaptiste Daroussin if ((v).n == (v).m) { \ 1418e3b1ab2SBaptiste Daroussin kv_grow(type, v); \ 1428e3b1ab2SBaptiste Daroussin } \ 1438e3b1ab2SBaptiste Daroussin (v).a[(v).n++] = (x); \ 1448e3b1ab2SBaptiste Daroussin } while (0) 1458e3b1ab2SBaptiste Daroussin 1468e3b1ab2SBaptiste Daroussin #define kv_prepend(type, v, x) do { \ 1478e3b1ab2SBaptiste Daroussin if ((v).n == (v).m) { \ 1488e3b1ab2SBaptiste Daroussin kv_grow(type, v); \ 1498e3b1ab2SBaptiste Daroussin } \ 1508e3b1ab2SBaptiste Daroussin memmove((v).a + 1, (v).a, sizeof(type) * (v).n); \ 1518e3b1ab2SBaptiste Daroussin (v).a[0] = (x); \ 1528e3b1ab2SBaptiste Daroussin (v).n ++; \ 1538e3b1ab2SBaptiste Daroussin } while (0) 1548e3b1ab2SBaptiste Daroussin 1558e3b1ab2SBaptiste Daroussin #define kv_concat(type, v1, v0) do { \ 1568e3b1ab2SBaptiste Daroussin if ((v1).m < (v0).n + (v1).n) kv_resize(type, v1, (v0).n + (v1).n); \ 15739ee7a7aSBaptiste Daroussin memcpy((v1).a + (v1).n, (v0).a, sizeof(type) * (v0).n); \ 1588e3b1ab2SBaptiste Daroussin (v1).n = (v0).n + (v1).n; \ 1598e3b1ab2SBaptiste Daroussin } while (0) 1608e3b1ab2SBaptiste Daroussin 161*a0409676SBaptiste Daroussin #endif /* AC_KVEC_H */ 162