Created
September 21, 2016 00:38
-
-
Save ShawnMcGrath/9d210624b9f28822172905ecdb0808fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MG_LINKEDLIST_EXTERN | |
#define MG_LINKEDLIST_EXTERN extern | |
#endif | |
#ifndef MG_LINKEDLIST_INTERN | |
#define MG_LINKEDLIST_INTERN static | |
#endif | |
//mandatory | |
#ifndef MG_LINKEDLIST_TYPE | |
#error "Must #define MG_LINKEDLIST_TYPE" | |
#endif | |
//optional | |
#ifndef MG_LINKEDLIST_NEXT_NAME | |
#define MG_LINKEDLIST_NEXT_NAME next | |
#endif | |
#ifndef MG_LINKEDLIST_PREV_NAME | |
#define MG_LINKEDLIST_PREV_NAME prev | |
#endif | |
/*MG_LINKEDLIST_FN_EXT | |
if you specify this, all linked list functions will be: | |
mgll_fnNameMG_LINKEDLIST_FN_EXT(..) | |
if you don't specify it, then it'll rely on C++ overloading and just make the functions: | |
mggl_fnName(..) | |
*/ | |
#define __MG_LINKEDLIST_JOIN_HELPER(name0, name1) name0## ##name1 | |
#define __MG_LINKEDLIST_JOIN2(name0, name1) __MG_LINKEDLIST_JOIN_HELPER(name0, name1) | |
#ifdef MG_LINKEDLIST_FN_EXT | |
#define __MG_LINKEDLIST_FN(ret, name, ...) ret __MG_LINKEDLIST_JOIN2(mgll_##name, MG_LINKEDLIST_FN_EXT)(__VA_ARGS__) | |
#else | |
#define __MG_LINKEDLIST_FN(ret, name, ...) ret mgll_##name(__VA_ARGS__) | |
#endif | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(MG_LINKEDLIST_TYPE *, getLast, MG_LINKEDLIST_TYPE *list) { | |
while (list) { | |
if (!list->MG_LINKEDLIST_NEXT_NAME) { | |
return list; | |
} | |
list = list->MG_LINKEDLIST_NEXT_NAME; | |
} | |
return list; | |
} | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(int, getCount, MG_LINKEDLIST_TYPE *list) { | |
int c = 0; | |
while (list) { | |
list = list->next; | |
++c; | |
} | |
return c; | |
} | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(void, addToListFront, MG_LINKEDLIST_TYPE *element, MG_LINKEDLIST_TYPE **first_element) { | |
element->MG_LINKEDLIST_NEXT_NAME = *first_element; | |
if (*first_element) { | |
if ((*first_element)->MG_LINKEDLIST_PREV_NAME) { | |
(*first_element)->MG_LINKEDLIST_PREV_NAME->MG_LINKEDLIST_NEXT_NAME = element; | |
element->MG_LINKEDLIST_PREV_NAME = (*first_element)->MG_LINKEDLIST_PREV_NAME; | |
} | |
(*first_element)->MG_LINKEDLIST_PREV_NAME = element; | |
} else { | |
*first_element = element; | |
} | |
if (element->MG_LINKEDLIST_PREV_NAME) { | |
element->MG_LINKEDLIST_PREV_NAME->MG_LINKEDLIST_NEXT_NAME = element->MG_LINKEDLIST_NEXT_NAME; | |
} | |
if (element->MG_LINKEDLIST_NEXT_NAME) { | |
element->MG_LINKEDLIST_NEXT_NAME->MG_LINKEDLIST_PREV_NAME = element->MG_LINKEDLIST_PREV_NAME; | |
} | |
} | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(void, addToListBack, MG_LINKEDLIST_TYPE *element, MG_LINKEDLIST_TYPE **first_element) { | |
if (*first_element) { | |
MG_LINKEDLIST_TYPE *last = *first_element; | |
while (last->MG_LINKEDLIST_NEXT_NAME) { | |
last = last->MG_LINKEDLIST_NEXT_NAME; | |
} | |
last->MG_LINKEDLIST_NEXT_NAME = element; | |
element->MG_LINKEDLIST_PREV_NAME = last; | |
} else { | |
element->MG_LINKEDLIST_PREV_NAME = 0; | |
element->MG_LINKEDLIST_NEXT_NAME = 0; | |
*first_element = element; | |
} | |
} | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(void, removeFromList, MG_LINKEDLIST_TYPE *element, MG_LINKEDLIST_TYPE **opt_root = 0) { | |
if (opt_root && element == *opt_root) { | |
*opt_root = element->next; | |
} | |
if (element->MG_LINKEDLIST_PREV_NAME) { | |
element->MG_LINKEDLIST_PREV_NAME->MG_LINKEDLIST_NEXT_NAME = element->MG_LINKEDLIST_NEXT_NAME; | |
} | |
if (element->MG_LINKEDLIST_NEXT_NAME) { | |
element->MG_LINKEDLIST_NEXT_NAME->MG_LINKEDLIST_PREV_NAME = element->MG_LINKEDLIST_PREV_NAME; | |
} | |
} | |
MG_LINKEDLIST_INTERN __MG_LINKEDLIST_FN(void, swap, MG_LINKEDLIST_TYPE *e0, MG_LINKEDLIST_TYPE *e1, MG_LINKEDLIST_TYPE **opt_root = 0) { | |
MG_LINKEDLIST_TYPE *e0_next = e0->next; | |
MG_LINKEDLIST_TYPE *e0_prev = e0->prev; | |
MG_LINKEDLIST_TYPE *e1_next = e1->next; | |
MG_LINKEDLIST_TYPE *e1_prev = e1->prev; | |
if (e0_next) { | |
e0_next->prev = e1; | |
} | |
if (e0_prev) { | |
e0_prev->next = e1; | |
} | |
if (e1_next) { | |
e1_next->prev = e0; | |
} | |
if (e1_prev) { | |
e1_prev->next = e0; | |
} | |
mg_swap(e0->next, e1->next); | |
mg_swap(e0->prev, e1->prev); | |
if (opt_root) { | |
if (*opt_root == e0) { | |
*opt_root = e1; | |
} else if (*opt_root == e1) { | |
*opt_root = e0; | |
} | |
} | |
} | |
#undef __MG_LINKEDLIST_FN | |
#undef __MG_LINKEDLIST_JOIN_HELPER | |
#undef __MG_LINKEDLIST_JOIN2 | |
#undef MG_LINKEDLIST_TYPE | |
#undef MG_LINKEDLIST_NEXT_NAME | |
#undef MG_LINKEDLIST_PREV_NAME | |
#ifndef MG_LINKEDLIST_FN_EXT | |
#undef MG_LINKEDLIST_FN_EXT | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment