mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 09:58:03 +02:00
FFlist: adds FF_LIST_INSERT_AT and FF_LIST_REMOVE_AT
This commit is contained in:
+22
-2
@@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FF_LIST_DEFAULT_ALLOC 16
|
||||
|
||||
@@ -110,6 +111,19 @@ static inline void* ffListAdd(FFlist* list, uint32_t elementSize) {
|
||||
return ffListGet(list, elementSize, list->length - 1);
|
||||
}
|
||||
|
||||
static inline void ffListRemoveAt(FFlist* list, uint32_t elementSize, uint32_t index) {
|
||||
assert(list->length > index);
|
||||
memmove(list->data + (index * elementSize), list->data + ((index + 1) * elementSize), (size_t) (list->length - index - 1) * elementSize);
|
||||
--list->length;
|
||||
}
|
||||
|
||||
static inline void ffListInsertAt(FFlist* list, uint32_t elementSize, uint32_t index, const void* element) {
|
||||
assert(list->length >= index);
|
||||
ffListAdd(list, elementSize);
|
||||
memmove(list->data + ((index + 1) * elementSize), list->data + (index * elementSize), (size_t) (list->length - index - 1) * elementSize);
|
||||
memcpy(list->data + (index * elementSize), element, elementSize);
|
||||
}
|
||||
|
||||
#define FF_LIST_FOR_EACH(itemType, itemVarName, listVar) \
|
||||
for (itemType* itemVarName = (itemType*) (listVar).data; \
|
||||
itemVarName - (itemType*) (listVar).data < (intptr_t) (listVar).length; \
|
||||
@@ -125,6 +139,12 @@ static inline void* ffListAdd(FFlist* list, uint32_t elementSize) {
|
||||
|
||||
#define FF_LIST_ADD(itemType, listVar) (itemType*) ffListAdd(&(listVar), (uint32_t) sizeof(itemType))
|
||||
|
||||
#define FF_LIST_REMOVE_AT(itemType, listVar, index) \
|
||||
ffListRemoveAt(&(listVar), (uint32_t) sizeof(itemType), (index))
|
||||
|
||||
#define FF_LIST_INSERT_AT(itemType, listVar, index, pElement) \
|
||||
ffListInsertAt(&(listVar), (uint32_t) sizeof(itemType), (index), (pElement))
|
||||
|
||||
#define FF_LIST_FIRST(itemType, listVar) FF_LIST_GET(itemType, listVar, 0)
|
||||
#define FF_LIST_LAST(itemType, listVar) \
|
||||
({ \
|
||||
@@ -134,9 +154,9 @@ static inline void* ffListAdd(FFlist* list, uint32_t elementSize) {
|
||||
|
||||
#define FF_LIST_CONTAINS(listVar, pCompElement, compFunc) \
|
||||
({ \
|
||||
typedef typeof(*(pCompElement)) compElementType; \
|
||||
typedef typeof(*(pCompElement)) compElementType; \
|
||||
typedef bool compFuncType(const compElementType*, const compElementType*); \
|
||||
static_assert(__builtin_types_compatible_p(typeof(compFunc), compFuncType), "Incompatible callback function"); \
|
||||
static_assert(__builtin_types_compatible_p(typeof(compFunc), compFuncType), "Incompatible callback function"); \
|
||||
ffListContains(&(listVar), (uint32_t) sizeof(*(pCompElement)), (pCompElement), (bool (*)(const void*, const void*)) compFunc); \
|
||||
})
|
||||
|
||||
|
||||
@@ -100,6 +100,79 @@ int main(void) {
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, list.length - 1) == FF_LIST_DEFAULT_ALLOC);
|
||||
|
||||
// insertAt
|
||||
ffListClear(&list);
|
||||
for (uint32_t i = 1; i <= 5; ++i) {
|
||||
*FF_LIST_ADD(uint32_t, list) = i;
|
||||
}
|
||||
// list = [1,2,3,4,5]
|
||||
|
||||
{
|
||||
uint32_t v = 0;
|
||||
FF_LIST_INSERT_AT(uint32_t, list, 0, &v); // insert at head
|
||||
}
|
||||
VERIFY(list.length == 6);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 0);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 1) == 1);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 5) == 5);
|
||||
// list = [0,1,2,3,4,5]
|
||||
|
||||
{
|
||||
uint32_t v = 99;
|
||||
FF_LIST_INSERT_AT(uint32_t, list, 3, &v); // insert in the middle
|
||||
}
|
||||
VERIFY(list.length == 7);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 2) == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 3) == 99);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 4) == 3);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 6) == 5);
|
||||
// list = [0,1,2,99,3,4,5]
|
||||
|
||||
{
|
||||
uint32_t v = 6;
|
||||
FF_LIST_INSERT_AT(uint32_t, list, list.length, &v); // insert at tail
|
||||
}
|
||||
VERIFY(list.length == 8);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 3) == 99);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 7) == 6);
|
||||
// list = [0,1,2,99,3,4,5,6]
|
||||
|
||||
ffListClear(&list);
|
||||
{
|
||||
uint32_t v = 42;
|
||||
FF_LIST_INSERT_AT(uint32_t, list, 0, &v); // insert into empty list
|
||||
}
|
||||
VERIFY(list.length == 1);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 42);
|
||||
|
||||
// removeAt
|
||||
FF_LIST_REMOVE_AT(uint32_t, list, 0); // remove the only element
|
||||
VERIFY(list.length == 0);
|
||||
|
||||
for (uint32_t i = 1; i <= 5; ++i) {
|
||||
*FF_LIST_ADD(uint32_t, list) = i;
|
||||
}
|
||||
// list = [1,2,3,4,5]
|
||||
|
||||
FF_LIST_REMOVE_AT(uint32_t, list, 0); // remove head
|
||||
VERIFY(list.length == 4);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, list.length - 1) == 5);
|
||||
// list = [2,3,4,5]
|
||||
|
||||
FF_LIST_REMOVE_AT(uint32_t, list, 1); // remove in the middle
|
||||
VERIFY(list.length == 3);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 1) == 4);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 2) == 5);
|
||||
// list = [2,4,5]
|
||||
|
||||
FF_LIST_REMOVE_AT(uint32_t, list, list.length - 1); // remove tail
|
||||
VERIFY(list.length == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 0) == 2);
|
||||
VERIFY(*FF_LIST_GET(uint32_t, list, 1) == 4);
|
||||
// list = [2,4]
|
||||
|
||||
// Destroy
|
||||
ffListDestroy(&list);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user