diff --git a/src/LinkedList/LinkedList.c b/src/LinkedList/LinkedList.c index a6302ed..26732c6 100644 --- a/src/LinkedList/LinkedList.c +++ b/src/LinkedList/LinkedList.c @@ -1,3 +1,68 @@ #include "LinkedList.h" 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); +} diff --git a/src/LinkedList/LinkedList.h b/src/LinkedList/LinkedList.h index 6283ad7..441d6bf 100644 --- a/src/LinkedList/LinkedList.h +++ b/src/LinkedList/LinkedList.h @@ -13,14 +13,20 @@ extern "C" { #define LLNode(TYPE) LLNode_##TYPE #define LinkedList(TYPE) LinkedList_##TYPE +#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE) + #define LinkedList_create(TYPE) LinkedList_##TYPE##_create() #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 -#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 -#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 /// if FREE_REMOVED then frees removed node @@ -35,9 +41,11 @@ extern "C" { ///@param CODE code todo in every iteration #define LLNode_foreach(FIRST_N, CURR_N, CODE...) { \ typeof(FIRST_N) CURR_N=FIRST_N; \ + typeof(FIRST_N) NEXT_N=FIRST_N; \ while(CURR_N!=NULL) { \ + NEXT_N=CURR_N->next; \ CODE; \ - CURR_N=CURR_N->next; \ + CURR_N=NEXT_N; \ } \ } @@ -46,9 +54,11 @@ extern "C" { ///@param CODE code todo in every iteration #define LLNode_foreachReverse(FIRST_N, CURR_N, CODE...) { \ typeof(FIRST_N) CURR_N=FIRST_N; \ + typeof(FIRST_N) PREV_N=FIRST_N; \ while(CURR_N!=NULL) { \ + PREV_N=CURR_N->prev; \ CODE; \ - CURR_N=CURR_N->prev; \ + CURR_N=PREV_N; \ } \ } diff --git a/src/LinkedList/LinkedList_declare.h b/src/LinkedList/LinkedList_declare.h index 418a722..a0f4c9e 100644 --- a/src/LinkedList/LinkedList_declare.h +++ b/src/LinkedList/LinkedList_declare.h @@ -11,8 +11,7 @@ STRUCT(LLNode(TYPE), \ TYPE value; \ ) \ \ -LLNode(TYPE)* LLNode_##TYPE##_create(); \ -LLNode(TYPE)* LLNode_##TYPE##_createFromValue(TYPE value); \ +LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \ void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value); @@ -29,8 +28,6 @@ STRUCT(LinkedList(TYPE), \ \ typedef struct LinkedList_##TYPE##_functions_t { \ 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 (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \ } LinkedList_##TYPE##_functions_t; \ diff --git a/src/LinkedList/LinkedList_define.h b/src/LinkedList/LinkedList_define.h index 2ea4e16..f978638 100644 --- a/src/LinkedList/LinkedList_define.h +++ b/src/LinkedList/LinkedList_define.h @@ -5,15 +5,8 @@ extern "C" { #endif #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)); \ node->prev=NULL; \ node->next=NULL; \ @@ -26,14 +19,10 @@ void LLNode_##TYPE##_freeMembers(void* _node){ \ void* value_ptr=&node->value; \ if(TYPE_IS_PTR) value_ptr=*(TYPE**)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){ \ if(free_value) LLNode_##TYPE##_freeMembers(node); \ - if(node->prev) node->prev->next=NULL; \ - if(node->next) node->next->prev=NULL; \ free(node); \ } \ \ @@ -59,20 +48,6 @@ void LinkedList_##TYPE##_freeMembers(void* _l){ \ 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){ \ llist->count--; \ 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={ \ .freeMembers=LinkedList_##TYPE##_freeMembers, \ - .insertPrev=LinkedList_##TYPE##_insertPrev, \ - .insertNext=LinkedList_##TYPE##_insertNext, \ .removePrev=LinkedList_##TYPE##_removePrev, \ .removeNext=LinkedList_##TYPE##_removeNext \ }; \