mie: vector: add copy- and move-constructor support

This commit is contained in:
2026-01-18 21:52:39 +00:00
parent 04af390fe8
commit 759aaf9fd8
8 changed files with 171 additions and 77 deletions

View File

@@ -73,7 +73,7 @@ static enum mie_status parse(
return MIE_ERR_BAD_FORMAT; return MIE_ERR_BAD_FORMAT;
} }
mie_vector_push_back(array->a_items, &item); mie_vector_push_back(array->a_items, &item, NULL);
while (1) { while (1) {
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) { if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
@@ -89,7 +89,7 @@ static enum mie_status parse(
return MIE_ERR_BAD_FORMAT; return MIE_ERR_BAD_FORMAT;
} }
mie_vector_push_back(array->a_items, &item); mie_vector_push_back(array->a_items, &item, NULL);
} }
*out = (struct mie_attribute *)array; *out = (struct mie_attribute *)array;

View File

@@ -2,14 +2,14 @@
#define MIE_VECTOR_H_ #define MIE_VECTOR_H_
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h> #include <stddef.h>
#if 0 struct mie_vector_ops {
#define MIE_VECTOR_DEFINE(type, name) \ enum mie_status (*v_copy)(void *, const void *, size_t);
size_t name##_count = 0; \ enum mie_status (*v_move)(void *, void *, size_t);
size_t name##_max = 0; \ enum mie_status (*v_destroy)(void *);
type *name = NULL };
#endif
#define MIE_VECTOR_DEFINE(type, name) \ #define MIE_VECTOR_DEFINE(type, name) \
struct { \ struct { \
@@ -43,52 +43,65 @@
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max) #define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
/* use these functions if you're accessing a vector directly. */ /* use these functions if you're accessing a vector directly. */
#define mie_vector_push_back(vector, ptr) \ #define mie_vector_push_back(vector, ptr, ops) \
__mie_vector_push_back( \ __mie_vector_push_back( \
(void **)&(vector.items), ptr, sizeof *ptr, &(vector.count), \ (void **)&(vector.items), ptr, sizeof *ptr, &(vector.count), \
&(vector.max)) &(vector.max), ops)
#define mie_vector_pop_back(vector) \ #define mie_vector_pop_back(vector, ops) \
__mie_vector_pop_back( \ __mie_vector_pop_back( \
(void **)&(vector), sizeof *vector, &(vector.count), \ (void **)&(vector), sizeof *vector, &(vector.count), \
&(vector.max)) &(vector.max), ops)
#define mie_vector_emplace_back(vector) \ #define mie_vector_emplace_back(vector, ops) \
__mie_vector_emplace_back( \ __mie_vector_emplace_back( \
(void **)&(vector.items), sizeof *vector.items, \ (void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max)) &(vector.count), &(vector.max), ops)
#define mie_vector_destroy(vector, dtor) \ #define mie_vector_trim(vector, ops) \
__mie_vector_trim( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max), ops)
#define mie_vector_destroy(vector, ops) \
__mie_vector_destroy( \ __mie_vector_destroy( \
(void **)&(vector.items), sizeof *vector.items, \ (void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max), dtor) &(vector.count), &(vector.max), ops)
/* use these functions if you're accessing a vector as a reference /* use these functions if you're accessing a vector as a reference
* via MIE_VECTOR_REF_PARAM. */ * via MIE_VECTOR_REF_PARAM. */
#define mie_vector_ref_push_back(vector, ptr) \ #define mie_vector_ref_push_back(vector, ptr, ops) \
__mie_vector_push_back( \ __mie_vector_push_back( \
(void **)(vector), ptr, sizeof *ptr, (vector##_count), \ (void **)(vector), ptr, sizeof *ptr, (vector##_count), \
(vector##_max)) (vector##_max), ops)
#define mie_vector_ref_pop_back(vector) \ #define mie_vector_ref_pop_back(vector, ops) \
__mie_vector_pop_back( \ __mie_vector_pop_back( \
(void **)(vector), sizeof **vector, (vector##_count), \ (void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max)) (vector##_max), ops)
#define mie_vector_ref_emplace_back(vector) \ #define mie_vector_ref_emplace_back(vector, ops) \
__mie_vector_emplace_back( \ __mie_vector_emplace_back( \
(void **)(vector), sizeof **vector, (vector##_count), \ (void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max)) (vector##_max), ops)
#define mie_vector_ref_destroy(vector, dtor) \ #define mie_vector_ref_trim(vector, ops) \
__mie_vector_trim( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), ops)
#define mie_vector_ref_destroy(vector, ops) \
__mie_vector_destroy( \ __mie_vector_destroy( \
(void **)(vector), sizeof **vector, (vector##_count), \ (void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), dtor) (vector##_max), ops)
/* don't use these functions */ /* don't use these functions */
MIE_API int __mie_vector_push_back( MIE_API int __mie_vector_push_back(
void **vector, const void *item, size_t item_size, size_t *count, void **vector, const void *item, size_t item_size, size_t *count,
size_t *max); size_t *max, const struct mie_vector_ops *ops);
MIE_API void __mie_vector_pop_back( MIE_API void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max); void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void *__mie_vector_emplace_back( MIE_API void *__mie_vector_emplace_back(
void **vector, size_t item_size, size_t *count, size_t *max); void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void __mie_vector_trim(
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void __mie_vector_destroy( MIE_API void __mie_vector_destroy(
void **vector, size_t item_size, size_t *count, size_t *max, void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *)); const struct mie_vector_ops *ops);
#endif #endif

View File

@@ -12,7 +12,7 @@ struct mie_block *mie_region_add_block(struct mie_region *region)
memset(block, 0x0, sizeof *block); memset(block, 0x0, sizeof *block);
mie_vector_push_back(region->r_blocks, &block); mie_vector_push_back(region->r_blocks, &block, NULL);
return block; return block;
} }

View File

@@ -398,7 +398,7 @@ static bool parse_composite_type(struct mie_parser *ctx, const struct mie_type *
ok = mie_parser_parse_type(ctx, &temp); ok = mie_parser_parse_type(ctx, &temp);
if (temp) { if (temp) {
mie_vector_push_back(type_list_2, &temp); mie_vector_push_back(type_list_2, &temp, NULL);
} }
} }
@@ -449,13 +449,13 @@ bool mie_parser_parse_type_list(
return true; return true;
} }
type_slot = mie_vector_ref_emplace_back(out); type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) { if (!type_slot) {
return false; return false;
} }
if (!mie_parser_parse_type(ctx, type_slot)) { if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out); mie_vector_ref_pop_back(out, NULL);
return false; return false;
} }
@@ -464,13 +464,13 @@ bool mie_parser_parse_type_list(
break; break;
} }
type_slot = mie_vector_ref_emplace_back(out); type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) { if (!type_slot) {
return false; return false;
} }
if (!mie_parser_parse_type(ctx, type_slot)) { if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out); mie_vector_ref_pop_back(out, NULL);
return false; return false;
} }
} }
@@ -506,7 +506,7 @@ MIE_API bool mie_parser_parse_function_type(
ok = mie_parser_parse_type(ctx, &type); ok = mie_parser_parse_type(ctx, &type);
if (type) { if (type) {
mie_vector_push_back(out_parts, &type); mie_vector_push_back(out_parts, &type, NULL);
} }
} }
@@ -558,7 +558,7 @@ bool mie_parser_parse_operand_list(
return false; return false;
} }
operand = mie_vector_ref_emplace_back(out); operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) { if (!operand) {
return false; return false;
} }
@@ -582,7 +582,7 @@ bool mie_parser_parse_operand_list(
return false; return false;
} }
operand = mie_vector_ref_emplace_back(out); operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) { if (!operand) {
return false; return false;
} }
@@ -634,7 +634,7 @@ bool mie_parser_parse_parameter_list(
return false; return false;
} }
operand = mie_vector_ref_emplace_back(out); operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) { if (!operand) {
return false; return false;
} }
@@ -658,7 +658,7 @@ bool mie_parser_parse_parameter_list(
return false; return false;
} }
operand = mie_vector_ref_emplace_back(out); operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) { if (!operand) {
return false; return false;
} }
@@ -733,7 +733,7 @@ bool mie_parser_parse_register_list(
return false; return false;
} }
mie_vector_ref_push_back(out, &reg); mie_vector_ref_push_back(out, &reg, NULL);
if (!mie_parser_parse_register(ctx, names, reg)) { if (!mie_parser_parse_register(ctx, names, reg)) {
return false; return false;
@@ -758,7 +758,7 @@ bool mie_parser_parse_register_list(
if (!reg) { if (!reg) {
return false; return false;
} }
mie_vector_ref_push_back(out, &reg); mie_vector_ref_push_back(out, &reg, NULL);
if (!mie_parser_parse_register(ctx, names, reg)) { if (!mie_parser_parse_register(ctx, names, reg)) {
return false; return false;
@@ -812,7 +812,7 @@ bool mie_parser_parse_region_list(
return false; return false;
} }
struct mie_region *region = mie_vector_ref_emplace_back(out); struct mie_region *region = mie_vector_ref_emplace_back(out, NULL);
if (!mie_parser_parse_region(ctx, region)) { if (!mie_parser_parse_region(ctx, region)) {
return false; return false;
@@ -827,7 +827,7 @@ bool mie_parser_parse_region_list(
break; break;
} }
struct mie_region *region = mie_vector_ref_emplace_back(out); struct mie_region *region = mie_vector_ref_emplace_back(out, NULL);
if (!mie_parser_parse_region(ctx, region)) { if (!mie_parser_parse_region(ctx, region)) {
return false; return false;
@@ -842,7 +842,7 @@ bool mie_parser_parse_anonymous_block(
{ {
mie_parser_parse_linefeed(ctx); mie_parser_parse_linefeed(ctx);
struct mie_op *op = mie_vector_emplace_back(block->b_ops); struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op); mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) { if (!mie_parser_parse_op(ctx, names, op)) {
@@ -860,7 +860,7 @@ bool mie_parser_parse_anonymous_block(
break; break;
} }
struct mie_op *op = mie_vector_emplace_back(block->b_ops); struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op); mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) { if (!mie_parser_parse_op(ctx, names, op)) {
@@ -899,7 +899,7 @@ static bool parse_block_parameters(
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) { for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
struct mie_register *param_reg = calloc(1, sizeof *param_reg); struct mie_register *param_reg = calloc(1, sizeof *param_reg);
mie_vector_push_back(block->b_params, &param_reg); mie_vector_push_back(block->b_params, &param_reg, NULL);
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
| MIE_REGISTER_F_BLOCK_PARAM; | MIE_REGISTER_F_BLOCK_PARAM;
@@ -955,7 +955,7 @@ bool mie_parser_parse_block(
break; break;
} }
struct mie_op *op = mie_vector_emplace_back(block->b_ops); struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op); mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) { if (!mie_parser_parse_op(ctx, names, op)) {
return false; return false;
@@ -1019,7 +1019,7 @@ bool mie_parser_parse_successor_list(
bool ok = false; bool ok = false;
struct mie_op_successor *successor = NULL; struct mie_op_successor *successor = NULL;
successor = mie_vector_ref_emplace_back(out); successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) { if (!successor) {
return false; return false;
} }
@@ -1038,7 +1038,7 @@ bool mie_parser_parse_successor_list(
mie_parser_advance(ctx); mie_parser_advance(ctx);
mie_parser_parse_linefeed(ctx); mie_parser_parse_linefeed(ctx);
successor = mie_vector_ref_emplace_back(out); successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) { if (!successor) {
return false; return false;
} }

View File

@@ -74,7 +74,7 @@ struct mie_pass_manager *mie_pass_manager_nest(struct mie_pass_manager *pm)
struct mie_pass_manager *nest = mie_pass_manager_create(pm->pm_ctx); struct mie_pass_manager *nest = mie_pass_manager_create(pm->pm_ctx);
nest->pm_depth = pm->pm_depth + 1; nest->pm_depth = pm->pm_depth + 1;
mie_vector_push_back(pm->pm_nested, &nest); mie_vector_push_back(pm->pm_nested, &nest, NULL);
return nest; return nest;
} }
@@ -171,7 +171,7 @@ static bool filter_check_op(
void mie_pass_manager_add_pass(struct mie_pass_manager *pm, struct mie_pass *pass) void mie_pass_manager_add_pass(struct mie_pass_manager *pm, struct mie_pass *pass)
{ {
mie_vector_push_back(pm->pm_passes, &pass); mie_vector_push_back(pm->pm_passes, &pass, NULL);
} }
static void schedule_passes( static void schedule_passes(

View File

@@ -74,13 +74,13 @@ struct mie_function_type *mie_function_type_create(void)
void mie_function_type_add_in_part( void mie_function_type_add_in_part(
struct mie_function_type *ty, const struct mie_type *part) struct mie_function_type *ty, const struct mie_type *part)
{ {
mie_vector_push_back(ty->func_in, &part); mie_vector_push_back(ty->func_in, &part, NULL);
} }
void mie_function_type_add_out_part( void mie_function_type_add_out_part(
struct mie_function_type *ty, const struct mie_type *part) struct mie_function_type *ty, const struct mie_type *part)
{ {
mie_vector_push_back(ty->func_out, &part); mie_vector_push_back(ty->func_out, &part, NULL);
} }
void mie_function_type_print( void mie_function_type_print(

View File

@@ -56,7 +56,7 @@ struct mie_storage_type *mie_storage_type_create(void)
void mie_storage_type_add_part( void mie_storage_type_add_part(
struct mie_storage_type *ty, const struct mie_type *part) struct mie_storage_type *ty, const struct mie_type *part)
{ {
mie_vector_push_back(ty->st_parts, &part); mie_vector_push_back(ty->st_parts, &part, NULL);
} }
void mie_storage_type_build_id( void mie_storage_type_build_id(

View File

@@ -30,26 +30,84 @@ static void vector_unwrap(
*max = v->v_max; *max = v->v_max;
} }
static int vector_reserve(struct vector *v, size_t new_capacity) static int move_vector_items(
struct vector *v, void *new_buf, size_t new_capacity,
const struct mie_vector_ops *ops)
{
size_t items_to_copy = MIN(v->v_count, new_capacity);
if (!ops || (!ops->v_copy && !ops->v_move)) {
memcpy(new_buf, v->v_buf, items_to_copy * v->v_itemsz);
return 0;
}
char *src = v->v_buf;
char *dst = new_buf;
for (size_t i = 0; i < items_to_copy; i++) {
if (ops->v_move) {
ops->v_move(dst, src, v->v_itemsz);
} else if (ops->v_copy) {
ops->v_copy(dst, src, v->v_itemsz);
} else {
memcpy(dst, src, v->v_itemsz);
}
src += v->v_itemsz;
dst += v->v_itemsz;
}
return 0;
}
static int trim_excess_items(
struct vector *v, size_t new_capacity, const struct mie_vector_ops *ops)
{
size_t to_trim = v->v_count - new_capacity;
size_t start = new_capacity;
char *item = &v->v_buf[start];
for (size_t i = start; i < v->v_count; i++) {
ops->v_destroy(item);
item += v->v_itemsz;
}
return 0;
}
static int vector_resize(
struct vector *v, size_t new_capacity, const struct mie_vector_ops *ops)
{ {
if (v->v_max >= new_capacity) { if (v->v_max >= new_capacity) {
return 0; return 0;
} }
void *ptr = realloc(v->v_buf, new_capacity * v->v_itemsz); void *new_buf = malloc(new_capacity * v->v_itemsz);
if (!ptr) { if (!new_buf) {
return -1; return -1;
} }
v->v_buf = ptr; move_vector_items(v, new_buf, new_capacity, ops);
if (ops && ops->v_destroy && new_capacity < v->v_count) {
trim_excess_items(v, new_capacity, ops);
}
if (v->v_buf) {
free(v->v_buf);
}
v->v_buf = new_buf;
v->v_max = new_capacity; v->v_max = new_capacity;
if (new_capacity < v->v_count) {
v->v_count = new_capacity;
}
return 0; return 0;
} }
static int vector_push_back(struct vector *v, const void *item) static int vector_push_back(
struct vector *v, const void *item, const struct mie_vector_ops *ops)
{ {
int err = vector_reserve(v, v->v_count + DEFAULT_CAPACITY); int err = vector_resize(v, v->v_count + DEFAULT_CAPACITY, ops);
if (err != 0) { if (err != 0) {
return err; return err;
} }
@@ -61,7 +119,7 @@ static int vector_push_back(struct vector *v, const void *item)
return 0; return 0;
} }
static int vector_pop_back(struct vector *v) static int vector_pop_back(struct vector *v, const struct mie_vector_ops *ops)
{ {
if (v->v_count > 0) { if (v->v_count > 0) {
v->v_count--; v->v_count--;
@@ -70,9 +128,13 @@ static int vector_pop_back(struct vector *v)
return 0; return 0;
} }
static void *vector_emplace_back(struct vector *v) static void *vector_emplace_back(struct vector *v, const struct mie_vector_ops *ops)
{ {
int err = vector_reserve(v, v->v_count + 1); int err = 0;
if (v->v_count >= v->v_max) {
err = vector_resize(v, v->v_count + DEFAULT_CAPACITY, ops);
}
if (err != 0) { if (err != 0) {
return NULL; return NULL;
} }
@@ -84,18 +146,25 @@ static void *vector_emplace_back(struct vector *v)
return dest; return dest;
} }
static void vector_destroy_items(struct vector *v, void (*dtor)(void *)) static void vector_destroy_items(struct vector *v, const struct mie_vector_ops *ops)
{ {
for (size_t i = 0; i < v->v_count; i++) { for (size_t i = 0; i < v->v_count; i++) {
void *item = (char *)v->v_buf + (i * v->v_itemsz); void *item = (char *)v->v_buf + (i * v->v_itemsz);
dtor(item); ops->v_destroy(item);
} }
} }
static void vector_destroy(struct vector *v, void (*dtor)(void *)) static void vector_trim(struct vector *v, const struct mie_vector_ops *ops)
{ {
if (dtor) { if (v->v_max > v->v_count) {
vector_destroy_items(v, dtor); vector_resize(v, v->v_count, ops);
}
}
static void vector_destroy(struct vector *v, const struct mie_vector_ops *ops)
{
if (ops && ops->v_destroy) {
vector_destroy_items(v, ops);
} }
if (v->v_buf) { if (v->v_buf) {
@@ -109,47 +178,59 @@ static void vector_destroy(struct vector *v, void (*dtor)(void *))
int __mie_vector_push_back( int __mie_vector_push_back(
void **vector, const void *item, size_t item_size, size_t *count, void **vector, const void *item, size_t item_size, size_t *count,
size_t *max) size_t *max, const struct mie_vector_ops *ops)
{ {
struct vector v = {}; struct vector v = {};
int err = 0; int err = 0;
vector_wrap(&v, vector, item_size, count, max); vector_wrap(&v, vector, item_size, count, max);
err = vector_push_back(&v, item); err = vector_push_back(&v, item, ops);
vector_unwrap(&v, vector, item_size, count, max); vector_unwrap(&v, vector, item_size, count, max);
return err; return err;
} }
void __mie_vector_pop_back( void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max) void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{ {
struct vector v = {}; struct vector v = {};
vector_wrap(&v, vector, item_size, count, max); vector_wrap(&v, vector, item_size, count, max);
vector_pop_back(&v); vector_pop_back(&v, ops);
vector_unwrap(&v, vector, item_size, count, max); vector_unwrap(&v, vector, item_size, count, max);
} }
void *__mie_vector_emplace_back( void *__mie_vector_emplace_back(
void **vector, size_t item_size, size_t *count, size_t *max) void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{ {
struct vector v = {}; struct vector v = {};
void *p = 0; void *p = 0;
vector_wrap(&v, vector, item_size, count, max); vector_wrap(&v, vector, item_size, count, max);
p = vector_emplace_back(&v); p = vector_emplace_back(&v, NULL);
vector_unwrap(&v, vector, item_size, count, max); vector_unwrap(&v, vector, item_size, count, max);
return p; return p;
} }
void __mie_vector_destroy( void __mie_vector_trim(
void **vector, size_t item_size, size_t *count, size_t *max, void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *)) const struct mie_vector_ops *ops)
{ {
struct vector v = {}; struct vector v = {};
vector_wrap(&v, vector, item_size, count, max); vector_wrap(&v, vector, item_size, count, max);
vector_destroy(&v, dtor); vector_trim(&v, ops);
vector_unwrap(&v, vector, item_size, count, max);
}
void __mie_vector_destroy(
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_destroy(&v, ops);
vector_unwrap(&v, vector, item_size, count, max); vector_unwrap(&v, vector, item_size, count, max);
} }