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

Last change on this file since d3942b9 was e26a842, checked in by Peter A. Buhr <pabuhr@…>, 14 months ago

update example programs

  • Property mode set to 100644
File size: 2.8 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.