aboutsummaryrefslogtreecommitdiff
path: root/example_vec/new/vec.h
blob: 613af51bf427af0d315a51e2dc7a87aadd6a0a01 (plain) (blame)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef NGC_VEC_H
#define NGC_VEC_H

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>

typedef vec[any type]() {
	struct <> {
		size_t n;
		size_t s;
		type *buf;
	};

	typedef type *<>_iter;

	struct <> <>_create(size_t reserve)
	{
		if (reserve == 0)
			return (struct <>){.n = 0, .s = 0, .buf = NULL};

		return (struct <>){
			.n = 0,
			.s = reserve,
			.buf = malloc(reserve * sizeof(type))
		};
	}

	bool <>_uninit(struct <> *v)
	{
		return v->buf == NULL;
	}

	size_t <>_len(struct <> *v)
	{
		return v->n;
	}


	type *<>_at(struct <> *v, size_t i)
	{
		assert(i < v->n && "out of vector bounds");
		return &v->buf[i];
	}

	type *<>_pop(struct <> *v)
	{
		assert(v->n && "attempting to pop empty vector");
		v->n--;
		return &v->buf[v->n];
	}

	type* <>_append(struct <> *v, type n)
	{
		v->n++;
		if (v->n >= v->s) {
			v->s = v->s == 0 ? 1 : 2 * v->s;
			v->buf = realloc(v->buf, v->s * sizeof(type));
		}

		v->buf[v->n - 1] = n;
	}

	void <>_reset(struct <> *v)
	{
		v->n = 0;
	}

	void <>_destroy(struct <> *v)
	{
		free(v->buf);
	}

	void <>_reserve(struct <> *v, size_t n)
	{
		if (v->n >= n)
			return;

		while (v->s < v->n)
			v->s = v->s == 0 ? 1 : 2 * v->s;

		v->buf = realloc(v->buf, v->s * sizeof(type));
	}

	void <>_shrink(struct <> *v, size_t n)
	{
		assert(v->n >= n);
		v->n = n;
	}

	void <>_remove(struct <> *v, size_t i)
	{
		assert(v->n > i);
		size_t c = sizeof(type) * (v->n - i);
		memcpy(&v->buf[i], &v->buf[i + 1], c);
		v->n--;
	}

	<>_iter <>_begin(struct <> *v)
	{
		return &v->buf[0];
	}

	bool <>_end(struct <> *v, <>_iter i)
	{
		return &v->buf[v->n] == i;
	}

	<>_iter <>_next(<>_iter i)
	{
		return i + 1;
	}
}

#endif /* NGC_VEC_H */