update
This commit is contained in:
parent
f5e048d02e
commit
7d24552659
3 changed files with 162 additions and 143 deletions
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue