~lattis/muon

ref: 49a50d56c57dfdf470b4bcbffc16bc5ec92dcb4e muon/src/data/darr.c -rw-r--r-- 1.8 KiB
49a50d56Stone Tickle support comma seperated option array 10 months ago
                                                                                
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
#include "posix.h"

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

#include "data/darr.h"
#include "log.h"
#include "platform/mem.h"

void
darr_init(struct darr *da, size_t initial, size_t item_size)
{
	assert(item_size > 0);
	*da = (struct darr) {
		.item_size = item_size,
		.cap = initial,
		.e = z_malloc(initial * item_size),
	};
}

void
darr_destroy(struct darr *da)
{
	if (da->e) {
		z_free(da->e);
		da->e = NULL;
	}
}

void
darr_clear(struct darr *da)
{
	da->len = 0;
}

static uint8_t *
darr_point_at(const struct darr *da, size_t i)
{
	return da->e + (i * da->item_size);
}

static void *
darr_get_mem(struct darr *da)
{
	size_t i, newcap;
	++da->len;
	/* ensure_mem_size(elem, size, ++(*len), cap); */
	if (da->len > da->cap) {
		assert(da->cap);
		newcap = da->cap * 2;
		if (newcap < da->len) {
			newcap = da->len * 2;
		}

		da->cap = newcap;
		da->e = z_realloc(da->e, da->cap * da->item_size);
	} else {
		/* NOTE: uncomment the below line to cause a realloc for
		 * _every_ push into a darr.  This can help find bugs where you
		 * held a pointer into a darr too long. */
		/* da->e = z_realloc(da->e, da->cap * da->item_size); */
	}

	i = da->len - 1;

	return darr_point_at(da, i);
}

void
darr_grow_by(struct darr *da, size_t size)
{
	da->len += size - 1;
	darr_get_mem(da);
}

size_t
darr_push(struct darr *da, const void *item)
{
	memcpy(darr_get_mem(da), item, da->item_size);

	return da->len - 1;
}

void *
darr_get(const struct darr *da, size_t i)
{
	if (i >= da->len) {
		L("index %ld out of bounds (%ld)", i, da->len);
	}
	assert(i < da->len);

	return darr_point_at(da, i);
}

void
darr_del(struct darr *da, size_t i)
{
	assert(i < da->len);

	da->len--;

	if (da->len > 0 && da->len != i) {
		memmove(darr_point_at(da, i), darr_point_at(da, da->len), da->item_size);
	}
}