Files
containers/sources/container.c
T
2026-08-17 04:16:46 -05:00

183 lines
4.5 KiB
C

#include "malunal/container.h"
typedef container_exception_t
(*container_initialize_pfn_t)(
container_mptr_t container,
allocator_mptr_t allocator,
malunal_size_t stride,
malunal_size_t capacity
);
typedef container_exception_t
(*container_finalize_pfn_t)(
container_mptr_t container
);
typedef container_exception_t
(*container_clear_pfn_t)(
container_mptr_t container
);
typedef container_exception_t
(*container_append_pfn_t)(
container_mptr_t container,
malunal_iptr_t element
);
typedef container_exception_t
(*container_remove_pfn_t)(
container_mptr_t container,
malunal_iptr_t element
);
typedef container_exception_t
(*container_contains_pfn_t)(
container_iptr_t container,
malunal_iptr_t element
);
typedef struct {
container_initialize_pfn_t const initialize;
container_finalize_pfn_t const finalize;
container_clear_pfn_t const clear;
container_append_pfn_t const append;
container_remove_pfn_t const remove;
container_contains_pfn_t const contains;
} virtual_table_t;
typedef virtual_table_t* base_vtable_mptr_t;
typedef const virtual_table_t* vtable_iptr_t;
typedef struct {
vtable_iptr_t const vtable;
allocator_mptr_t allocator;
malunal_mptr_t context;
malunal_size_t stride;
malunal_size_t count;
malunal_size_t capacity;
} implementation_t;
typedef implementation_t* impl_mptr_t;
typedef const implementation_t* impl_iptr_t;
// Verify these are the same.
_Static_assert(
CONTAINER_SIZE == sizeof(implementation_t),
"container_t must be the same size as its implementation"
);
container_exception_t
container_allocator(
container_iptr_t container,
allocator_mptr_t* out
) {
impl_iptr_t implementation = (impl_iptr_t)container;
if (implementation == NULL_ADDRESS)
return CONTAINER_ERROR_NULL_CONTAINER;
*out = implementation->allocator;
return CONTAINER_ERROR_SUCCESS;
}
container_exception_t
container_stride(
container_iptr_t container,
malunal_size_t* out
) {
impl_iptr_t implementation = (impl_iptr_t)container;
if (implementation == NULL_ADDRESS)
return CONTAINER_ERROR_NULL_CONTAINER;
*out = implementation->stride;
return CONTAINER_ERROR_SUCCESS;
}
container_exception_t
container_count(
container_iptr_t container,
malunal_size_t* out
) {
impl_iptr_t implementation = (impl_iptr_t)container;
if (implementation == NULL_ADDRESS)
return CONTAINER_ERROR_NULL_CONTAINER;
*out = implementation->count;
return CONTAINER_ERROR_SUCCESS;
}
container_exception_t
container_capacity(
container_iptr_t container,
malunal_size_t* out
) {
impl_iptr_t implementation = (impl_iptr_t)container;
if (implementation == NULL_ADDRESS)
return CONTAINER_ERROR_NULL_CONTAINER;
*out = implementation->capacity;
return CONTAINER_ERROR_SUCCESS;
}
container_exception_t
container_initialize(
container_mptr_t container,
allocator_mptr_t allocator,
malunal_size_t stride,
malunal_size_t capacity
) {
impl_mptr_t implementation = (impl_mptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->initialize(container, allocator, stride, capacity)
: CONTAINER_ERROR_NULL_CONTAINER;
}
container_exception_t
container_finalize(container_mptr_t container) {
impl_mptr_t implementation = (impl_mptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->finalize(container)
: CONTAINER_ERROR_NULL_CONTAINER;
}
container_exception_t
container_clear(container_mptr_t container) {
impl_mptr_t implementation = (impl_mptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->clear(container)
: CONTAINER_ERROR_NULL_CONTAINER;
}
container_exception_t
container_append(
container_mptr_t container,
malunal_iptr_t element
) {
impl_mptr_t implementation = (impl_mptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->append(container, element)
: CONTAINER_ERROR_NULL_CONTAINER;
}
container_exception_t
container_remove(
container_mptr_t container,
malunal_iptr_t element
) {
impl_mptr_t implementation = (impl_mptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->remove(container, element)
: CONTAINER_ERROR_NULL_CONTAINER;
}
container_exception_t
container_contains(
container_iptr_t container,
malunal_iptr_t element
) {
impl_iptr_t implementation = (impl_iptr_t)container;
return implementation != NULL_ADDRESS
? implementation->vtable->contains(container, element)
: CONTAINER_ERROR_NULL_CONTAINER;
}