cleanup
This commit is contained in:
@@ -17,7 +17,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y gcc make libcriterion-dev valgrind
|
sudo apt-get install -y gcc make libcriterion-dev valgrind zig
|
||||||
|
|
||||||
- name: Build and run tests
|
- name: Build and run tests
|
||||||
run: make test
|
run: make test
|
||||||
|
|||||||
+2
-4
@@ -1,13 +1,11 @@
|
|||||||
#include "cig.h"
|
#include "cig.h"
|
||||||
|
|
||||||
static void *buffer_allocator_alloc(buffer_allocator_t *this, size_t bytes) {
|
static void *buffer_allocator_alloc(buffer_allocator_t *this, size_t bytes) {
|
||||||
size_t address_of_new_data = (size_t) &this->data[this->size];
|
bytes = (bytes + MAX_ALIGN - 1) / MAX_ALIGN * MAX_ALIGN;
|
||||||
size_t offset = address_of_new_data % MAX_ALIGN;
|
size_t new_size = this->size + bytes;
|
||||||
size_t new_size = this->size + offset + bytes;
|
|
||||||
if (new_size > this->capacity) {
|
if (new_size > this->capacity) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
this->size += offset;
|
|
||||||
void *ptr = &this->data[this->size];
|
void *ptr = &this->data[this->size];
|
||||||
this->size = new_size;
|
this->size = new_size;
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ typedef union any_align { char c; int i; long l; long long ll; float f; double d
|
|||||||
#define KB (1024)
|
#define KB (1024)
|
||||||
#define MB (KB * KB)
|
#define MB (KB * KB)
|
||||||
#define GB (KB * KB * KB)
|
#define GB (KB * KB * KB)
|
||||||
#define OFFSET(STRUCT, FIELD) ((size_t) (&((STRUCT*) NULL)->FIELD))
|
#define PTR_FROM_FIELD_PTR(STRUCT, FIELD, PTR) ((STRUCT *) (((char *) PTR) - offsetof(STRUCT, FIELD)))
|
||||||
#define PTR_FROM_FIELD_PTR(STRUCT, FIELD, PTR) ((STRUCT *) (((char *) PTR) - OFFSET(STRUCT, FIELD)))
|
|
||||||
|
|
||||||
// Contains all operations an allocator can do. Similar interface to sdtlibs
|
// Contains all operations an allocator can do. Similar interface to sdtlibs
|
||||||
// malloc, realloc and free.
|
// malloc, realloc and free.
|
||||||
@@ -144,12 +143,11 @@ typedef struct dyn_array_create_func_args {
|
|||||||
} dyn_array_create_func_args_t;
|
} dyn_array_create_func_args_t;
|
||||||
void *dyn_array_create_func(dyn_array_create_func_args_t args);
|
void *dyn_array_create_func(dyn_array_create_func_args_t args);
|
||||||
|
|
||||||
#define make_arr(ALLOCATOR, TYPE, ...) ((TYPE *)dyn_array_create_func((dyn_array_create_func_args_t){ \
|
#define make_arr(TYPE, ...) ((TYPE *)dyn_array_create_func((dyn_array_create_func_args_t){ \
|
||||||
.allocator = ALLOCATOR, \
|
|
||||||
.itemsize = sizeof(TYPE), \
|
.itemsize = sizeof(TYPE), \
|
||||||
.file = __FILE__, \
|
.file = __FILE__, \
|
||||||
.line = __LINE__, \
|
.line = __LINE__, \
|
||||||
__VA_ARGS__ \
|
.allocator = __VA_ARGS__, \
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Always reassign the array. if multiple variables reference the same growing
|
// Always reassign the array. if multiple variables reference the same growing
|
||||||
@@ -180,13 +178,13 @@ size_t arr_cap(void *this);
|
|||||||
|
|
||||||
#define arr_pop(THIS) (arr_shrink(THIS, 1), THIS[arr_len(THIS)])
|
#define arr_pop(THIS) (arr_shrink(THIS, 1), THIS[arr_len(THIS)])
|
||||||
|
|
||||||
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line);
|
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line, bool print_error);
|
||||||
|
|
||||||
#define arr_get(THIS, INDEX) \
|
#define arr_get(THIS, INDEX) \
|
||||||
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__), (THIS)[INDEX])
|
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__, true), (THIS)[INDEX])
|
||||||
|
|
||||||
#define arr_set(THIS, INDEX, VALUE) \
|
#define arr_set(THIS, INDEX, VALUE) \
|
||||||
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__), (THIS)[INDEX] = (VALUE))
|
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__, true), (THIS)[INDEX] = (VALUE))
|
||||||
|
|
||||||
#define STATIC_ASSERT(expr) ((void)sizeof(char[(expr) ? 1 : -1]))
|
#define STATIC_ASSERT(expr) ((void)sizeof(char[(expr) ? 1 : -1]))
|
||||||
|
|
||||||
@@ -212,13 +210,6 @@ bool dyn_array_contains_cmp_func(void *this, uint8_t *value, dyn_array_eq_fn eq)
|
|||||||
// Comparison function for sorting: returns -1 if a < b, 0 if a == b, 1 if a > b
|
// Comparison function for sorting: returns -1 if a < b, 0 if a == b, 1 if a > b
|
||||||
typedef int (*dyn_array_cmp_fn)(const void *a, const void *b);
|
typedef int (*dyn_array_cmp_fn)(const void *a, const void *b);
|
||||||
|
|
||||||
void dyn_array_insert_sorted_func(void **this_ptr, const void *value, dyn_array_cmp_fn cmp, const char *file, int line);
|
|
||||||
|
|
||||||
#define arr_insert_sorted(THIS, VALUE, CMP_FN) do { \
|
|
||||||
typeof((THIS)[0]) _tmp_value = (VALUE); \
|
|
||||||
dyn_array_insert_sorted_func((void**)&(THIS), &_tmp_value, (CMP_FN), __FILE__, __LINE__); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
// CLI /////////////////////////////////////////////////////////////////////////
|
// CLI /////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define CLI_UNIQUE1 __macro_internal_34bba35b8b9b20a75f9881e3795630e25d36e620d9c9741e2e9141ba82ec6ef7__
|
#define CLI_UNIQUE1 __macro_internal_34bba35b8b9b20a75f9881e3795630e25d36e620d9c9741e2e9141ba82ec6ef7__
|
||||||
|
|||||||
+4
-36
@@ -96,9 +96,10 @@ bool dyn_array_contains_cmp_func(void *this, uint8_t *value, dyn_array_eq_fn eq)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line) {
|
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line, bool print_error) {
|
||||||
size_t len = arr_len(this);
|
size_t len = arr_len(this);
|
||||||
if (index >= len) {
|
if ((index >= len)) {
|
||||||
|
if (print_error) {
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"%s:%d: array index %zu out of bounds (length is %zu)\n",
|
"%s:%d: array index %zu out of bounds (length is %zu)\n",
|
||||||
@@ -107,41 +108,8 @@ void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int
|
|||||||
index,
|
index,
|
||||||
len
|
len
|
||||||
);
|
);
|
||||||
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dyn_array_insert_sorted_func(void **this_ptr, const void *value, dyn_array_cmp_fn cmp, const char *file, int line) {
|
|
||||||
void *this = *this_ptr;
|
|
||||||
dyn_array_header_t *header = PTR_FROM_FIELD_PTR(dyn_array_header_t, bytes, this);
|
|
||||||
|
|
||||||
// First append the value
|
|
||||||
this = dyn_array_grow_func(this, 1, file, line);
|
|
||||||
*this_ptr = this;
|
|
||||||
header = PTR_FROM_FIELD_PTR(dyn_array_header_t, bytes, this);
|
|
||||||
|
|
||||||
size_t itemsize = header->itemsize;
|
|
||||||
size_t n_items = header->n_items;
|
|
||||||
|
|
||||||
// Copy value to the end
|
|
||||||
memcpy(&header->bytes[(n_items - 1) * itemsize], value, itemsize);
|
|
||||||
|
|
||||||
// Bubble it into the correct position from the back
|
|
||||||
size_t pos = n_items - 1;
|
|
||||||
while (pos > 0) {
|
|
||||||
void *a = &header->bytes[(pos - 1) * itemsize];
|
|
||||||
void *b = &header->bytes[pos * itemsize];
|
|
||||||
|
|
||||||
if (cmp(a, b) <= 0) {
|
|
||||||
break; // Already in correct position
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap using a temporary buffer
|
|
||||||
uint8_t temp[itemsize];
|
|
||||||
memcpy(temp, a, itemsize);
|
|
||||||
memcpy(a, b, itemsize);
|
|
||||||
memcpy(b, temp, itemsize);
|
|
||||||
|
|
||||||
pos--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ char *read_entire_file(const char *path, allocator_t allocator) {
|
|||||||
// Returns dynamic array, of fixed char strings.
|
// Returns dynamic array, of fixed char strings.
|
||||||
char **read_all_file_lines(const char *path, allocator_t allocator) {
|
char **read_all_file_lines(const char *path, allocator_t allocator) {
|
||||||
char *contents = read_entire_file(path, allocator);
|
char *contents = read_entire_file(path, allocator);
|
||||||
char **lines = make_arr(allocator, char*);
|
char **lines = make_arr(char*, allocator);
|
||||||
arr_append(lines, contents);
|
arr_append(lines, contents);
|
||||||
bool just_split = false;
|
bool just_split = false;
|
||||||
for (char *c = contents; (*c)!='\0'; c++) {
|
for (char *c = contents; (*c)!='\0'; c++) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
CC := gcc
|
CC := zig cc
|
||||||
CFLAGS := -pedantic -Wall -Wextra -Wno-override-init -O0 -g -fno-omit-frame-pointer -fno-inline
|
CFLAGS := -pedantic -Wall -Wextra -Wno-override-init -O0 -g -fno-omit-frame-pointer -fno-inline
|
||||||
LDFLAGS := -lcriterion
|
LDFLAGS := -lcriterion
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ Test(arena_allocator, dyn_array_resize_pattern) {
|
|||||||
allocator_t arena = arena_allocator_create(backing, 10 * KB);
|
allocator_t arena = arena_allocator_create(backing, 10 * KB);
|
||||||
allocator_reset(arena);
|
allocator_reset(arena);
|
||||||
|
|
||||||
int *arr = make_arr(arena, int);
|
int *arr = make_arr(int, arena);
|
||||||
|
|
||||||
// Add 100 elements, forcing multiple resizes
|
// Add 100 elements, forcing multiple resizes
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
@@ -207,8 +207,8 @@ Test(arena_allocator, multiple_arrays_resize) {
|
|||||||
allocator_t arena = arena_allocator_create(backing, 20 * KB);
|
allocator_t arena = arena_allocator_create(backing, 20 * KB);
|
||||||
allocator_reset(arena);
|
allocator_reset(arena);
|
||||||
|
|
||||||
int *arr1 = make_arr(arena, int);
|
int *arr1 = make_arr(int, arena);
|
||||||
int *arr2 = make_arr(arena, int);
|
int *arr2 = make_arr(int, arena);
|
||||||
|
|
||||||
// Add to arr1
|
// Add to arr1
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < 50; i++) {
|
||||||
@@ -267,11 +267,11 @@ Test(arena_allocator, nested_structures_with_resize) {
|
|||||||
allocator_reset(arena);
|
allocator_reset(arena);
|
||||||
|
|
||||||
// Create array of int pointers (like dyn_array of dyn_arrays)
|
// Create array of int pointers (like dyn_array of dyn_arrays)
|
||||||
int **rows = make_arr(arena, int*);
|
int **rows = make_arr(int*, arena);
|
||||||
|
|
||||||
// Add 5 rows
|
// Add 5 rows
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
int *row = make_arr(arena, int);
|
int *row = make_arr(int, arena);
|
||||||
for (int j = 0; j < 10; j++) {
|
for (int j = 0; j < 10; j++) {
|
||||||
arr_append(row, i * 10 + j);
|
arr_append(row, i * 10 + j);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ static void test_buffer_alloc(buffer_allocator_t impl) {
|
|||||||
for (int i = 0; i < n_ints; i++) {
|
for (int i = 0; i < n_ints; i++) {
|
||||||
cr_assert_eq(ints[i], i);
|
cr_assert_eq(ints[i], i);
|
||||||
}
|
}
|
||||||
cr_assert_eq(impl.size, sizeof(int)*n_ints);
|
cr_assert_eq(impl.size, sizeof(int)*n_ints, "%zu != %d", impl.size, n_ints);
|
||||||
ints = allocator_alloc(inter, sizeof(int) * n_ints);
|
ints = allocator_alloc(inter, sizeof(int) * n_ints);
|
||||||
for (int i = 0; i < n_ints; i++) {
|
for (int i = 0; i < n_ints; i++) {
|
||||||
ints[i] = i;
|
ints[i] = i;
|
||||||
|
|||||||
+18
-147
@@ -2,25 +2,13 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "cig.h"
|
#include "cig.h"
|
||||||
|
|
||||||
static int int_cmp(const void *a, const void *b) {
|
|
||||||
int ia = *(const int*)a;
|
|
||||||
int ib = *(const int*)b;
|
|
||||||
if (ia < ib) return -1;
|
|
||||||
if (ia > ib) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool int_eq(const void *a, const void *b) {
|
static bool int_eq(const void *a, const void *b) {
|
||||||
return *(const int*)a == *(const int*)b;
|
return *(const int*)a == *(const int*)b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reverse_cmp(const void *a, const void *b) {
|
|
||||||
return -int_cmp(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, append) {
|
Test(dynamic_arrays, append) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *numbers = make_arr(alloc, int);
|
int *numbers = make_arr(int, alloc);
|
||||||
arr_append(numbers, 40);
|
arr_append(numbers, 40);
|
||||||
arr_append(numbers, 41);
|
arr_append(numbers, 41);
|
||||||
arr_append(numbers, 42);
|
arr_append(numbers, 42);
|
||||||
@@ -40,7 +28,7 @@ Test(dynamic_arrays, append) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, pop) {
|
Test(dynamic_arrays, pop) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *numbers = make_arr(alloc, int);
|
int *numbers = make_arr(int, alloc);
|
||||||
arr_append(numbers, 40);
|
arr_append(numbers, 40);
|
||||||
arr_append(numbers, 41);
|
arr_append(numbers, 41);
|
||||||
arr_append(numbers, 42);
|
arr_append(numbers, 42);
|
||||||
@@ -67,7 +55,7 @@ Test(dynamic_arrays, pop) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains) {
|
Test(dynamic_arrays, contains) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *numbers = make_arr(alloc, int);
|
int *numbers = make_arr(int, alloc);
|
||||||
arr_append(numbers, 20);
|
arr_append(numbers, 20);
|
||||||
cr_expect(arr_contains(numbers, &(int){20}));
|
cr_expect(arr_contains(numbers, &(int){20}));
|
||||||
arr_reset(numbers);
|
arr_reset(numbers);
|
||||||
@@ -82,72 +70,12 @@ Test(dynamic_arrays, contains) {
|
|||||||
cr_assert_eq(arr_len(numbers), 100);
|
cr_assert_eq(arr_len(numbers), 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Test(dynamic_arrays, insert_sorted_ascending) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
// Insert in random order
|
|
||||||
arr_insert_sorted(arr, 5, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 2, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 8, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 1, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 9, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 3, int_cmp);
|
|
||||||
|
|
||||||
// Verify sorted order
|
|
||||||
cr_assert_eq(arr_len(arr), 6);
|
|
||||||
cr_assert_eq(arr[0], 1);
|
|
||||||
cr_assert_eq(arr[1], 2);
|
|
||||||
cr_assert_eq(arr[2], 3);
|
|
||||||
cr_assert_eq(arr[3], 5);
|
|
||||||
cr_assert_eq(arr[4], 8);
|
|
||||||
cr_assert_eq(arr[5], 9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, insert_sorted_descending) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
// Insert in random order with reverse comparison
|
|
||||||
arr_insert_sorted(arr, 5, reverse_cmp);
|
|
||||||
arr_insert_sorted(arr, 2, reverse_cmp);
|
|
||||||
arr_insert_sorted(arr, 8, reverse_cmp);
|
|
||||||
arr_insert_sorted(arr, 1, reverse_cmp);
|
|
||||||
|
|
||||||
// Verify descending order
|
|
||||||
cr_assert_eq(arr_len(arr), 4);
|
|
||||||
cr_assert_eq(arr[0], 8);
|
|
||||||
cr_assert_eq(arr[1], 5);
|
|
||||||
cr_assert_eq(arr[2], 2);
|
|
||||||
cr_assert_eq(arr[3], 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, insert_sorted_duplicates) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
// Insert duplicates
|
|
||||||
arr_insert_sorted(arr, 5, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 3, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 5, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 3, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 5, int_cmp);
|
|
||||||
|
|
||||||
// Verify all elements are present
|
|
||||||
cr_assert_eq(arr_len(arr), 5);
|
|
||||||
cr_assert_eq(arr[0], 3);
|
|
||||||
cr_assert_eq(arr[1], 3);
|
|
||||||
cr_assert_eq(arr[2], 5);
|
|
||||||
cr_assert_eq(arr[3], 5);
|
|
||||||
cr_assert_eq(arr[4], 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, contains_found) {
|
Test(dynamic_arrays, contains_found) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -160,7 +88,7 @@ Test(dynamic_arrays, contains_found) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains_not_found) {
|
Test(dynamic_arrays, contains_not_found) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -173,63 +101,16 @@ Test(dynamic_arrays, contains_not_found) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains_empty) {
|
Test(dynamic_arrays, contains_empty) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
|
|
||||||
cr_assert_not(arr_contains(arr, &(int){10}));
|
cr_assert_not(arr_contains(arr, &(int){10}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(dynamic_arrays, insert_sorted_single_element) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
arr_insert_sorted(arr, 42, int_cmp);
|
|
||||||
|
|
||||||
cr_assert_eq(arr_len(arr), 1);
|
|
||||||
cr_assert_eq(arr[0], 42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, insert_sorted_already_sorted) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
// Insert in already sorted order
|
|
||||||
arr_insert_sorted(arr, 1, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 2, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 3, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 4, int_cmp);
|
|
||||||
|
|
||||||
// Verify order maintained
|
|
||||||
cr_assert_eq(arr_len(arr), 4);
|
|
||||||
for (size_t i = 0; i < arr_len(arr); i++) {
|
|
||||||
cr_assert_eq(arr[i], (int)(i + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, insert_sorted_reverse_order) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
|
||||||
|
|
||||||
// Insert in reverse order (worst case for bubble sort)
|
|
||||||
arr_insert_sorted(arr, 5, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 4, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 3, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 2, int_cmp);
|
|
||||||
arr_insert_sorted(arr, 1, int_cmp);
|
|
||||||
|
|
||||||
// Verify correct ascending order
|
|
||||||
cr_assert_eq(arr_len(arr), 5);
|
|
||||||
for (size_t i = 0; i < arr_len(arr); i++) {
|
|
||||||
cr_assert_eq(arr[i], (int)(i + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Test(dynamic_arrays, contains_cmp_found) {
|
Test(dynamic_arrays, contains_cmp_found) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -242,7 +123,7 @@ Test(dynamic_arrays, contains_cmp_found) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains_cmp_not_found) {
|
Test(dynamic_arrays, contains_cmp_not_found) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -255,7 +136,7 @@ Test(dynamic_arrays, contains_cmp_not_found) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains_cmp_empty) {
|
Test(dynamic_arrays, contains_cmp_empty) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int, .initial_capacity = 5);
|
int *arr = make_arr(int, alloc, .initial_capacity = 5);
|
||||||
|
|
||||||
cr_assert_not(arr_contains_cmp(arr, int_eq, &(int){10}));
|
cr_assert_not(arr_contains_cmp(arr, int_eq, &(int){10}));
|
||||||
}
|
}
|
||||||
@@ -275,7 +156,7 @@ static bool kv_eq_by_key(const void *a, const void *b) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, contains_cmp_key_value_map) {
|
Test(dynamic_arrays, contains_cmp_key_value_map) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
kv_pair_t *map = make_arr(alloc, kv_pair_t, .initial_capacity = 10);
|
kv_pair_t *map = make_arr(kv_pair_t, alloc, .initial_capacity = 10);
|
||||||
|
|
||||||
// Add some key-value pairs
|
// Add some key-value pairs
|
||||||
arr_append(map, ((kv_pair_t){.key = 1, .value = "one"}));
|
arr_append(map, ((kv_pair_t){.key = 1, .value = "one"}));
|
||||||
@@ -295,7 +176,7 @@ Test(dynamic_arrays, contains_cmp_key_value_map) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, get_valid_indices) {
|
Test(dynamic_arrays, get_valid_indices) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int);
|
int *arr = make_arr(int, alloc);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -310,7 +191,7 @@ Test(dynamic_arrays, get_valid_indices) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, set_valid_indices) {
|
Test(dynamic_arrays, set_valid_indices) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int);
|
int *arr = make_arr(int, alloc);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
arr_append(arr, 30);
|
arr_append(arr, 30);
|
||||||
@@ -327,36 +208,26 @@ Test(dynamic_arrays, set_valid_indices) {
|
|||||||
|
|
||||||
Test(dynamic_arrays, get_out_of_bounds, .exit_code = 1) {
|
Test(dynamic_arrays, get_out_of_bounds, .exit_code = 1) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int);
|
int *arr = make_arr(int, alloc);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
|
dyn_array_bounds_check_func( arr, 2, __FILE__, __LINE__, false);
|
||||||
(void)arr_get(arr, 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(dynamic_arrays, set_out_of_bounds, .exit_code = 1) {
|
Test(dynamic_arrays, set_out_of_bounds, .exit_code = 1) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int);
|
int *arr = make_arr(int, alloc);
|
||||||
arr_append(arr, 10);
|
arr_append(arr, 10);
|
||||||
arr_append(arr, 20);
|
arr_append(arr, 20);
|
||||||
|
|
||||||
arr_set(arr, 2, 999);
|
dyn_array_bounds_check_func( arr, 2, __FILE__, __LINE__, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(dynamic_arrays, get_empty_array, .exit_code = 1) {
|
Test(dynamic_arrays, get_empty_array, .exit_code = 1) {
|
||||||
with_borrow(alloc) {
|
with_borrow(alloc) {
|
||||||
int *arr = make_arr(alloc, int);
|
int *arr = make_arr(int, alloc);
|
||||||
(void)arr_get(arr, 0);
|
dyn_array_bounds_check_func( arr, 0, __FILE__, __LINE__, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(dynamic_arrays, set_empty_array, .exit_code = 1) {
|
|
||||||
with_borrow(alloc) {
|
|
||||||
int *arr = make_arr(alloc, int);
|
|
||||||
arr_set(arr, 0, 42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ typedef struct args {
|
|||||||
#define ARGS_DEFAULT .animal=cat, .is_true=true
|
#define ARGS_DEFAULT .animal=cat, .is_true=true
|
||||||
#define ARGS(...) ((args_t){ ARGS_DEFAULT, __VA_ARGS__ })
|
#define ARGS(...) ((args_t){ ARGS_DEFAULT, __VA_ARGS__ })
|
||||||
|
|
||||||
|
// NOTE: this is actually an extension, not really supported by the C standard.
|
||||||
Test(macro_magic, default_values) {
|
Test(macro_magic, default_values) {
|
||||||
args_t a1 = ARGS();
|
args_t a1 = ARGS();
|
||||||
args_t a2 = ARGS(.animal=dog);
|
args_t a2 = ARGS(.animal=dog);
|
||||||
|
|||||||
Reference in New Issue
Block a user