diff options
| author | Mosder <xmosder12@gmail.com> | 2026-08-15 01:14:52 +0200 |
|---|---|---|
| committer | Mosder <xmosder12@gmail.com> | 2026-08-15 01:14:52 +0200 |
| commit | 3727b8b1308f731b86a6ff666ee75f44fe113674 (patch) | |
| tree | 58a8b48f85d1785c7214798d8ee900d0e8d7b234 /include | |
| parent | 8a37a456ec3fd4c9a270d8dca487ed19b8172407 (diff) | |
implemented dynamic array
Diffstat (limited to 'include')
| -rw-r--r-- | include/moslib/ds/array.h | 120 | ||||
| -rw-r--r-- | include/moslib/tester.h | 6 |
2 files changed, 75 insertions, 51 deletions
diff --git a/include/moslib/ds/array.h b/include/moslib/ds/array.h index 41164c5..ac8b9f9 100644 --- a/include/moslib/ds/array.h +++ b/include/moslib/ds/array.h @@ -47,18 +47,18 @@ // // To put into specific index (and update if value exists) use: // -// size_t zerod = arr_put(array, i, item); +// size_t index = arr_put(array, i, item); // +// It returns the index of the newly put item // If index is greater or equal to array length it will extend the length to the put item and it will // zero all items between previously last item to the new item. -// It returns the count of items that were zerod that way. // // If you want to add more items than 1 at once, you can use these: // // size_t index = arr_append_n(array, items, n_items); // size_t index = arr_push_n(array, items, n_items); // size_t index = arr_insert_n(array, i, items, n_items); -// size_t zerod = arr_put_n(array, i, items, n_items); +// size_t index = arr_put_n(array, i, items, n_items); // // They work the same way as their counterparts without n, but accept an array of items instead. // @@ -70,15 +70,15 @@ // // First array will be the destination. // Returns index of the first item of array2 in array1. +// If array 2 is NULL or has length 0 - returns (size_t)-1. // // ---------------------------------------------------------------------------------------------------- // -// To delete item from an array at specific index and retrieve it you can use: +// To delete and retrieve the last item from an array use: // -// T item = arr_pop_i(array, i); -// T item = arr_pop(array); // same as arr_pop_i(array, arr_len(array)-1) +// T item = arr_pop(array); // -// No bounds checking, so it may return garbage or segfault. +// No bounds checking, so it may return garbage or segfault if the array is empty. // // You can just delete items on given index with: // @@ -165,7 +165,6 @@ #define arr_insert_n mos_arr_insert_n #define arr_put_n mos_arr_put_n #define arr_concat mos_arr_concat -#define arr_pop_i mos_arr_pop_i #define arr_pop mos_arr_pop #define arr_del mos_arr_del #define arr_del_n mos_arr_del_n @@ -195,7 +194,7 @@ // // Returns: // pointer to the item or NULL if i is out of bounds -#define mos_arr_get(arr, i) ((arr) ? (arr) : NULL) +#define mos_arr_get(arr, i) ((size_t)(i) < mos_arr_len(arr) ? (arr) + (size_t)(i) : NULL) // Get a pointer to the first item in the array // @@ -205,7 +204,7 @@ // // Returns: // pointer to the first item or NULL if array is empty -#define mos_arr_first(arr) NULL +#define mos_arr_first(arr) (mos_arr_len(arr) == 0 ? NULL : (arr)) // Get a pointer to the last item in the array // @@ -215,7 +214,9 @@ // // Returns: // pointer to the last item or NULL if array is empty -#define mos_arr_last(arr) NULL +#define mos_arr_last(arr) (mos_arr_len(arr) == 0 ? NULL : (arr) + mos_arr_len(arr) - 1) + +// clang-format off // Append a given item to the array // @@ -229,8 +230,12 @@ // // Returns: // index of the appended item -#define mos_arr_append(arr, ...) (!(arr) ? (arr) = mos_safe_malloc(sizeof(*(arr))) : 0, *(arr) = (__VA_ARGS__)) #define mos_arr_push mos_arr_append +#define mos_arr_append(arr, ...) ( \ + mos_arr_append_fn(&(arr), sizeof(*(arr))), \ + (arr)[mos_arr_len(arr) - 1] = __VA_ARGS__, \ + mos_arr_len(arr) - 1 \ +) // Insert a given item at the specific position in the array // Move everything after it to the right @@ -249,7 +254,15 @@ // // Returns: // index of the inserted item -#define mos_arr_insert(arr, i, ...) 0 +#define mos_arr_insert(arr, i, ...) ( \ + (size_t)(i) >= mos_arr_len(arr) ? ( \ + mos_arr_append(arr, __VA_ARGS__) \ + ) : ( \ + mos_arr_insert_fn(&(arr), i, sizeof(*(arr))), \ + (arr)[(size_t)(i)] = __VA_ARGS__, \ + (size_t)(i) \ + ) \ +) // Put a given item at the specific position in the array // If index is within array bounds - it overwrites the item at given spot @@ -268,8 +281,14 @@ // variadic to make things like (struct T){1,1} work properly // // Returns: -// count of zerod items -#define mos_arr_put(arr, i, ...) 0 +// index of the put item +#define mos_arr_put(arr, i, ...) ( \ + mos_arr_put_fn(&(arr), i, sizeof(*(arr))), \ + (arr)[(size_t)(i)] = __VA_ARGS__, \ + (size_t)(i) \ +) + +// clang-format on // Append n given items to the array // @@ -285,8 +304,8 @@ // // Returns: // index of the first appended item -#define mos_arr_append_n(arr, items, n) (!(arr) ? (arr) = mos_safe_malloc(sizeof(*(arr))) : 0, *(arr) = (items)[0]) #define mos_arr_push_n mos_arr_append_n +#define mos_arr_append_n(arr, items, n) mos_arr_append_n_fn(&(arr), items, n, sizeof(*(arr))) // Insert n given items at the specific position in the array // Move everything after them to the right @@ -307,7 +326,7 @@ // // Returns: // index of the first inserted item -#define mos_arr_insert_n(arr, i, items, n) 0 +#define mos_arr_insert_n(arr, i, items, n) mos_arr_insert_n_fn(&(arr), i, items, n, sizeof(*(arr))) // Put n given items at the specific position in the array // If index is within array bounds - it overwrites the items at given spots @@ -328,8 +347,8 @@ // count of items to put // // Returns: -// count of zerod items -#define mos_arr_put_n(arr, i, items, n) 0 +// index of the first put item +#define mos_arr_put_n(arr, i, items, n) mos_arr_put_n_fn(&(arr), i, items, n, sizeof(*(arr))) // Concatenate two dynamic arrays of the same type // @@ -341,23 +360,8 @@ // array to concatenate (source) // // Returns: -// index of the first new item in arr1 -#define mos_arr_concat(arr1, arr2) 0 - -// Delete and retrieve an item at specific index from the array -// Moves items after deleted one to the left -// No bounds checking -// -// Arguments: -// arr -// array to pop from -// -// i -// index of the item to pop -// -// Returns: -// the popped item -#define mos_arr_pop_i(arr, i) (arr)[0] +// index of the first new item in arr1 or (size_t)-1 if arr2 is NULL or has length 0 +#define mos_arr_concat(arr1, arr2) mos_arr_concat_fn(&(arr1), arr2, sizeof(*(arr1))) // Delete and retrieve the last item from the array // No bounds checking @@ -368,7 +372,7 @@ // // Returns: // the popped item -#define mos_arr_pop(arr) (arr)[0] +#define mos_arr_pop(arr) (mos_arr_del_back(arr, 1), (arr)[mos_arr_len(arr)]) // Delete an item at specific index from the array // Moves items after deleted one to the left @@ -382,7 +386,7 @@ // // Returns: // 1 if item was deleted, 0 if it failed (e.g. out of bounds) -#define mos_arr_del(arr, i) 0 +#define mos_arr_del(arr, i) mos_arr_del_fn(arr, i, sizeof(*(arr))) // Delete n consecutive items at specific index from the array // Moves items after deleted ones to the left @@ -399,7 +403,7 @@ // // Returns: // count of deleted items -#define mos_arr_del_n(arr, i, n) 0 +#define mos_arr_del_n(arr, i, n) mos_arr_del_n_fn(arr, i, n, sizeof(*(arr))) // Delete n first items from the array // Moves items after deleted ones to the left @@ -413,7 +417,7 @@ // // Returns: // count of deleted items -#define mos_arr_del_front(arr, n) 0 +#define mos_arr_del_front(arr, n) mos_arr_del_front_fn(arr, n, sizeof(*(arr))) // Delete n last items from the array // @@ -426,7 +430,7 @@ // // Returns: // count of deleted items -#define mos_arr_del_back(arr, n) 0 +#define mos_arr_del_back(arr, n) mos_arr_del_back_fn(arr, n) // Get the pointer to the previous item in the array from the pointer to the current one // If pointer is NULL - gets the last item from the array @@ -440,7 +444,7 @@ // // Returns: // pointer to the previous item or NULL if there's no more items -#define mos_arr_prev(arr, curr) NULL +#define mos_arr_prev(arr, curr) (mos_arr_len(arr) == 0 ? NULL : (!(curr) ? mos_arr_last(arr) : ((curr) == (arr) ? NULL : (curr) - 1))) // Get the pointer to the next item in the array from the pointer to the current one // If pointer is NULL - gets the first item from the array @@ -454,7 +458,7 @@ // // Returns: // pointer to the next item or NULL if there's no more items -#define mos_arr_next(arr, curr) NULL +#define mos_arr_next(arr, curr) (mos_arr_len(arr) == 0 ? NULL : (!(curr) ? (arr) : ((curr) == mos_arr_last(arr) ? NULL : (curr) + 1))) // Get the length of the array // @@ -464,7 +468,7 @@ // // Returns: // length of the array -#define mos_arr_len(arr) 0 +extern size_t mos_arr_len(void *arr); // Set the length of the array // If it's bigger than current length - it will zero new items @@ -479,7 +483,7 @@ // // Returns: // count of the deleted items -#define mos_arr_set_len(arr, len) 0 +#define mos_arr_set_len(arr, len) mos_arr_set_len_fn(&(arr), len, sizeof(*(arr))) // Get the capacity of the array // @@ -489,7 +493,7 @@ // // Returns: // capacity of the array -#define mos_arr_cap(arr) 0 +extern size_t mos_arr_cap(void *arr); // Set the capacity of the array // If it's lower than current length - it will set the capacity equal to length @@ -503,13 +507,33 @@ // // Returns: // new capacity of the array -#define mos_arr_set_cap(arr, cap) 0 +#define mos_arr_set_cap(arr, cap) mos_arr_set_cap_fn(&(arr), cap, sizeof(*(arr))) // Free the array // // Arguments: // arr // array to free -#define mos_arr_free(arr) void +extern void mos_arr_free(void *arr); + +typedef struct { + size_t len; + size_t cap; +} MosArrHeader; + +// Function prototypes for macros +extern void mos_arr_append_fn(void *p_arr, size_t el_size); +extern void mos_arr_insert_fn(void *p_arr, size_t i, size_t el_size); +extern void mos_arr_put_fn(void *p_arr, size_t i, size_t el_size); +extern size_t mos_arr_append_n_fn(void *p_arr, void *items, size_t n, size_t el_size); +extern size_t mos_arr_insert_n_fn(void *p_arr, size_t i, void *items, size_t n, size_t el_size); +extern size_t mos_arr_put_n_fn(void *p_arr, size_t i, void *items, size_t n, size_t el_size); +extern size_t mos_arr_concat_fn(void *p_arr, void *arr2, size_t el_size); +extern size_t mos_arr_del_fn(void *arr, size_t i, size_t el_size); +extern size_t mos_arr_del_n_fn(void *arr, size_t i, size_t n, size_t el_size); +extern size_t mos_arr_del_front_fn(void *arr, size_t n, size_t el_size); +extern size_t mos_arr_del_back_fn(void *arr, size_t n); +extern size_t mos_arr_set_len_fn(void *p_arr, size_t len, size_t el_size); +extern size_t mos_arr_set_cap_fn(void *p_arr, size_t cap, size_t el_size); #endif // MOSLIB_DS_ARRAY_H diff --git a/include/moslib/tester.h b/include/moslib/tester.h index aa0adb2..ae41629 100644 --- a/include/moslib/tester.h +++ b/include/moslib/tester.h @@ -124,7 +124,7 @@ extern MosTester *mos_new_tester(void); // // Returns: // pointer to the added group -#define mos_add_test_group(tester, group_name) ((!(tester) ? (tester) = mos_new_tester() : 0), mos_add_test_group_fn((tester), (group_name))) +#define mos_add_test_group(tester, group_name) ((!(tester) ? (tester) = mos_new_tester() : 0), mos_add_test_group_fn(tester, group_name)) // Assert that an expression is true // Use in test functions to test correctness @@ -146,7 +146,7 @@ extern void mos_test_assert(int expression, const char *fail_message); // // code // expected exit code -#define mos_test_assert_exit(function, code) mos_test_assert_exit_fn((function), (code), #function); +#define mos_test_assert_exit(function, code) mos_test_assert_exit_fn(function, code, #function); // Suppress given output // @@ -167,7 +167,7 @@ extern void mos_unsuppress_outputs(void); // // test // test to add to the group -#define mos_add_test(group, test) mos_add_test_fn((group), (test), #test); +#define mos_add_test(group, test) mos_add_test_fn(group, test, #test); // Run defined tests // |
