Compare commits

...

17 Commits

Author SHA1 Message Date
9fbd7d87ce Merge pull request 'implementation_ArrayListSlice' (#1) from implementation_ArrayListSlice into main
Reviewed-on: #1
2026-04-23 11:25:37 -06:00
d940b68eef test: tests for arrayslice to aray done 2026-04-23 11:22:57 -06:00
51f1166f31 test: advance tests done 2026-04-23 10:47:23 -06:00
a515f8eaf2 test: reset tests done 2026-04-23 10:29:53 -06:00
e04fc30f4e test: next tests done 2026-04-23 10:03:55 -06:00
9920b518bf test: peek tests done 2026-04-23 09:39:59 -06:00
4a1575e833 addtition: slice to array, needs testing 2026-04-23 09:18:18 -06:00
dd992cf6b9 addtition: reset and advance, need testing 2026-04-23 08:59:12 -06:00
e8aaa006de addition: next and peek, need testing 2026-04-23 08:47:45 -06:00
94dc859a8f test: added tests for slice_destroy 2026-04-22 17:55:14 -06:00
b34fb9902f test: added tests for slice_unsafe 2026-04-22 17:26:49 -06:00
198997e2b6 test: arraylist_slice tested 2026-04-21 19:57:58 -06:00
b313045153 test: Check for borrows before changing array state 2026-04-21 11:16:11 -06:00
dafaa5b87e fix: fixed problems with init and destroy slice 2026-04-21 09:10:53 -06:00
6088895ad0 addition: create slice and unsafe, also destroy 2026-04-20 08:43:58 -06:00
04a52e3455 addtition: Added function declarations 2026-04-19 21:57:28 -06:00
4b2389ad62 feature: Added structure for ArrayListSlices 2026-04-19 12:32:11 -06:00
3 changed files with 1120 additions and 9 deletions

View File

@@ -7,15 +7,7 @@
typedef struct ArrayList ArrayList; typedef struct ArrayList ArrayList;
// FUCK, i forgot one of the main reasons i wanted to typedef struct ArraySlice ArraySlice;
// implement arrays myself was because i needed
// array slices or something like this and i completely
// forgot, fuck, guess i will implement it once i get
// the tests done.
typedef struct {
ArrayList *array;
size_t offset;
} ArrayListSlice;
typedef enum { typedef enum {
ARRLIST_OK = 0, ARRLIST_OK = 0,
@@ -26,11 +18,14 @@ typedef enum {
ARRLIST_NULL_ARG, ARRLIST_NULL_ARG,
ARRLIST_INVALID_ELEM_SIZE, ARRLIST_INVALID_ELEM_SIZE,
ARRLIST_INVALID_CAPACITY, ARRLIST_INVALID_CAPACITY,
ARRLIST_IS_BORROWED,
ARRLIST_INVALID_SLICE,
} ArrayListErr; } ArrayListErr;
ArrayList *arraylist_init(size_t capacity, size_t elem_size); ArrayList *arraylist_init(size_t capacity, size_t elem_size);
ArrayListErr arraylist_destroy(ArrayList **arr); ArrayListErr arraylist_destroy(ArrayList **arr);
ArrayListErr arraylist_clear(ArrayList *arr); ArrayListErr arraylist_clear(ArrayList *arr);
ArrayList *arraylist_clone(const ArrayList *arr);
size_t arraylist_size(const ArrayList *arr); size_t arraylist_size(const ArrayList *arr);
size_t arraylist_capacity(const ArrayList *arr); size_t arraylist_capacity(const ArrayList *arr);
@@ -51,4 +46,22 @@ ArrayListErr arraylist_set(ArrayList *arr, size_t index, void *data);
ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity); ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity);
ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve); ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve);
//Slice stuff
ArraySlice *arraylist_slice(ArrayList *arr, size_t start, size_t len);
ArraySlice *arraylist_slice_unsafe(ArrayList *arr, size_t start, size_t len);
ArrayListErr arrayslice_destroy(ArraySlice **slice);
bool arrayslice_is_valid(const ArraySlice *slice);
size_t arrayslice_size(const ArraySlice *slice);
// peek and next can be null, get can't, like, why would you use get without
// actually getting something?, for validating an index?, use size idiot
ArrayListErr arrayslice_peek(const ArraySlice *slice, void *out);
ArrayListErr arrayslice_next(ArraySlice *slice, void *out);
ArrayListErr arrayslice_reset(ArraySlice *slice);
ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n);
ArrayList *arrayslice_to_arraylist(const ArraySlice *slice);
#endif #endif

View File

@@ -9,6 +9,15 @@ struct ArrayList{
size_t capacity; size_t capacity;
size_t len; size_t len;
size_t elem_size; size_t elem_size;
size_t borrows;
};
struct ArraySlice {
ArrayList *arr;
size_t start;
size_t end;
size_t current;
bool is_safe;
}; };
// Grow and shrink factor is 2, 1.5 might give different results i guess // Grow and shrink factor is 2, 1.5 might give different results i guess
@@ -37,6 +46,7 @@ ArrayList *arraylist_init(size_t capacity, size_t elem_size) {
arr->capacity = capacity; arr->capacity = capacity;
arr->elem_size = elem_size; arr->elem_size = elem_size;
arr->len = 0; arr->len = 0;
arr->borrows = 0;
arr->buffer = malloc(capacity * elem_size); arr->buffer = malloc(capacity * elem_size);
if (arr->buffer == NULL) { if (arr->buffer == NULL) {
free(arr); free(arr);
@@ -51,6 +61,10 @@ ArrayListErr arraylist_destroy(ArrayList **arr) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if ((*arr)->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
// No problem on using free on NULL :) // No problem on using free on NULL :)
free((*arr)->buffer); free((*arr)->buffer);
free(*arr); free(*arr);
@@ -64,6 +78,10 @@ ArrayListErr arraylist_clear(ArrayList *arr) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
arr->len = 0; arr->len = 0;
return ARRLIST_OK; return ARRLIST_OK;
} }
@@ -131,6 +149,10 @@ ArrayListErr arraylist_push_back(ArrayList *arr, void *data) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (arr->len >= arr->capacity) { if (arr->len >= arr->capacity) {
ArrayListErr err = arraylist_grow(arr); ArrayListErr err = arraylist_grow(arr);
@@ -149,6 +171,10 @@ ArrayListErr arraylist_push_front(ArrayList *arr, void *data) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (arr->len >= arr->capacity) { if (arr->len >= arr->capacity) {
ArrayListErr err = arraylist_grow(arr); ArrayListErr err = arraylist_grow(arr);
@@ -179,6 +205,10 @@ ArrayListErr arraylist_insert(ArrayList *arr, size_t index, void *data) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (index > arr->len) { if (index > arr->len) {
return ARRLIST_OUT_OF_BOUNDS; return ARRLIST_OUT_OF_BOUNDS;
} }
@@ -209,6 +239,10 @@ ArrayListErr arraylist_pop_back(ArrayList *arr, void *out) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (arr->len < 1) { if (arr->len < 1) {
return ARRLIST_EMPTY; return ARRLIST_EMPTY;
} }
@@ -237,6 +271,10 @@ ArrayListErr arraylist_pop_front(ArrayList *arr, void *out) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (arr->len < 1) { if (arr->len < 1) {
return ARRLIST_EMPTY; return ARRLIST_EMPTY;
} }
@@ -271,6 +309,10 @@ ArrayListErr arraylist_remove_at(ArrayList *arr, size_t index, void *out) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (index >= arr->len) { if (index >= arr->len) {
return ARRLIST_OUT_OF_BOUNDS; return ARRLIST_OUT_OF_BOUNDS;
} }
@@ -336,6 +378,10 @@ ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (new_capacity < 1) { if (new_capacity < 1) {
return ARRLIST_INVALID_CAPACITY; return ARRLIST_INVALID_CAPACITY;
} }
@@ -359,6 +405,10 @@ ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve) {
return ARRLIST_NULL_ARG; return ARRLIST_NULL_ARG;
} }
if (arr->borrows > 0) {
return ARRLIST_IS_BORROWED;
}
if (arr->capacity + size_to_reserve > SIZE_MAX / arr->elem_size || if (arr->capacity + size_to_reserve > SIZE_MAX / arr->elem_size ||
size_to_reserve > SIZE_MAX / arr->elem_size) { size_to_reserve > SIZE_MAX / arr->elem_size) {
@@ -377,3 +427,180 @@ ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve) {
arr->capacity += size_to_reserve; arr->capacity += size_to_reserve;
return ARRLIST_OK; return ARRLIST_OK;
} }
ArraySlice *arraylist_slice(ArrayList *arr, size_t start, size_t len) {
if (arr == NULL) {
return NULL;
}
if (arr->len == 0 || len == 0) {
return NULL;
}
if (start > SIZE_MAX / arr->elem_size || len > SIZE_MAX / arr->elem_size) {
return NULL;
}
if (start + len > arr->len) {
return NULL;
}
ArraySlice *slice = malloc(sizeof(ArraySlice));
if (slice == NULL) {
return NULL;
}
slice->arr = arr;
slice->start = start;
slice->end = start + len;
slice->current = start;
slice->is_safe = true;
arr->borrows++;
return slice;
}
ArraySlice *arraylist_slice_unsafe(ArrayList *arr, size_t start, size_t len) {
if (arr == NULL) {
return NULL;
}
if (arr->len == 0 || len == 0) {
return NULL;
}
if (start > SIZE_MAX / arr->elem_size || len > SIZE_MAX / arr->elem_size) {
return NULL;
}
if (start + len > arr->len) {
return NULL;
}
ArraySlice *slice = malloc(sizeof(ArraySlice));
if (slice == NULL) {
return NULL;
}
slice->arr = arr;
slice->start = start;
slice->end = start + len;
slice->current = start;
slice->is_safe = false;
return slice;
}
ArrayListErr arrayslice_destroy(ArraySlice **slice) {
if (slice == NULL || *slice == NULL) {
return ARRLIST_NULL_ARG;
}
if ((*slice)->is_safe) {
(*slice)->arr->borrows--;
}
free(*slice);
*slice = NULL;
return ARRLIST_OK;
}
bool arrayslice_is_valid(const ArraySlice *slice) {
if (slice == NULL) {
return false;
}
return slice->current != slice->end;
}
size_t arrayslice_size(const ArraySlice *slice) {
if (slice == NULL) {
return 0;
}
return slice->end - slice->start;
}
ArrayListErr arrayslice_peek(const ArraySlice *slice, void *out) {
if (slice == NULL || out == NULL) {
return ARRLIST_NULL_ARG;
}
if (slice->current >= slice->end) {
return ARRLIST_INVALID_SLICE;
}
arraylist_get(slice->arr, slice->current, out);
return ARRLIST_OK;
}
ArrayListErr arrayslice_next(ArraySlice *slice, void *out) {
// HERE, it makes sense that you want to advance to the next
// without actually getting the value so it's good
if (slice == NULL) {
return ARRLIST_NULL_ARG;
}
if (slice->current == slice->end) {
return ARRLIST_INVALID_SLICE;
}
arraylist_get(slice->arr, slice->current, out);
slice->current++;
return ARRLIST_OK;
}
ArrayListErr arrayslice_reset(ArraySlice *slice) {
if (slice == NULL) {
return ARRLIST_NULL_ARG;
}
slice->current = slice->start;
return ARRLIST_OK;
}
ArrayListErr arrayslice_advance(ArraySlice *slice, size_t n) {
if (slice == NULL) {
return ARRLIST_NULL_ARG;
}
if (n > SIZE_MAX - slice->current || slice->current + n > slice->end) {
return ARRLIST_OUT_OF_BOUNDS;
}
slice->current += n;
return ARRLIST_OK;
}
ArrayList *arrayslice_to_arraylist(const ArraySlice *slice) {
if (slice == NULL || slice->arr == NULL) {
return NULL;
}
if (slice->start >= slice->end) {
return NULL;
}
size_t len = slice->end - slice->start;
ArrayList *new_arr = arraylist_init(arraylist_capacity(slice->arr), slice->arr->elem_size);
if (new_arr == NULL) {
return NULL;
}
memcpy(
new_arr->buffer,
slice->arr->buffer + (slice->start * slice->arr->elem_size),
slice->arr->elem_size * len
);
new_arr->len = len;
return new_arr;
}

File diff suppressed because it is too large Load Diff