mirror of
https://github.com/git/git.git
synced 2026-01-11 13:23:12 +09:00
112 lines
2.1 KiB
C
112 lines
2.1 KiB
C
#include "ivec.h"
|
|
|
|
struct IVec_c_void {
|
|
void *ptr;
|
|
size_t length;
|
|
size_t capacity;
|
|
size_t element_size;
|
|
};
|
|
|
|
static void _set_capacity(void *self_, size_t new_capacity)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
if (new_capacity == self->capacity) {
|
|
return;
|
|
}
|
|
if (new_capacity == 0) {
|
|
FREE_AND_NULL(self->ptr);
|
|
} else {
|
|
self->ptr = realloc(self->ptr, new_capacity * self->element_size);
|
|
}
|
|
self->capacity = new_capacity;
|
|
}
|
|
|
|
|
|
void ivec_init(void *self_, size_t element_size)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
self->ptr = NULL;
|
|
self->length = 0;
|
|
self->capacity = 0;
|
|
self->element_size = element_size;
|
|
}
|
|
|
|
void ivec_zero(void *self_, size_t capacity)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
self->ptr = calloc(capacity, self->element_size);
|
|
self->length = capacity;
|
|
self->capacity = capacity;
|
|
// DO NOT MODIFY element_size!!!
|
|
}
|
|
|
|
void ivec_reserve_exact(void *self_, size_t additional)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
_set_capacity(self, self->capacity + additional);
|
|
}
|
|
|
|
void ivec_reserve(void *self_, size_t additional)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
size_t growby = 128;
|
|
if (self->capacity > growby)
|
|
growby = self->capacity;
|
|
if (additional > growby)
|
|
growby = additional;
|
|
|
|
_set_capacity(self, self->capacity + growby);
|
|
}
|
|
|
|
void ivec_shrink_to_fit(void *self_)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
_set_capacity(self, self->length);
|
|
}
|
|
|
|
void ivec_push(void *self_, const void *value)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
void *dst = NULL;
|
|
|
|
if (self->length == self->capacity)
|
|
ivec_reserve(self, 1);
|
|
|
|
dst = (uint8_t*)self->ptr + self->length * self->element_size;
|
|
memcpy(dst, value, self->element_size);
|
|
self->length++;
|
|
}
|
|
|
|
void ivec_free(void *self_)
|
|
{
|
|
struct IVec_c_void *self = self_;
|
|
|
|
FREE_AND_NULL(self->ptr);
|
|
self->length = 0;
|
|
self->capacity = 0;
|
|
// DO NOT MODIFY element_size!!!
|
|
}
|
|
|
|
void ivec_move(void *src_, void *dst_)
|
|
{
|
|
struct IVec_c_void *src = src_;
|
|
struct IVec_c_void *dst = dst_;
|
|
|
|
ivec_free(dst);
|
|
dst->ptr = src->ptr;
|
|
dst->length = src->length;
|
|
dst->capacity = src->capacity;
|
|
// DO NOT MODIFY element_size!!!
|
|
|
|
src->ptr = NULL;
|
|
src->length = 0;
|
|
src->capacity = 0;
|
|
// DO NOT MODIFY element_size!!!
|
|
}
|