Skip to content

Instantly share code, notes, and snippets.

@ShawnMcGrath
Created September 21, 2016 00:38
Show Gist options
  • Save ShawnMcGrath/32dfc0e969f92002c2b016cd69735e38 to your computer and use it in GitHub Desktop.
Save ShawnMcGrath/32dfc0e969f92002c2b016cd69735e38 to your computer and use it in GitHub Desktop.
#ifndef MG_FREELIST_EXTERN
#define MG_FREELIST_EXTERN extern
#endif
#ifndef MG_FREELIST_INTERN
#define MG_FREELIST_INTERN static
#endif
//mandatory
#ifndef MG_FREELIST_FREE_FN_NAME
#error "Must define MG_FREELIST_FREE_FN_NAME"
#endif
#ifndef MG_FREELIST_TYPE
#error "Must define MG_FREELIST_TYPE"
#endif
#ifndef MG_FREELIST_NEW_FN_NAME
#error "Must define MG_FREELIST_NEW_FN_NAME"
#endif
//optional
#ifndef MG_FREELIST_NEXT_NAME
#define MG_FREELIST_NEXT_NAME next
#endif
#ifndef MG_FREELIST_PREV_NAME
#define MG_FREELIST_PREV_NAME prev
#endif
#ifndef MG_FREELIST_FREE_FN
#define MG_FREELIST_FREE_FN(element)
#endif
#ifndef MG_FREELIST_INIT_FN
#define MG_FREELIST_INIT_FN(element)
#endif
#ifndef MG_FREELIST_ASSERT_ON_ALLOC_FAIL
#define MG_FREELIST_ASSERT_ON_ALLOC_FAIL(expr)
#endif
//MG_LINKEDLIST //#define this if you want have mg_linkedlist.h and want all the linked list functionatily as well
#if !defined(MG_FREELIST_NEW_MSTACK) && !defined (MG_FREELIST_NEW_MEMORY)
#define MG_FREELIST_NEW_MALLOC malloc
#endif
#ifdef MG_FREELIST_NEW_MSTACK
MG_FREELIST_INTERN MG_FREELIST_TYPE *MG_FREELIST_NEW_FN_NAME(MG_FREELIST_TYPE *prev, MG_FREELIST_TYPE **freelist, mgMemStack *mstack, MG_FREELIST_TYPE **opt_root = 0) {
#define __MG_FREELIST_ALLOC_NEW_NODE res = (MG_FREELIST_TYPE *)mg_memStackPush(mstack, sizeof(MG_FREELIST_TYPE), true);
#elif defined(MG_FREELIST_NEW_MEMORY)
MG_FREELIST_INTERN MG_FREELIST_TYPE *MG_FREELIST_NEW_FN_NAME(MG_FREELIST_TYPE *prev, MG_FREELIST_TYPE **freelist, void *mem, MG_FREELIST_TYPE **opt_root = 0) {
#define __MG_FREELIST_ALLOC_NEW_NODE res = (MG_FREELIST_TYPE *)mem;
#else
MG_FREELIST_INTERN MG_FREELIST_TYPE *MG_FREELIST_NEW_FN_NAME(MG_FREELIST_TYPE *prev, MG_FREELIST_TYPE **freelist, MG_FREELIST_TYPE **opt_root = 0) {
#define __MG_FREELIST_ALLOC_NEW_NODE res = (MG_FREELIST_TYPE *) MG_FREELIST_NEW_MALLOC(sizeof(MG_FREELIST_TYPE), true);
#endif
MG_FREELIST_TYPE *res = 0;
if (*freelist) {
res = *freelist;
*freelist = (*freelist)->MG_FREELIST_NEXT_NAME;
if (res->MG_FREELIST_NEXT_NAME) {
res->MG_FREELIST_NEXT_NAME->MG_FREELIST_PREV_NAME = 0;
}
} else {
__MG_FREELIST_ALLOC_NEW_NODE;
}
if (!res) {
MG_FREELIST_ASSERT_ON_ALLOC_FAIL(false);
return 0;
}
if (prev) {
res->MG_FREELIST_NEXT_NAME = prev->MG_FREELIST_NEXT_NAME;
prev->MG_FREELIST_NEXT_NAME = res;
} else {
res->MG_FREELIST_NEXT_NAME = 0;
}
res->MG_FREELIST_PREV_NAME = prev;
if (opt_root && !*opt_root) {
*opt_root = res;
}
MG_FREELIST_INIT_FN(res);
return res;
}
MG_FREELIST_INTERN MG_FREELIST_TYPE *MG_FREELIST_FREE_FN_NAME(MG_FREELIST_TYPE *item, MG_FREELIST_TYPE **free_list, MG_FREELIST_TYPE **opt_root = 0) {
MG_FREELIST_TYPE *passed_in_item = item;
MG_FREELIST_TYPE *passed_in_next = item->next;
MG_FREELIST_TYPE *next = item->MG_FREELIST_NEXT_NAME;
if (*free_list) {
MG_ASSERT((*free_list)->MG_FREELIST_PREV_NAME == 0);
(*free_list)->MG_FREELIST_PREV_NAME = item;
}
if (item->MG_FREELIST_PREV_NAME) {
item->MG_FREELIST_PREV_NAME->MG_FREELIST_NEXT_NAME = item->MG_FREELIST_NEXT_NAME;
}
if (item->MG_FREELIST_NEXT_NAME) {
item->MG_FREELIST_NEXT_NAME->MG_FREELIST_PREV_NAME = item->MG_FREELIST_PREV_NAME;
}
item->MG_FREELIST_PREV_NAME = 0;
item->MG_FREELIST_NEXT_NAME = (*free_list);
*free_list = item;
MG_FREELIST_FREE_FN(item);
if (opt_root && *opt_root == passed_in_item) {
*opt_root = passed_in_next;
}
return next;
}
#ifdef MG_FREELIST_GEN_LINKEDLIST
#define MG_LINKEDLIST_TYPE MG_FREELIST_TYPE
#include "mg_linkedlist.h"
#endif
#undef MG_FREELIST_FREE_FN_NAME
#undef MG_FREELIST_NEW_FN_NAME
#undef MG_FREELIST_TYPE
#undef MG_FREELIST_NEXT_NAME
#undef MG_FREELIST_PREV_NAME
#undef MG_FREELIST_FREE_FN
#undef MG_FREELIST_INIT_FN
#undef __MG_FREELIST_ALLOC_NEW_NODE
#undef MG_FREELIST_ASSERT_ON_ALLOC_FAIL
#ifdef MG_FREELIST_NEW_MSTACK
#undef MG_FREELIST_NEW_MSTACK
#endif
#ifdef MG_FREELIST_NEW_MEMORY
#undef MG_FREELIST_NEW_MEMORY
#endif
#ifdef MG_FREELIST_NEW_MALLOC
#undef MG_FREELIST_NEW_MALLOC
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment