#ifndef LIBCGDS_LIST_H
#define LIBCGDS_LIST_H 1
#include <stddef.h>
/* Singly-linked list
* ---------> --------->
* |Next|... => |Next|... => ...
* ---------> --------->
* Elements of linked list must have sllist_node struct at front
* sllist functions take pointer to sllist head ptr
* */
struct sllist_node {
struct sllist_node *next;
};
/* Pushes element into first index of sllist
* Element must have sllist_node as first member
* Replaces pointer at head with new head
* */
void __sll_push(struct sllist_node **head, struct sllist_node *data);
#define sll_push(a, b) __sll_push((struct sllist_node**)a, (struct sllist_node*)b)
void __sll_pushback(struct sllist_node **head, struct sllist_node *data);
#define sll_pushback(a, b) __sll_pushback((struct sllist_node**)a, (struct sllist_node*)b)
/* Pops element 0 from list
* Returns element 0
* Sets new head
* */
void *__sll_pop(struct sllist_node **head);
#define sll_pop(a) __sll_pop((struct sllist_node**)a)
/* Gets element of sllist at i
* Element must have sllist_node as first member
* Head can be in middle of list to get n elements after
* */
void *__sll_at(struct sllist_node **head, size_t i);
#define sll_at(a, b) __sll_at((struct sllist_node**)a, b)
/* Removes element of sllist at i
* Moves leading elements down
* */
void __sll_remove(struct sllist_node **head, size_t i);
#define sll_remove(a, b) __sll_remove((struct sllist_node**)a, b)
/* Removes element from list
* Moves leading elements down
* */
void __sll_delete(struct sllist_node **head, struct sllist_node *node);
#define sll_delete(a, b) __sll_delete((struct sllist_node**)a, (struct sllist_node*)b)
/* Pushes val into list at i, moving following elements forward starting at replaced
* Sets new head if i == 0
* */
void __sll_insert(struct sllist_node **head, struct sllist_node *val, size_t i);
#define sll_insert(a, b, c) __sll_insert((struct sllist_node**)a, (struct sllist_node*)b, c)
#define sll_foreach(t, a, b) for(t a = *b; a; a = (t)(((struct sllist_node*)a)->next))
#endif