@@ -3,6 +3,7 @@ tests = [
|
||||
'reducecap_updatelen',
|
||||
'reducecap_free_elems',
|
||||
'reducelen_free_elems',
|
||||
'pop_out_frees_vector_owned_elem',
|
||||
]
|
||||
|
||||
foreach t : tests
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#define EV_VEC_IMPLEMENTATION
|
||||
#include "ev_vec.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int free_calls = 0;
|
||||
|
||||
typedef struct OwningInt {
|
||||
int *ptr;
|
||||
} OwningInt;
|
||||
|
||||
DEFINE_COPY_FUNCTION(OwningInt, Default)
|
||||
{
|
||||
dst->ptr = malloc(sizeof(*dst->ptr));
|
||||
assert(dst->ptr != NULL);
|
||||
*dst->ptr = *src->ptr;
|
||||
}
|
||||
|
||||
DEFINE_FREE_FUNCTION(OwningInt, Default)
|
||||
{
|
||||
assert(self->ptr != NULL);
|
||||
free(self->ptr);
|
||||
self->ptr = NULL;
|
||||
free_calls++;
|
||||
}
|
||||
|
||||
TYPEDATA_GEN(OwningInt, COPY(Default), FREE(Default));
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ev_vec(OwningInt) v = ev_vec_init(OwningInt);
|
||||
assert(v != NULL);
|
||||
|
||||
OwningInt original = { .ptr = malloc(sizeof(*original.ptr)) };
|
||||
assert(original.ptr != NULL);
|
||||
*original.ptr = 42;
|
||||
|
||||
assert(ev_vec_push_impl(&v, &original) == 0);
|
||||
free(original.ptr);
|
||||
|
||||
OwningInt out = {0};
|
||||
assert(ev_vec_pop(&v, &out) == EV_VEC_ERR_NONE);
|
||||
assert(out.ptr != NULL);
|
||||
assert(*out.ptr == 42);
|
||||
|
||||
FREE_FUNCTION(OwningInt, Default)(&out);
|
||||
|
||||
/* Popping with an output copy transfers no pointer from the vector element.
|
||||
The vector's own deep-copied element must still be destroyed. */
|
||||
assert(free_calls == 2);
|
||||
|
||||
ev_vec_fini(&v);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user