WIP
This commit is contained in:
@@ -96,8 +96,13 @@ allocator_t borrow_allocator_interface(borrow_allocator_t *this);
|
|||||||
// with_borrow(foos_allocator) {bar = foo(foos_allocator, my_allocator); } Using
|
// with_borrow(foos_allocator) {bar = foo(foos_allocator, my_allocator); } Using
|
||||||
// the return a keyword in the statement following this macro will cause a
|
// the return a keyword in the statement following this macro will cause a
|
||||||
// guaranteed memory leak.
|
// guaranteed memory leak.
|
||||||
#define with_borrow(NAME) \
|
#define with_borrow(NAME) \
|
||||||
for (allocator_t NAME = borrow_allocator_interface(&borrow_allocator_create()); !((borrow_allocator_t*)NAME.this)->head; ((borrow_allocator_t*)NAME.this)->head = (borrow_allocator_reset(((borrow_allocator_t*)NAME.this)), (linked_allocation_node_t*) 1)) \
|
for (allocator_t NAME = \
|
||||||
|
borrow_allocator_interface(&borrow_allocator_create()); \
|
||||||
|
!((borrow_allocator_t *)NAME.this)->head; \
|
||||||
|
((borrow_allocator_t *)NAME.this)->head = \
|
||||||
|
(borrow_allocator_reset(((borrow_allocator_t *)NAME.this)), \
|
||||||
|
(linked_allocation_node_t *)1)) \
|
||||||
for (int UNIQUE = 0; UNIQUE < 1; UNIQUE++)
|
for (int UNIQUE = 0; UNIQUE < 1; UNIQUE++)
|
||||||
|
|
||||||
// dynamic arrays //////////////////////////////////////////////////////////////
|
// dynamic arrays //////////////////////////////////////////////////////////////
|
||||||
@@ -119,8 +124,8 @@ void *dyn_array_create_func(dyn_array_create_func_args_t args);
|
|||||||
#define dyn_array_create(ALLOCATOR, TYPE, ...) ((TYPE*) dyn_array_create_func((dyn_array_create_func_args_t){.allocator=ALLOCATOR, .itemsize=sizeof(TYPE), .file=__FILE__, .line=__LINE__, __VA_ARGS__}))
|
#define dyn_array_create(ALLOCATOR, TYPE, ...) ((TYPE*) dyn_array_create_func((dyn_array_create_func_args_t){.allocator=ALLOCATOR, .itemsize=sizeof(TYPE), .file=__FILE__, .line=__LINE__, __VA_ARGS__}))
|
||||||
// Always reassign the array. if multiple variables reference the same growing
|
// Always reassign the array. if multiple variables reference the same growing
|
||||||
// array, then you should be using pointer pointers.
|
// array, then you should be using pointer pointers.
|
||||||
void *dyn_array_append_func(void *this, void *item, const char *file, int line);
|
void *dyn_array_grow_func(void *this, size_t n_new_items, const char *file, int line);
|
||||||
#define dyn_array_append(THIS, ITEM) dyn_array_append_func(THIS, &(ITEM), __FILE__, __LINE__)
|
#define dyn_array_grow(THIS, N_NEW_ITEMS) dyn_array_grow_func(THIS, N_NEW_ITEMS, __FILE__, __LINE__)
|
||||||
|
|
||||||
typedef struct dyn_array_create_non_crashing_func_args {
|
typedef struct dyn_array_create_non_crashing_func_args {
|
||||||
allocator_t allocator;
|
allocator_t allocator;
|
||||||
@@ -135,8 +140,8 @@ void *dyn_array_create_non_crashing_func(dyn_array_create_non_crashing_func_args
|
|||||||
// It is up to you to check that the pointer returned isn't NULL
|
// It is up to you to check that the pointer returned isn't NULL
|
||||||
// Always reassign the array. if multiple variables reference the same growing
|
// Always reassign the array. if multiple variables reference the same growing
|
||||||
// array, then you should be using pointer pointers.
|
// array, then you should be using pointer pointers.
|
||||||
void *dyn_array_append_non_crashing_func(void *this, void *item);
|
void *dyn_array_grow_non_crashing_func(void *this, size_t n_new_items);
|
||||||
#define dyn_array_append_non_crashing(THIS, ITEM) dyn_array_append_non_crashing_func(THIS, &(ITEM))
|
#define dyn_array_grow_non_crashing(THIS, N_NEW_ITEMS) dyn_array_grow_non_crashing_func(THIS, N_NEW_ITEMS)
|
||||||
|
|
||||||
size_t dyn_array_length(void *this);
|
size_t dyn_array_length(void *this);
|
||||||
size_t dyn_array_capacity(void *this);
|
size_t dyn_array_capacity(void *this);
|
||||||
|
|||||||
+13
-20
@@ -21,16 +21,15 @@ void *dyn_array_create_func(dyn_array_create_func_args_t args) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dyn_array_append_func(void *this, void *item, const char *file, int line) {
|
void *dyn_array_grow_func(void *this, size_t n_new_items, const char *file, int line) {
|
||||||
void *bytes = dyn_array_append_non_crashing_func(this, item);
|
void *bytes = dyn_array_grow_non_crashing_func(this, n_new_items);
|
||||||
if (bytes == NULL) {
|
if (bytes == NULL) {
|
||||||
fprintf(
|
fpritnf(
|
||||||
stderr,
|
stderr,
|
||||||
"%s:%d: allocator returned NULL\n",
|
"%s:%d: allocator returned NULL\n",
|
||||||
file,
|
file,
|
||||||
line
|
line
|
||||||
);
|
);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
@@ -48,11 +47,16 @@ void *dyn_array_create_non_crashing_func(dyn_array_create_non_crashing_func_args
|
|||||||
return &header->bytes;
|
return &header->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dyn_array_append_non_crashing_func(void *this, void *item) {
|
void *dyn_array_grow_non_crashing_func(void *this, size_t n_new_items) {
|
||||||
dyn_array_header_t *header = PTR_FROM_FIELD_PTR(dyn_array_header_t, bytes, this);
|
dyn_array_header_t *header = PTR_FROM_FIELD_PTR(dyn_array_header_t, bytes, this);
|
||||||
if (header->capacity <= header->size) {
|
size_t new_size = header->size + n_new_items;
|
||||||
size_t new_capacity = header->capacity * 2;
|
|
||||||
if (new_capacity == 0) { new_capacity = 1; }
|
if (header->capacity < new_size) {
|
||||||
|
size_t cap_times_2 = header->capacity * 2;
|
||||||
|
size_t new_capacity =
|
||||||
|
cap_times_2 > new_size
|
||||||
|
? cap_times_2
|
||||||
|
: new_size;
|
||||||
header = allocator_resize(
|
header = allocator_resize(
|
||||||
header->allocator,
|
header->allocator,
|
||||||
header,
|
header,
|
||||||
@@ -61,18 +65,7 @@ void *dyn_array_append_non_crashing_func(void *this, void *item) {
|
|||||||
if (header == NULL) { return NULL; }
|
if (header == NULL) { return NULL; }
|
||||||
header->capacity = new_capacity;
|
header->capacity = new_capacity;
|
||||||
}
|
}
|
||||||
&header->bytes[header->itemsize*header->size]
|
return &header->bytes
|
||||||
// typedef struct dyn_array_header {
|
|
||||||
// size_t size, capacity, itemsize;
|
|
||||||
// allocator_t allocator;
|
|
||||||
// uint8_t bytes[];
|
|
||||||
// } dyn_array_header_t;
|
|
||||||
|
|
||||||
// TODO: this is not good. the type has to be passed into the macro or
|
|
||||||
// something because passing in an integer does not work. it won't know to cast
|
|
||||||
// it to a char, int, long, whatever, so the bytes will be fucked. Either the
|
|
||||||
// macro can take the type to cast the value into the type, or we can just have
|
|
||||||
// some grow function instead...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t dyn_array_length(void *this) {
|
size_t dyn_array_length(void *this) {
|
||||||
|
|||||||
Reference in New Issue
Block a user