aboutsummaryrefslogtreecommitdiff
path: root/src/list.h
blob: cd5c7e6e7218e716a9307ef8b92bce90f7b16038 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#ifndef ALGDS_LIST_H_
#define ALGDS_LIST_H_

#include <stdlib.h>


#define LIST_DEF(T) \
    struct T##List_node { \
        T val; \
        struct T##List_node *prev; \
        struct T##List_node *next; \
    }; \
    typedef struct T##List_node T##ListNode; \
    typedef T##ListNode *T##ListIter; \
    typedef struct { \
        T##ListNode *vhead; \
        T##ListNode *vtail; \
        size_t len; \
    } T##List; \
    void T##List_init(T##List *self); \
    void T##List_free(T##List *self); \
    void T##List_move(T##List *self); \
    T##ListIter T##List_insert_before(T##List *self, T##ListIter iter); \
    T##ListIter T##List_insert_after(T##List *self, T##ListIter iter); \
    void T##List_remove_before(T##List *self, T##ListIter iter); \
    void T##List_remove_after(T##List *self, T##ListIter iter); \
    T##ListIter T##List_begin(T##List *self); \
    T##ListIter T##List_last(T##List *self); \
    T##ListIter T##List_end(T##List *self); \
    T##ListIter T##List_next(T##ListIter *iter); \
    T##ListIter T##List_prev(T##ListIter *iter); \
    size_t T##List_len(T##ListIter *iter); \
    void T##List_push_back(T##List *self, T val); \
    void T##List_push_front(T##List *self, T val); \
    void T##List_pop_back(T##List *self, T val); \
    void T##List_pop_front(T##List *self, T val); \

#define LIST_IMPL(T) \
    void T##List_init(T##List *self) { \
        self->vhead = malloc(sizeof(T##ListNode)); \
        self->vtail = malloc(sizeof(T##ListNode)); \
        self->vhead->next = self->vtail; \
        self->vhead->prev = NULL; \
        self->vtail->next = NULL; \
        self->vhead->prev = self->vhead; \
        self->len = 0; \
    } \
    void T##List_free(T##List *self) { \
        T##ListIter cur = self->vhead; \
        while (cur != NULL) { \
            T##ListIter next = cur->next; \
            free(cur); \
            cur = next; \
        } \
    } \
    void T##List_move(T##List *self) { \
        T##List dup; \
        dup.vhead = self->vhead; \
        dup.vtail = self->vtail; \
        dup.len = self->len; \
        self->vhead = NULL; \
        self->vtail = NULL; \
        self->len = 0; \
    } \
    T##ListIter T##List_insert_before(T##List *self, T##ListIter iter, T val) { \
        if (iter->prev == NULL) return NULL; \
        T##ListIter newnode = malloc(sizeof(T##ListNode)); \
        newnode->prev = iter->prev; \
        newnode->next = iter->next; \
        newnode->val = val; \
        iter->prev->next = newnode; \
        iter->prev = newnode; \
        self->len++; \
    } \
    T##ListIter T##List_insert_after(T##List *self, T##ListIter iter); \
    void T##List_remove_before(T##List *self, T##ListIter iter); \
    void T##List_remove_after(T##List *self, T##ListIter iter); \
    T##ListIter T##List_begin(T##List *self); \
    T##ListIter T##List_last(T##List *self); \
    T##ListIter T##List_end(T##List *self); \
    T##ListIter T##List_next(T##ListIter *iter); \
    T##ListIter T##List_prev(T##ListIter *iter); \
    size_t T##List_len(T##ListIter *iter); \
    void T##List_push_back(T##List *self, T val); \
    void T##List_push_front(T##List *self, T val); \
    void T##List_pop_back(T##List *self, T val); \
    void T##List_pop_front(T##List *self, T val); \

#endif