This commit is contained in:
Maieul BOYER 2024-05-30 15:43:32 +02:00
parent f5e048d02e
commit 7d24552659
No known key found for this signature in database
3 changed files with 162 additions and 143 deletions

View file

@ -1,5 +1,23 @@
#ifndef ARRAY_H
#define ARRAY_H
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if true
# undef malloc
# undef calloc
# undef realloc
# undef free
# define malloc(s) mem_alloc((s))
# define calloc(s, l) mem_alloc_array((s), (l))
# define realloc(p, t) mem_realloc((p), (t))
# define free(p) mem_free((p))
#endif
#define Array(T) \
struct \
{ \
@ -146,4 +164,147 @@
array_insert(self, _index, value); \
} while (0)
typedef Array(void) Array;
/// This is not what you're looking for, see `array_delete`.
static inline void _array__delete(Array *self)
{
if (self->contents)
{
free(self->contents);
self->contents = NULL;
self->size = 0;
self->capacity = 0;
}
}
/// This is not what you're looking for, see `array_erase`.
static inline void _array__erase(Array *self, size_t element_size,
uint32_t index)
{
assert(index < self->size);
char *contents = (char *)self->contents;
memmove(contents + index * element_size,
contents + (index + 1) * element_size,
(self->size - index - 1) * element_size);
self->size--;
}
/// This is not what you're looking for, see `array_reserve`.
static inline void _array__reserve(Array *self, size_t element_size,
uint32_t new_capacity)
{
if (new_capacity > self->capacity)
{
if (self->contents)
{
self->contents =
realloc(self->contents, new_capacity * element_size);
}
else
{
self->contents = malloc(new_capacity * element_size);
}
self->capacity = new_capacity;
}
}
/// This is not what you're looking for, see `array_assign`.
static inline void _array__assign(Array *self, const Array *other,
size_t element_size)
{
_array__reserve(self, element_size, other->size);
self->size = other->size;
memcpy(self->contents, other->contents, self->size * element_size);
}
/// This is not what you're looking for, see `array_swap`.
static inline void _array__swap(Array *self, Array *other)
{
Array swap = *other;
*other = *self;
*self = swap;
}
/// This is not what you're looking for, see `array_push` or `array_grow_by`.
static inline void _array__grow(Array *self, uint32_t count,
size_t element_size)
{
uint32_t new_size = self->size + count;
if (new_size > self->capacity)
{
uint32_t new_capacity = self->capacity * 2;
if (new_capacity < 8)
new_capacity = 8;
if (new_capacity < new_size)
new_capacity = new_size;
_array__reserve(self, element_size, new_capacity);
}
}
/// This is not what you're looking for, see `array_splice`.
static inline void _array__splice(Array *self, size_t element_size,
uint32_t index, uint32_t old_count,
uint32_t new_count, const void *elements)
{
uint32_t new_size = self->size + new_count - old_count;
uint32_t old_end = index + old_count;
uint32_t new_end = index + new_count;
assert(old_end <= self->size);
_array__reserve(self, element_size, new_size);
char *contents = (char *)self->contents;
if (self->size > old_end)
{
memmove(contents + new_end * element_size,
contents + old_end * element_size,
(self->size - old_end) * element_size);
}
if (new_count > 0)
{
if (elements)
{
memcpy((contents + index * element_size), elements,
new_count * element_size);
}
else
{
memset((contents + index * element_size), 0,
new_count * element_size);
}
}
self->size += new_count - old_count;
}
/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
/// This is not what you're looking for, see `array_search_sorted_with` or
/// `array_search_sorted_by`.
#define _array__search_sorted(self, start, compare, suffix, needle, _index, \
_exists) \
do \
{ \
*(_index) = start; \
*(_exists) = false; \
uint32_t size = (self)->size - *(_index); \
if (size == 0) \
break; \
int comparison; \
while (size > 1) \
{ \
uint32_t half_size = size / 2; \
uint32_t mid_index = *(_index) + half_size; \
comparison = \
compare(&((self)->contents[mid_index] suffix), (needle)); \
if (comparison <= 0) \
*(_index) = mid_index; \
size -= half_size; \
} \
comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
if (comparison == 0) \
*(_exists) = true; \
else if (comparison < 0) \
*(_index) += 1; \
} while (0)
#endif // ARRAY_H