about summary refs log tree commit diff stats
path: root/src/resarr.c
blob: a359d71fca582f3e64081428c4d6c44da4eec294 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "resarr.h"

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

stype_resarr resarr_create(size_t elemsize) {
	return (stype_resarr) { .elemsize = elemsize, .elemcount = 0, .allocsize = 0, .array = NULL };
}

int resarr_reserve(stype_resarr *arr, size_t elemcount) {
	if (arr == NULL) return -1;
	size_t ec = 1;
	while (ec < elemcount) {
		ec *= 2;
	}
	if (ec * arr->elemsize < arr->allocsize) return -1;
	arr->array = realloc(arr->array, (ec * arr->elemsize));
	if (arr->array == NULL) return -1;
	arr->allocsize = ec * arr->elemsize;
	return 0;
}

int resarr_reserve_exact(stype_resarr *arr, size_t elemcount) {
	if (arr == NULL) return -1;
	if (elemcount * arr->elemsize < arr->allocsize) return -1;
	arr->array = realloc(arr->array, (elemcount * arr->elemsize));
	if (arr->array == NULL) return -1;
	arr->allocsize = elemcount * arr->elemsize;
	return 0;
}

int resarr_push(stype_resarr *arr, void *elem) {
	if (arr == NULL) return -1;
	if (arr->elemsize * arr->elemcount == arr->allocsize) {
		arr->array = realloc(arr->array, (arr->allocsize * 2));
		if (arr->array == NULL) return -1;
		arr->allocsize *= 2;
	}
	memcpy(
		((uintptr_t *)arr->array + (arr->elemsize * arr->elemcount)),
		(uintptr_t *)elem,
		arr->elemsize
	);
	return 0;
}

int resarr_pop(stype_resarr *arr) {
	if (arr == NULL) return -1;
	if (arr->array == NULL) return -1;
	memset(
		((uintptr_t *)arr->array + (arr->elemsize * arr->elemcount)),
		0,
		arr->elemsize
	);
	return 0;
}

size_t resarr_size(stype_resarr arr) {
	return arr.elemcount;
}

// TODO: insert{,_single}, delete

int resarr_swap(stype_resarr *first, stype_resarr *second) {
	if (first == NULL || second == NULL) return -1;
	if (first->elemsize != second->elemsize) return -1;
	size_t size = first->elemsize;
	size_t largest = 0;
	if (first->elemcount > second->elemcount) {
		largest = first->elemcount;
		resarr_reserve(second, first->elemcount);
	} else {
		largest = second->elemcount;
		resarr_reserve(first, second->elemcount);
	}
	// There has got to be a better way to do this...
	stype_resarr uwu = resarr_create(size);
	resarr_reserve_exact(&uwu, largest);
	uwu.elemcount = first->elemcount;
	memcpy(
		(uintptr_t *)uwu.array,
		(uintptr_t *)first->array,
		size
	);
	first->elemcount = second->elemcount;
	memcpy(
		(uintptr_t *)first->array,
		(uintptr_t *)second->array,
		size
	);
	second->elemcount = uwu.elemcount;
	memcpy(
		(uintptr_t *)second->array,
		(uintptr_t *)uwu.array,
		size
	);
	resarr_destroy(&uwu);
	return 0;
}

int resarr_swap_quick(stype_resarr *first, stype_resarr *second) {
	if (first == NULL || second == NULL) return -1;
	if (first->elemsize != second->elemsize) return -1;
	size_t size = first->elemcount;
	size_t alloc = first->allocsize;
	void *array = first->array;
	first->elemcount = second->elemcount;
	first->allocsize = second->allocsize;
	first->array = second->array;
	second->elemcount = size;
	second->allocsize = alloc;
	second->array = array;
	return 0;
}

int resarr_clear(stype_resarr *arr) {
	if (arr == NULL) return -1;
	memset(
		((uintptr_t *)arr->array),
		0,
		arr->elemsize * arr->elemcount
	);
	arr->elemcount = 0;
	return 0;
}

int resarr_destroy(stype_resarr *arr) {
	if (arr == NULL) return -1;
	free(arr->array);
	arr->elemcount = 0;
	arr->elemsize = 0;
	arr->allocsize = 0;
	return 0;
}