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;
}
mie_vector_push_back(array->a_items, &item);
mie_vector_push_back(array->a_items, &item, NULL);
while (1) {
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
@@ -89,7 +89,7 @@ static enum mie_status parse(
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;

View File

@@ -2,14 +2,14 @@
#define MIE_VECTOR_H_
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
#if 0
#define MIE_VECTOR_DEFINE(type, name) \
size_t name##_count = 0; \
size_t name##_max = 0; \
type *name = NULL
#endif
struct mie_vector_ops {
enum mie_status (*v_copy)(void *, const void *, size_t);
enum mie_status (*v_move)(void *, void *, size_t);
enum mie_status (*v_destroy)(void *);
};
#define MIE_VECTOR_DEFINE(type, name) \
struct { \
@@ -43,52 +43,65 @@
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
/* 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( \
(void **)&(vector.items), ptr, sizeof *ptr, &(vector.count), \
&(vector.max))
#define mie_vector_pop_back(vector) \
&(vector.max), ops)
#define mie_vector_pop_back(vector, ops) \
__mie_vector_pop_back( \
(void **)&(vector), sizeof *vector, &(vector.count), \
&(vector.max))
#define mie_vector_emplace_back(vector) \
&(vector.max), ops)
#define mie_vector_emplace_back(vector, ops) \
__mie_vector_emplace_back( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max))
#define mie_vector_destroy(vector, dtor) \
&(vector.count), &(vector.max), ops)
#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( \
(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
* 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( \
(void **)(vector), ptr, sizeof *ptr, (vector##_count), \
(vector##_max))
#define mie_vector_ref_pop_back(vector) \
(vector##_max), ops)
#define mie_vector_ref_pop_back(vector, ops) \
__mie_vector_pop_back( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max))
#define mie_vector_ref_emplace_back(vector) \
(vector##_max), ops)
#define mie_vector_ref_emplace_back(vector, ops) \
__mie_vector_emplace_back( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max))
#define mie_vector_ref_destroy(vector, dtor) \
(vector##_max), ops)
#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( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), dtor)
(vector##_max), ops)
/* don't use these functions */
MIE_API int __mie_vector_push_back(
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(
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(
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(
void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *));
const struct mie_vector_ops *ops);
#endif

View File

@@ -12,7 +12,7 @@ struct mie_block *mie_region_add_block(struct mie_region *region)
memset(block, 0x0, sizeof *block);
mie_vector_push_back(region->r_blocks, &block);
mie_vector_push_back(region->r_blocks, &block, NULL);
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);
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;
}
type_slot = mie_vector_ref_emplace_back(out);
type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) {
return false;
}
if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out);
mie_vector_ref_pop_back(out, NULL);
return false;
}
@@ -464,13 +464,13 @@ bool mie_parser_parse_type_list(
break;
}
type_slot = mie_vector_ref_emplace_back(out);
type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) {
return false;
}
if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out);
mie_vector_ref_pop_back(out, NULL);
return false;
}
}
@@ -506,7 +506,7 @@ MIE_API bool mie_parser_parse_function_type(
ok = mie_parser_parse_type(ctx, &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;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -582,7 +582,7 @@ bool mie_parser_parse_operand_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -634,7 +634,7 @@ bool mie_parser_parse_parameter_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -658,7 +658,7 @@ bool mie_parser_parse_parameter_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -733,7 +733,7 @@ bool mie_parser_parse_register_list(
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)) {
return false;
@@ -758,7 +758,7 @@ bool mie_parser_parse_register_list(
if (!reg) {
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)) {
return false;
@@ -812,7 +812,7 @@ bool mie_parser_parse_region_list(
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)) {
return false;
@@ -827,7 +827,7 @@ bool mie_parser_parse_region_list(
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)) {
return false;
@@ -842,7 +842,7 @@ bool mie_parser_parse_anonymous_block(
{
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);
if (!mie_parser_parse_op(ctx, names, op)) {
@@ -860,7 +860,7 @@ bool mie_parser_parse_anonymous_block(
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);
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++) {
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
| MIE_REGISTER_F_BLOCK_PARAM;
@@ -955,7 +955,7 @@ bool mie_parser_parse_block(
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);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
@@ -1019,7 +1019,7 @@ bool mie_parser_parse_successor_list(
bool ok = false;
struct mie_op_successor *successor = NULL;
successor = mie_vector_ref_emplace_back(out);
successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) {
return false;
}
@@ -1038,7 +1038,7 @@ bool mie_parser_parse_successor_list(
mie_parser_advance(ctx);
mie_parser_parse_linefeed(ctx);
successor = mie_vector_ref_emplace_back(out);
successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) {
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);
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;
}
@@ -171,7 +171,7 @@ static bool filter_check_op(
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(

View File

@@ -74,13 +74,13 @@ struct mie_function_type *mie_function_type_create(void)
void mie_function_type_add_in_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(
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(

View File

@@ -56,7 +56,7 @@ struct mie_storage_type *mie_storage_type_create(void)
void mie_storage_type_add_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(

View File

@@ -30,26 +30,84 @@ static void vector_unwrap(
*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) {
return 0;
}
void *ptr = realloc(v->v_buf, new_capacity * v->v_itemsz);
if (!ptr) {
void *new_buf = malloc(new_capacity * v->v_itemsz);
if (!new_buf) {
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;
if (new_capacity < v->v_count) {
v->v_count = new_capacity;
}
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) {
return err;
}
@@ -61,7 +119,7 @@ static int vector_push_back(struct vector *v, const void *item)
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) {
v->v_count--;
@@ -70,9 +128,13 @@ static int vector_pop_back(struct vector *v)
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) {
return NULL;
}
@@ -84,18 +146,25 @@ static void *vector_emplace_back(struct vector *v)
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++) {
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) {
vector_destroy_items(v, dtor);
if (v->v_max > v->v_count) {
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) {
@@ -109,47 +178,59 @@ static void vector_destroy(struct vector *v, void (*dtor)(void *))
int __mie_vector_push_back(
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 = {};
int err = 0;
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);
return err;
}
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 = {};
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);
}
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 = {};
void *p = 0;
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);
return p;
}
void __mie_vector_destroy(
void __mie_vector_trim(
void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *))
const struct mie_vector_ops *ops)
{
struct vector v = {};
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);
}