LinkedList new functions and fixes

This commit is contained in:
timerix 2023-03-15 05:52:33 +06:00
parent 6c6c4fff8b
commit a200f2c965
4 changed files with 81 additions and 36 deletions

View File

@ -1,3 +1,68 @@
#include "LinkedList.h" #include "LinkedList.h"
LinkedList_define(Pointer, true) LinkedList_define(Pointer, true)
void LinkedList_addToBeginning(void* _llist, void* _new_node) {
LinkedList(Pointer)* llist=_llist;
LLNode(Pointer)* new_node=_new_node;
llist->count++;
if(llist->last_node==NULL){
if(llist->first_node!=NULL)
throw(ERR_NULLPTR); // last_node can't be null if first_node != null
llist->last_node=new_node;
}
else {
llist->first_node->prev=new_node;
new_node->next=llist->first_node;
}
llist->first_node=new_node;
}
void LinkedList_addToEnd(void* _llist, void* _new_node) {
LinkedList(Pointer)* llist=_llist;
LLNode(Pointer)* new_node=_new_node;
llist->count++;
if(llist->first_node==NULL) {
if(llist->last_node!=NULL)
throw(ERR_NULLPTR); // first_node can't be null if last_node != null
llist->first_node=new_node;
}
else {
llist->last_node->next=new_node;
new_node->prev=llist->last_node;
}
llist->last_node=new_node;
}
static inline void _insertNode(LinkedList(Pointer)* llist,
LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){
if(prev_node==NULL){
if(next_node==llist->first_node)
LinkedList_addToBeginning(llist, new_node);
else throw(ERR_NULLPTR); // prev_node is null, but it isn't insertion before first_node
}
else if(next_node==NULL){
if(prev_node==llist->last_node)
LinkedList_addToEnd(llist, new_node);
else throw(ERR_NULLPTR); // next_node is null, but it isn't insertion after last_node
}
else {
prev_node->next=new_node;
new_node->prev=prev_node;
new_node->next=next_node;
next_node->prev=new_node;
llist->count++;
}
}
void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node){
LLNode(Pointer)* next_node=_next_node;
LLNode(Pointer)* prev_node=next_node->prev;
_insertNode(_llist, prev_node, _new_node, next_node);
}
void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node){
LLNode(Pointer)* prev_node=_prev_node;
LLNode(Pointer)* next_node=prev_node->next;
_insertNode(_llist, prev_node, _new_node, next_node);
}

View File

@ -13,14 +13,20 @@ extern "C" {
#define LLNode(TYPE) LLNode_##TYPE #define LLNode(TYPE) LLNode_##TYPE
#define LinkedList(TYPE) LinkedList_##TYPE #define LinkedList(TYPE) LinkedList_##TYPE
#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE)
#define LinkedList_create(TYPE) LinkedList_##TYPE##_create() #define LinkedList_create(TYPE) LinkedList_##TYPE##_create()
#define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); }) #define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); })
void LinkedList_addToBeginning(void* _llist, void* _new_node);
void LinkedList_addToEnd(void* _llist, void* _new_node);
/// inserts NEW_NODE before NEXT_NODE in LLIST /// inserts NEW_NODE before NEXT_NODE in LLIST
#define LinkedList_insertPrev(LLIST, NEW_NODE, NEXT_NODE) LLIST->_functions->insertPrev(LLIST, NEW_NODE, NEXT_NODE) void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node);
/// inserts NEW_NODE after PREV_NODE in LLIST /// inserts NEW_NODE after PREV_NODE in LLIST
#define LinkedList_insertNext(LLIST, NEW_NODE, PREV_NODE) LLIST->_functions->insertNext(LLIST, NEW_NODE, PREV_NODE) void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node);
/// removes node before NEXT_NODE in LLIST /// removes node before NEXT_NODE in LLIST
/// if FREE_REMOVED then frees removed node /// if FREE_REMOVED then frees removed node
@ -35,9 +41,11 @@ extern "C" {
///@param CODE code todo in every iteration ///@param CODE code todo in every iteration
#define LLNode_foreach(FIRST_N, CURR_N, CODE...) { \ #define LLNode_foreach(FIRST_N, CURR_N, CODE...) { \
typeof(FIRST_N) CURR_N=FIRST_N; \ typeof(FIRST_N) CURR_N=FIRST_N; \
typeof(FIRST_N) NEXT_N=FIRST_N; \
while(CURR_N!=NULL) { \ while(CURR_N!=NULL) { \
NEXT_N=CURR_N->next; \
CODE; \ CODE; \
CURR_N=CURR_N->next; \ CURR_N=NEXT_N; \
} \ } \
} }
@ -46,9 +54,11 @@ extern "C" {
///@param CODE code todo in every iteration ///@param CODE code todo in every iteration
#define LLNode_foreachReverse(FIRST_N, CURR_N, CODE...) { \ #define LLNode_foreachReverse(FIRST_N, CURR_N, CODE...) { \
typeof(FIRST_N) CURR_N=FIRST_N; \ typeof(FIRST_N) CURR_N=FIRST_N; \
typeof(FIRST_N) PREV_N=FIRST_N; \
while(CURR_N!=NULL) { \ while(CURR_N!=NULL) { \
PREV_N=CURR_N->prev; \
CODE; \ CODE; \
CURR_N=CURR_N->prev; \ CURR_N=PREV_N; \
} \ } \
} }

View File

@ -11,8 +11,7 @@ STRUCT(LLNode(TYPE), \
TYPE value; \ TYPE value; \
) \ ) \
\ \
LLNode(TYPE)* LLNode_##TYPE##_create(); \ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \
LLNode(TYPE)* LLNode_##TYPE##_createFromValue(TYPE value); \
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value); void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value);
@ -29,8 +28,6 @@ STRUCT(LinkedList(TYPE), \
\ \
typedef struct LinkedList_##TYPE##_functions_t { \ typedef struct LinkedList_##TYPE##_functions_t { \
freeMembers_t freeMembers; \ freeMembers_t freeMembers; \
void (*insertPrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* newNode, LLNode(TYPE)* nextNode); \
void (*insertNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* newNode, LLNode(TYPE)* prevNode); \
void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \ void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \
void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \ void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \
} LinkedList_##TYPE##_functions_t; \ } LinkedList_##TYPE##_functions_t; \

View File

@ -5,15 +5,8 @@ extern "C" {
#endif #endif
#define LLNode_define(TYPE, TYPE_IS_PTR)\ #define LLNode_define(TYPE, TYPE_IS_PTR)\
LLNode(TYPE)* LLNode_##TYPE##_create(){ \
LLNode(TYPE)* node= (LLNode(TYPE)*)malloc(sizeof(*node)); \
node->prev=NULL; \
node->next=NULL; \
node->value=(TYPE){0}; \
return node; \
} \
\ \
LLNode(TYPE)* LLNode_##TYPE##_createFromValue(TYPE value){ \ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value){ \
LLNode(TYPE)* node= (LLNode(TYPE)*)malloc(sizeof(*node)); \ LLNode(TYPE)* node= (LLNode(TYPE)*)malloc(sizeof(*node)); \
node->prev=NULL; \ node->prev=NULL; \
node->next=NULL; \ node->next=NULL; \
@ -26,14 +19,10 @@ void LLNode_##TYPE##_freeMembers(void* _node){ \
void* value_ptr=&node->value; \ void* value_ptr=&node->value; \
if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \ if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \
ktDescriptor_##TYPE.freeMembers(value_ptr); \ ktDescriptor_##TYPE.freeMembers(value_ptr); \
if(node->prev) node->prev->next=NULL; \
if(node->next) node->next->prev=NULL; \
} \ } \
\ \
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \ void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \
if(free_value) LLNode_##TYPE##_freeMembers(node); \ if(free_value) LLNode_##TYPE##_freeMembers(node); \
if(node->prev) node->prev->next=NULL; \
if(node->next) node->next->prev=NULL; \
free(node); \ free(node); \
} \ } \
\ \
@ -59,20 +48,6 @@ void LinkedList_##TYPE##_freeMembers(void* _l){ \
l->first_node=NULL; l->last_node=NULL; l->count=0; \ l->first_node=NULL; l->last_node=NULL; l->count=0; \
} \ } \
\ \
void LinkedList_##TYPE##_insertPrev(LinkedList(TYPE)* llist, LLNode(TYPE)* newNode, LLNode(TYPE)* nextNode){ \
llist->count++; \
newNode->prev=nextNode->prev; \
newNode->next=nextNode; \
nextNode->prev=newNode; \
} \
\
void LinkedList_##TYPE##_insertNext(LinkedList(TYPE)* llist, LLNode(TYPE)* newNode, LLNode(TYPE)* prevNode){ \
llist->count++; \
newNode->prev=prevNode; \
newNode->next=prevNode->next; \
prevNode->next=newNode; \
} \
\
void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved){ \ void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved){ \
llist->count--; \ llist->count--; \
LLNode(TYPE)* removedNode=nextNode->prev; \ LLNode(TYPE)* removedNode=nextNode->prev; \
@ -95,8 +70,6 @@ void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevN
\ \
LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \ LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \
.freeMembers=LinkedList_##TYPE##_freeMembers, \ .freeMembers=LinkedList_##TYPE##_freeMembers, \
.insertPrev=LinkedList_##TYPE##_insertPrev, \
.insertNext=LinkedList_##TYPE##_insertNext, \
.removePrev=LinkedList_##TYPE##_removePrev, \ .removePrev=LinkedList_##TYPE##_removePrev, \
.removeNext=LinkedList_##TYPE##_removeNext \ .removeNext=LinkedList_##TYPE##_removeNext \
}; \ }; \