acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
list.h
1#pragma once
2
3
4template < typename CONTAINER, typename LIST_ITEM >
5void list_predicateicate_add(CONTAINER& a, LIST_ITEM&& pitem)
6{
7
8 list_predicate(pitem, [&a](auto& p) { a.add(p); });
9
10}
11
12
13template < typename LIST_ITEM >
14::collection::count list_erase_all(LIST_ITEM&& pitem)
15{
16 ::collection::count c = 0;
17
18 auto pprevious = pitem->m_phead;
19
20 if (pprevious)
21 {
22
23 for (auto p = pprevious->m_pnext; ::is_set(p); p = p->m_pnext, c++)
24 {
25
26 pprevious->m_pnext = nullptr;
27
28 p->m_pprevious = nullptr;
29
30 }
31
32 }
33
34 pitem->m_phead = nullptr;
35
36 pitem->m_ptail = nullptr;
37
38 return c;
39
40}
41
42
43template < typename LIST_ITEM >
44::collection::count list_count(LIST_ITEM&& pitem)
45{
46
47 ::collection::count c = 0;
48
49 for (auto p = pitem->m_phead; ::is_set(p); p = p->m_pnext, c++);
50
51 return c;
52
53}
54
55
56template < typename LIST_ITEM, typename PRED >
57LIST_ITEM list_predicateicate_find(LIST_ITEM&& plist, PRED pred)
58{
59
60 for (auto p = plist->m_phead; ::is_set(p); p = p->m_pnext)
61 {
62
63 if (pred(p))
64 {
65
66 return p;
67
68 }
69
70 }
71
72 return nullptr;
73
74}
75
76
77template < typename LIST_ITEM, typename LIST_ITEM2 >
78bool list_contains_item(LIST_ITEM && pitem, LIST_ITEM2 && pitemItem)
79{
80
81 for (auto p = pitem->m_phead; ::is_set(p); p = p->m_pnext)
82 {
83
84 if (p == pitemItem)
85 {
86
87 return true;
88
89 }
90
91 }
92
93 return false;
94
95}
96
97
98template < typename LIST_ITEM, typename LIST_ITEM2 >
99::collection::index list_item_index(LIST_ITEM&& pitem, LIST_ITEM2&& pitemItem)
100{
101
102 ::collection::index i = 0;
103
104 for (auto p = pitem->m_phead; ::is_set(p); p = p->m_pnext, i++)
105 {
106
107 if (p == pitemItem)
108 {
109
110 return i;
111
112 }
113
114 }
115
116 return -1;
117
118}
119
120
121//template < typename LIST_ITEM, typename LIST_ITEM2 >
122//bool list_contains(LIST_ITEM&& pitem, LIST_ITEM2&& pitemItem)
123//{
124//
125// auto pFind = list_find_first(pitem, pitemItem);
126//
127// return ::is_set(pFind);
128//
129//}
130
131
132template < typename LIST_ITEM, typename LIST_ITEM2, typename LIST_ITEM3 >
133void list_insert_before(LIST_ITEM&& plist, LIST_ITEM2&& pitem, LIST_ITEM3&& pitemBefore)
134{
135
136 if (plist->m_phead == pitem)
137 {
138
139 pitem->m_phead = pitemBefore;
140
141 }
142
143 pitemBefore->m_pprevious = pitem->m_pprevious;
144
145 pitem->m_pprevious = pitemBefore;
146
147 pitemBefore->m_pnext = pitem;
148
149}
150
151
152template < typename LIST_ITEM, typename LIST_ITEM2, typename LIST_ITEM3 >
153void list_insert_after(LIST_ITEM&& plist, LIST_ITEM2&& pitem, LIST_ITEM3&& pitemAfter)
154{
155
156 if (plist->m_ptail == pitem)
157 {
158
159 pitem->m_ptail = pitemAfter;
160
161 }
162
163 pitemAfter->m_pnext = pitem->m_pnext;
164
165 pitem->m_pnext = pitemAfter;
166
167 pitemAfter->m_pprevious = pitem;
168
169}
170
171
172template < typename LIST_ITEM, typename LIST_ITEM2, typename LIST_ITEM3 >
173void list_replace_item(LIST_ITEM&& plist, LIST_ITEM2&& pitem, LIST_ITEM3&& pitemNew)
174{
175
176 if (plist->m_phead == pitem)
177 {
178
179 pitem->m_phead = pitemNew;
180
181 }
182
183 if (plist->m_ptail == pitem)
184 {
185
186 pitem->m_ptail = pitemNew;
187
188 }
189
190 pitemNew->m_pprevious = pitem->m_pprevious;
191
192 pitemNew->m_pnext = pitem->m_pnext;
193
194 pitem->m_pprevious = nullptr;
195
196 pitem->m_pnext = nullptr;
197
198 if (pitemNew->m_pnext)
199 {
200
201 pitemNew->m_pnext->m_pprevious = pitemNew;
202
203 }
204
205 if (pitemNew->m_pprevious)
206 {
207
208 pitemNew->m_pprevious->m_pnext = pitemNew;
209
210 }
211
212}
213
214
215
216
217
218template < typename LIST_ITEM, typename LIST_ITEM2 >
219void list_add(LIST_ITEM&& plist, LIST_ITEM2&& pitemAdd)
220{
221
222 if (plist->m_ptail)
223 {
224
225 plist->m_ptail->m_pnext = pitemAdd;
226
227 }
228
229 pitemAdd->m_pnext = nullptr;
230
231 pitemAdd->m_pprevious = plist->m_ptail;
232
233 plist->m_ptail = pitemAdd;
234
235 if (!plist->m_phead)
236 {
237
238 plist->m_phead = plist->m_ptail;
239
240 }
241
242}
243
244
245template < typename LIST_ITEM, typename LIST_ITEM2 >
246void list_add_head(LIST_ITEM&& plist, LIST_ITEM2&& pitemAdd)
247{
248
249 if (plist->m_phead)
250 {
251
252 plist->m_phead->m_pprevious = pitemAdd;
253
254 }
255
256 pitemAdd->m_pprevious = nullptr;
257
258 pitemAdd->m_pnext = plist->m_phead;
259
260 plist->m_phead = pitemAdd;
261
262 if (!plist->m_ptail)
263 {
264
265 plist->m_ptail = plist->m_phead;
266
267 }
268
269}
270
271
272template < typename LIST_ITEM, typename LIST_ITEM2 >
273void list_erase(LIST_ITEM&& pitem, LIST_ITEM2&& pitemRemove)
274{
275
276 if (pitem->m_phead == pitemRemove)
277 {
278
279 pitem->m_phead = pitemRemove->m_pnext;
280
281 }
282
283 if (pitem->m_ptail == pitemRemove)
284 {
285
286 pitem->m_ptail = pitemRemove->m_pprevious;
287
288 }
289
290 if (pitemRemove->m_pnext)
291 {
292
293 pitemRemove->m_pnext->m_pprevious = pitemRemove->m_pprevious;
294
295 }
296
297 if (pitemRemove->m_pprevious)
298 {
299
300 pitemRemove->m_pprevious->m_pnext = pitemRemove->m_pnext;
301
302 }
303
304}
305
306
307
308template < typename LIST_ITEM, typename PRED >
309void list_predicate(LIST_ITEM* pitem, PRED pred)
310{
311
312 for (auto p = pitem->m_phead; ::is_set(p); p = p->m_pnext)
313 {
314
315 pred(p);
316
317 }
318
319}
320
321template < typename LIST_ITEM, typename PRED >
322void list_predicateicate_with_index(LIST_ITEM* pitem, PRED pred)
323{
324
325 ::collection::index i = 0;
326
327 for (auto p = pitem->m_phead; ::is_set(p); p = p->m_pnext, i++)
328 {
329
330 pred(p, i);
331
332 }
333
334
335}
336
337
338template < typename TREE_ITEM, typename PRED >
339void tree_sort(TREE_ITEM* pitem, PRED pred)
340{
341
342 list_sort(pitem);
343
344 list_predicate(pitem, [pred](auto p) {tree_sort(p, pred); });
345
346}
347
348
349