Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Last active August 29, 2015 14:11
Show Gist options
  • Save ElectricCoffee/9b9531e1c9943317a354 to your computer and use it in GitHub Desktop.
Save ElectricCoffee/9b9531e1c9943317a354 to your computer and use it in GitHub Desktop.
Macros for easy generic creation of lists in C
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
DEFINE_LIST(int); /* defines the int_list type */
int main(void) {
int_list *lst = EMPTY;
PUSH(8, &lst, int_list);
PUSH(4, &lst, int_list);
PUSH(5, &lst, int_list);
printf("popping value: %d\n", POP(&lst, int, int_list));
printf("popping value: %d\n", POP(&lst, int, int_list));
FREE_LIST(lst, int_list);
if (lst == EMPTY) puts("the list has been freed");
exit(EXIT_SUCCESS);
}
#ifndef __list_h
#define __list_h
#define EMPTY NULL
/* defines a list with the name TYPE_list.
example: DEFINE_LIST(int); will make an int_list struct */
#define DEFINE_LIST(__head_t) \
typedef struct __head_t##_list { \
__head_t head; \
struct __head_t##_list *tail; \
} __head_t##_list
/* fres a list of any kind,
__lst is the list and __lst_type is the type of the list */
#define FREE_LIST(__lst, __lst_type) ({ \
__lst_type *tail, *current = __lst; \
while (current != EMPTY) { \
tail = current->tail; \
free(current); \
current = tail; \
} \
__lst = EMPTY; \
})
/* pushes a new value into the list,
__lst_type is the type of list, not type of head */
#define PUSH(__value, __lst, __tail_type) ({ \
__tail_type *temp = malloc(sizeof(__tail_type)); \
temp->head = __value; \
temp->tail = *__lst; \
*__lst = temp; \
})
/* pops a value from the list and returns it */
#define POP(__input, __head_type, __tail_type) ({ \
__tail_type *temp = *__input; \
__head_type result; \
if (temp->tail != EMPTY) { \
result = temp->head; \
temp = temp->tail; \
} \
else { \
result = temp->head; \
temp = EMPTY; \
} \
*__input = temp; \
result; \
})
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment