#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; }