wlroots/util/array.c

64 lines
1.4 KiB
C
Raw Normal View History

#include "util/array.h"
#include <assert.h>
2021-07-01 09:57:30 +02:00
#include <string.h>
2018-07-07 17:56:37 +02:00
2021-07-01 09:57:30 +02:00
void array_remove_at(struct wl_array *arr, size_t offset, size_t size) {
assert(arr->size >= offset + size);
char *data = arr->data;
memmove(&data[offset], &data[offset + size], arr->size - offset - size);
arr->size -= size;
}
bool array_realloc(struct wl_array *arr, size_t size) {
// If the size is less than 1/4th of the allocation size, we shrink it.
// 1/4th is picked to provide hysteresis, without which an array with size
// arr->alloc would constantly reallocate if an element is added and then
// removed continously.
size_t alloc;
if (arr->alloc > 0 && size > arr->alloc / 4) {
alloc = arr->alloc;
} else {
alloc = 16;
}
while (alloc < size) {
alloc *= 2;
}
if (alloc == arr->alloc) {
return true;
}
void *data = realloc(arr->data, alloc);
if (data == NULL) {
return false;
}
arr->data = data;
arr->alloc = alloc;
return true;
}
2022-08-25 21:55:46 -04:00
void *array_reversed_start(struct wl_array *arr) {
char *data = arr->data;
return data + arr->alloc - arr->size;
}
void *array_reversed_add(struct wl_array *arr, size_t size) {
if (arr->size + size > arr->alloc) {
size_t new_alloc = arr->alloc * 2;
char *new = malloc(new_alloc);
if (!new) {
return NULL;
}
memcpy(new + (new_alloc - arr->size), array_reversed_start(arr), arr->size);
free(arr->data);
arr->data = new;
arr->alloc = new_alloc;
}
arr->size += size;
return array_reversed_start(arr);
}