source: doc/theses/mike_brooks_MMath/programs/lst-issues-attach-reduction.hpp @ 6f774be

ast-experimental
Last change on this file since 6f774be was 5717495, checked in by Michael Brooks <mlbrooks@…>, 20 months ago

Start of the linked-list chapter.

  • Property mode set to 100644
File size: 2.9 KB
Line 
1
2
3// excerpt of <sys/queue.h>, modified to work in C++ along with templates
4
5#define LIST_HEAD(name, type)                                           \
6struct name {                                                           \
7        type *lh_first; /* first element */                     \
8}
9
10#define LIST_HEAD_INITIALIZER(head)                                     \
11        { NULL }
12
13#define LIST_ENTRY(type)                                                \
14struct {                                                                \
15        type *le_next;  /* next element */                      \
16        type **le_prev; /* address of previous next element */  \
17}
18
19/*
20 * List functions.
21 */
22#define LIST_INIT(head) do {                                            \
23        (head)->lh_first = NULL;                                        \
24} while (/*CONSTCOND*/0)
25
26#define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
27        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
28                (listelm)->field.le_next->field.le_prev =               \
29                    &(elm)->field.le_next;                              \
30        (listelm)->field.le_next = (elm);                               \
31        (elm)->field.le_prev = &(listelm)->field.le_next;               \
32} while (/*CONSTCOND*/0)
33
34#define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
35        (elm)->field.le_prev = (listelm)->field.le_prev;                \
36        (elm)->field.le_next = (listelm);                               \
37        *(listelm)->field.le_prev = (elm);                              \
38        (listelm)->field.le_prev = &(elm)->field.le_next;               \
39} while (/*CONSTCOND*/0)
40
41#define LIST_INSERT_HEAD(head, elm, field) do {                         \
42        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
43                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
44        (head)->lh_first = (elm);                                       \
45        (elm)->field.le_prev = &(head)->lh_first;                       \
46} while (/*CONSTCOND*/0)
47
48#define LIST_REMOVE(elm, field) do {                                    \
49        if ((elm)->field.le_next != NULL)                               \
50                (elm)->field.le_next->field.le_prev =                   \
51                    (elm)->field.le_prev;                               \
52        *(elm)->field.le_prev = (elm)->field.le_next;                   \
53} while (/*CONSTCOND*/0)
54
55#define LIST_FOREACH(var, head, field)                                  \
56        for ((var) = ((head)->lh_first);                                \
57                (var);                                                  \
58                (var) = ((var)->field.le_next))
59
60/*
61 * List access methods.
62 */
63#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
64#define LIST_FIRST(head)                ((head)->lh_first)
65#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
66
67
68
69
70
71
72
73namespace my {
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100template<typename El>
101class list {
102    struct node {
103        LIST_ENTRY(node) links;
104        El elem;
105    };
106    LIST_HEAD(Impl, node);
107    Impl impl;
108  public:
109    list() {
110        LIST_INIT(&impl);
111    }
112    void push_front( const El & src ) {
113        node * n = new node();
114        n->elem = src;
115        LIST_INSERT_HEAD(&impl, n, links);
116    }
117    // ... `emplace` elided
118
119
120
121
122
123
124
125
126
127
128
129
130
131    template<typename... CtorArgs>
132    void emplace_front( CtorArgs... args ) { 
133        El tempEl{args...}; // (mock: avoid real emplacing to keep `struct node` simple; disucssion is about allocation, not copying)
134        push_front(tempEl);
135    }
136    class IType {
137        node* p;
138      public:
139        IType(node* p) : p(p) {}
140        bool operator!=(IType rhs) {return p != rhs.p;}
141        const El& operator*() {return p->elem;}
142        void operator++() { p = LIST_NEXT(p, links); }
143    };
144    IType begin() {return IType(LIST_FIRST(&impl)); }
145    IType end() {return IType(NULL); }
146
147
148
149
150};
151
152
153
154
155
156
157}
Note: See TracBrowser for help on using the repository browser.