summaryrefslogtreecommitdiff
path: root/src/vec.cc
blob: d43bc52baf7d21657a81a4acb127d1fc5c9df086 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "vec.h"
#include "utils.h"
#include <cstring>
#include <mimalloc.h>

static inline usize wayc_raw_vec_next_cap(usize curr_cap, usize grow_to) {
  if (curr_cap == 0)
    return WAYC_VEC_INITIAL;

  usize next_cap = curr_cap * WAYC_VEC_GROWTH;
  if (next_cap < grow_to)
    return grow_to;

  return next_cap;
}

static inline bool wayc_raw_vec_needs_grow(raw_vec_s *vec) {
  wayc_notnull(vec);
  wayc_assert(vec->len <= vec->cap);
  return vec->len == vec->cap;
}

static inline usize wayc_raw_vec_bytes(usize size, usize value) {
  return value * size;
}

static inline u8 *wayc_raw_vec_at(raw_vec_s *vec, usize index) {
  wayc_notnull(vec);
  u8 *at = vec->ptr + wayc_raw_vec_bytes(vec->size, index);
  return at;
}

static void wayc_raw_vec_grow(raw_vec_s *vec, usize grow_to) {
  wayc_notnull(vec);
  wayc_assert(wayc_raw_vec_needs_grow(vec));

  usize curr_bytes = wayc_raw_vec_bytes(vec->size, vec->cap);
  usize next_cap = wayc_raw_vec_next_cap(vec->cap, grow_to);
  usize next_bytes = wayc_raw_vec_bytes(vec->size, next_cap);

  u8 *next_ptr = (u8 *)mi_malloc(next_bytes);
  memcpy(next_ptr, vec->ptr, curr_bytes);
  mi_free(vec->ptr);

  vec->ptr = next_ptr;
  vec->cap = next_cap;
}

void wayc_raw_vec_push(raw_vec_s *vec, const u8 *at) {
  wayc_notnull(vec);
  wayc_notnull(at);

  if (wayc_raw_vec_needs_grow(vec))
    wayc_raw_vec_grow(vec, vec->len + 1);

  u8 *dst = wayc_raw_vec_at(vec, vec->len);
  memcpy(dst, at, vec->size);
  vec->len++;
}

bool wayc_raw_vec_pop(raw_vec_s *vec, u8 *out) {
  wayc_notnull(vec);
  wayc_notnull(out);

  if (vec->len == 0)
    return false;

  u8 *at = wayc_raw_vec_at(vec, vec->len - 1);
  memcpy(out, at, vec->size);
  vec->len--;
  return true;
}

void wayc_raw_vec_deinit(raw_vec_s *vec) {
  wayc_notnull(vec);
  if (vec->ptr == nullptr)
    return;

  mi_free(vec->ptr);
  vec->ptr = nullptr;
  vec->len = 0;
  vec->cap = 0;
}