Vector reword + map
This commit is contained in:
+81
-82
@@ -3,9 +3,7 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
object_t object;
|
||||
container_t container;
|
||||
|
||||
container_t container;
|
||||
allocator_mptr_t allocator;
|
||||
malunal_size_t stride;
|
||||
malunal_size_t count;
|
||||
@@ -21,95 +19,60 @@ _Static_assert(
|
||||
);
|
||||
|
||||
|
||||
static
|
||||
error_t
|
||||
vector_object_cast_impl(
|
||||
malunal_mptr_t object,
|
||||
uuid_iptr_t uuid,
|
||||
malunal_mptr_t* out
|
||||
) {
|
||||
if (object == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_CONTAINER_T,
|
||||
.code = CONTAINER_ERROR_NULL_CONTAINER
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)object;
|
||||
if (uuid_equals(&UUID_OBJECT_T, uuid)) {
|
||||
*out = &self->object;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
if (uuid_equals(&UUID_CONTAINER_T, uuid)) {
|
||||
*out = &self->container;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
*out = null;
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_CONTAINER_T,
|
||||
.code = CONTAINER_ERROR_FAILURE
|
||||
};
|
||||
}
|
||||
|
||||
static
|
||||
malunal_uint32_t
|
||||
vector_object_retain_impl(
|
||||
malunal_mptr_t object
|
||||
) {
|
||||
// TODO: figure out how to handle this.
|
||||
}
|
||||
|
||||
static
|
||||
malunal_uint32_t
|
||||
vector_object_release_impl(
|
||||
malunal_mptr_t object
|
||||
) {
|
||||
// TODO: figure out how to handle this.
|
||||
}
|
||||
|
||||
static const
|
||||
object_vtable_t vector_object_vtable = {
|
||||
.cast = &vector_object_cast_impl,
|
||||
.retain = &vector_object_retain_impl,
|
||||
.release = &vector_object_release_impl
|
||||
};
|
||||
|
||||
static const
|
||||
container_vtable_t vector_container_vtable = {
|
||||
.allocator = (container_allocator_pfn_t)&vector_container_allocator,
|
||||
.stride = (container_stride_pfn_t)&vector_container_stride,
|
||||
.count = (container_count_pfn_t)&vector_container_count,
|
||||
.capacity = (container_capacity_pfn_t)&vector_container_capacity,
|
||||
.resize = (container_resize_pfn_t)&vector_container_resize,
|
||||
.reserve = (container_reserve_pfn_t)&vector_container_reserve,
|
||||
.append = (container_append_pfn_t)&vector_container_append,
|
||||
.remove = (container_remove_pfn_t)&vector_container_remove,
|
||||
.contains = (container_contains_pfn_t)&vector_container_contains,
|
||||
.clear = (container_clear_pfn_t)&vector_container_clear
|
||||
};
|
||||
|
||||
static
|
||||
malunal_size_t
|
||||
power_2_ceil(malunal_size_t capacity) {
|
||||
if (capacity <= 1)
|
||||
return 1;
|
||||
|
||||
capacity--;
|
||||
malunal_size_t power = 2;
|
||||
while (capacity >>= 1)
|
||||
power <<= 1;
|
||||
return power;
|
||||
}
|
||||
|
||||
static
|
||||
error_t
|
||||
vector_container_realloc(impl_mptr_t self) {
|
||||
if ((float)self->count / self->capacity < 0.75f)
|
||||
vector_container_realloc(
|
||||
impl_mptr_t self,
|
||||
malunal_size_t capacity
|
||||
) {
|
||||
if (capacity <= self->capacity)
|
||||
return NO_ERROR;
|
||||
|
||||
malunal_mptr_t buffer;
|
||||
malunal_size_t oldcap = self->stride * self->capacity;
|
||||
error_t result = allocator_acquire(self->allocator, oldcap * 2, &buffer);
|
||||
malunal_size_t newcap = power_2_ceil(capacity);
|
||||
malunal_size_t bytes = self->stride * newcap;
|
||||
error_t result = allocator_acquire(self->allocator, bytes, &buffer);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
|
||||
buffer = memmove(buffer, self->buffer, oldcap);
|
||||
result = allocator_dispose(self->allocator, self->buffer, oldcap);
|
||||
bytes = self->stride * self->capacity;
|
||||
buffer = memmove(buffer, self->buffer, bytes);
|
||||
result = allocator_dispose(self->allocator, self->buffer, bytes);
|
||||
self->buffer = buffer;
|
||||
self->capacity = self->capacity * 2;
|
||||
self->capacity = newcap;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
vector_container_init(
|
||||
malunal_size_t stride,
|
||||
malunal_size_t capacity,
|
||||
allocator_mptr_t allocator,
|
||||
vector_container_mptr_t vector
|
||||
) {
|
||||
@@ -119,22 +82,17 @@ vector_container_init(
|
||||
.code = CONTAINER_ERROR_NULL_CONTAINER
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)vector;
|
||||
error_t result = allocator_acquire(
|
||||
allocator,
|
||||
stride * capacity,
|
||||
&self->buffer
|
||||
);
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)vector;
|
||||
malunal_size_t bytes = stride * MALUNAL_CONTAINERS_VECTOR_INIT_CAPACITY;
|
||||
error_t result = allocator_acquire(allocator, bytes, &self->buffer);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
|
||||
self->object = (object_t) { &vector_object_vtable };
|
||||
self->container = (container_t){ &vector_container_vtable };
|
||||
self->allocator = allocator;
|
||||
self->stride = stride;
|
||||
self->count = 0;
|
||||
self->capacity = capacity;
|
||||
self->capacity = MALUNAL_CONTAINERS_VECTOR_INIT_CAPACITY;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -229,6 +187,41 @@ vector_container_capacity(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
vector_container_resize(
|
||||
vector_container_mptr_t vector,
|
||||
malunal_size_t capacity
|
||||
) {
|
||||
if (vector == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_CONTAINER_T,
|
||||
.code = CONTAINER_ERROR_NULL_CONTAINER
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)vector;
|
||||
error_t result = vector_container_realloc(self, capacity);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
|
||||
self->count = capacity;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
error_t
|
||||
vector_container_reserve(
|
||||
vector_container_mptr_t vector,
|
||||
malunal_size_t capacity
|
||||
) {
|
||||
if (vector == null)
|
||||
return (error_t) {
|
||||
.domain = &ERROR_DOMAIN_CONTAINER_T,
|
||||
.code = CONTAINER_ERROR_NULL_CONTAINER
|
||||
};
|
||||
|
||||
impl_mptr_t self = (impl_mptr_t)vector;
|
||||
return vector_container_realloc(self, capacity);
|
||||
}
|
||||
|
||||
error_t
|
||||
vector_container_append(
|
||||
vector_container_mptr_t vector,
|
||||
@@ -240,10 +233,13 @@ vector_container_append(
|
||||
.code = CONTAINER_ERROR_NULL_CONTAINER
|
||||
};
|
||||
|
||||
error_t result = {};
|
||||
impl_mptr_t self = (impl_mptr_t)vector;
|
||||
error_t result = vector_container_realloc(self);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
if ((float)self->count / self->capacity >= 0.75f) {
|
||||
result = vector_container_realloc(self, self->capacity * 2);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
malunal_uint8_t* buffer = self->buffer;
|
||||
buffer += self->stride * self->count;
|
||||
@@ -383,15 +379,18 @@ vector_container_insert_at(
|
||||
.code = CONTAINER_ERROR_OUT_OF_BOUNDS
|
||||
};
|
||||
|
||||
error_t result = vector_container_realloc(self);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
error_t result = {};
|
||||
if ((float)self->count / self->capacity > 0.75f) {
|
||||
result = vector_container_realloc(self, self->capacity * 2);
|
||||
if (result.domain != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
malunal_uint8_t* orig = self->buffer;
|
||||
orig += self->stride * index;
|
||||
|
||||
malunal_uint8_t* dest = orig + self->stride;
|
||||
memmove(dest, orig, self->stride * self->count - index);
|
||||
memmove(dest, orig, self->stride * (self->count - index));
|
||||
memcpy(orig, element, self->stride);
|
||||
self->count++;
|
||||
return NO_ERROR;
|
||||
@@ -419,7 +418,7 @@ vector_container_remove_at(
|
||||
dest += self->stride * index;
|
||||
|
||||
malunal_uint8_t* orig = dest + self->stride;
|
||||
memmove(dest, orig, self->stride * self->count - index);
|
||||
memmove(dest, orig, self->stride * (self->count - index));
|
||||
self->count--;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user