summaryrefslogtreecommitdiff
path: root/src/vec.h
blob: 2d5bd323ad1a8547001df6c0d1654665a1917f7c (plain)
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
#ifndef _VEC_H
#define _VEC_H

#define VEC(entry)                                                             \
  struct {                                                                     \
    entry *entries;                                                            \
    uint32_t nentries;                                                         \
    uint32_t capacity;                                                         \
  }

#define VEC_INIT(vec, initial_capacity)                                        \
  (vec)->entries = malloc(sizeof((vec)->entries[0]) * initial_capacity);       \
  (vec)->capacity = initial_capacity;                                          \
  (vec)->nentries = 0;

#define VEC_DESTROY(vec)                                                       \
  free((vec)->entries);                                                        \
  (vec)->entries = NULL;                                                       \
  (vec)->capacity = 0;                                                         \
  (vec)->nentries = 0;

#define VEC_GROW(vec, new_size)                                                \
  if (new_size > (vec)->capacity) {                                            \
    (vec)->capacity = new_size;                                                \
    (vec)->entries = realloc((vec)->entries,                                   \
                             (sizeof((vec)->entries[0]) * (vec)->capacity));   \
  }

#define VEC_PUSH(vec, entry)                                                   \
  if ((vec)->nentries + 1 >= (vec)->capacity) {                                \
    VEC_GROW(vec, (vec)->capacity * 2);                                        \
  }                                                                            \
                                                                               \
  (vec)->entries[(vec)->nentries] = entry;                                     \
  ++(vec)->nentries;

#define VEC_APPEND(vec, var)                                                   \
  if ((vec)->nentries + 1 >= (vec)->capacity) {                                \
    VEC_GROW(vec, (vec)->capacity * 2);                                        \
  }                                                                            \
                                                                               \
  var = &((vec)->entries[(vec)->nentries]);                                    \
  ++(vec)->nentries;

#define VEC_FOR_EACH(vec, var) VEC_FOR_EACH_INDEXED(vec, var, i)

#define VEC_FOR_EACH_INDEXED(vec, var, idx)                                    \
  for (uint32_t keep = 1, idx = 0, size = (vec)->nentries;                     \
       keep && idx != size; keep = !keep, idx++)                               \
    for (var = (vec)->entries + idx; keep; keep = !keep)

#define VEC_SIZE(vec) (vec)->nentries
#define VEC_CAPACITY(vec) (vec)->capacity
#define VEC_ENTRIES(vec) (vec)->entries
#define VEC_EMPTY(vec) ((vec)->nentries == 0)

#define VEC_CLEAR(vec) (vec)->nentries = 0
#define VEC_BACK(vec)                                                          \
  ((vec)->nentries > 0 ? &((vec)->entries[(vec)->nentries - 1]) : NULL)

#endif