00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #ifndef ILIST_H
00107 #define ILIST_H
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 typedef struct dlist_node dlist_node;
00121 struct dlist_node
00122 {
00123 dlist_node *prev;
00124 dlist_node *next;
00125 };
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 typedef struct dlist_head
00136 {
00137
00138
00139
00140
00141
00142
00143
00144 dlist_node head;
00145 } dlist_head;
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 typedef struct dlist_iter
00160 {
00161 dlist_node *cur;
00162 dlist_node *end;
00163 } dlist_iter;
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 typedef struct dlist_mutable_iter
00179 {
00180 dlist_node *cur;
00181 dlist_node *next;
00182 dlist_node *end;
00183 } dlist_mutable_iter;
00184
00185
00186
00187
00188
00189
00190 typedef struct slist_node slist_node;
00191 struct slist_node
00192 {
00193 slist_node *next;
00194 };
00195
00196
00197
00198
00199
00200
00201
00202
00203 typedef struct slist_head
00204 {
00205 slist_node head;
00206 } slist_head;
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 typedef struct slist_iter
00220 {
00221 slist_node *cur;
00222 } slist_iter;
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 typedef struct slist_mutable_iter
00233 {
00234 slist_node *cur;
00235 slist_node *next;
00236 } slist_mutable_iter;
00237
00238
00239
00240 #define DLIST_STATIC_INIT(name) {{&(name).head, &(name).head}}
00241 #define SLIST_STATIC_INIT(name) {{NULL}}
00242
00243
00244
00245
00246
00247 extern void slist_delete(slist_head *head, slist_node *node);
00248
00249 #ifdef ILIST_DEBUG
00250 extern void dlist_check(dlist_head *head);
00251 extern void slist_check(slist_head *head);
00252 #else
00253
00254
00255
00256
00257
00258
00259 #define dlist_check(head) ((void) (head))
00260 #define slist_check(head) ((void) (head))
00261 #endif
00262
00263
00264
00265
00266
00267
00268
00269 #ifndef PG_USE_INLINE
00270 extern void dlist_init(dlist_head *head);
00271 extern bool dlist_is_empty(dlist_head *head);
00272 extern void dlist_push_head(dlist_head *head, dlist_node *node);
00273 extern void dlist_push_tail(dlist_head *head, dlist_node *node);
00274 extern void dlist_insert_after(dlist_node *after, dlist_node *node);
00275 extern void dlist_insert_before(dlist_node *before, dlist_node *node);
00276 extern void dlist_delete(dlist_node *node);
00277 extern dlist_node *dlist_pop_head_node(dlist_head *head);
00278 extern void dlist_move_head(dlist_head *head, dlist_node *node);
00279 extern bool dlist_has_next(dlist_head *head, dlist_node *node);
00280 extern bool dlist_has_prev(dlist_head *head, dlist_node *node);
00281 extern dlist_node *dlist_next_node(dlist_head *head, dlist_node *node);
00282 extern dlist_node *dlist_prev_node(dlist_head *head, dlist_node *node);
00283 extern dlist_node *dlist_head_node(dlist_head *head);
00284 extern dlist_node *dlist_tail_node(dlist_head *head);
00285
00286
00287 extern void *dlist_tail_element_off(dlist_head *head, size_t off);
00288 extern void *dlist_head_element_off(dlist_head *head, size_t off);
00289 #endif
00290
00291 #if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
00292
00293
00294
00295
00296 STATIC_IF_INLINE void
00297 dlist_init(dlist_head *head)
00298 {
00299 head->head.next = head->head.prev = &head->head;
00300 }
00301
00302
00303
00304
00305
00306
00307 STATIC_IF_INLINE bool
00308 dlist_is_empty(dlist_head *head)
00309 {
00310 dlist_check(head);
00311
00312 return head->head.next == NULL || head->head.next == &(head->head);
00313 }
00314
00315
00316
00317
00318 STATIC_IF_INLINE void
00319 dlist_push_head(dlist_head *head, dlist_node *node)
00320 {
00321 if (head->head.next == NULL)
00322 dlist_init(head);
00323
00324 node->next = head->head.next;
00325 node->prev = &head->head;
00326 node->next->prev = node;
00327 head->head.next = node;
00328
00329 dlist_check(head);
00330 }
00331
00332
00333
00334
00335 STATIC_IF_INLINE void
00336 dlist_push_tail(dlist_head *head, dlist_node *node)
00337 {
00338 if (head->head.next == NULL)
00339 dlist_init(head);
00340
00341 node->next = &head->head;
00342 node->prev = head->head.prev;
00343 node->prev->next = node;
00344 head->head.prev = node;
00345
00346 dlist_check(head);
00347 }
00348
00349
00350
00351
00352 STATIC_IF_INLINE void
00353 dlist_insert_after(dlist_node *after, dlist_node *node)
00354 {
00355 node->prev = after;
00356 node->next = after->next;
00357 after->next = node;
00358 node->next->prev = node;
00359 }
00360
00361
00362
00363
00364 STATIC_IF_INLINE void
00365 dlist_insert_before(dlist_node *before, dlist_node *node)
00366 {
00367 node->prev = before->prev;
00368 node->next = before;
00369 before->prev = node;
00370 node->prev->next = node;
00371 }
00372
00373
00374
00375
00376 STATIC_IF_INLINE void
00377 dlist_delete(dlist_node *node)
00378 {
00379 node->prev->next = node->next;
00380 node->next->prev = node->prev;
00381 }
00382
00383
00384
00385
00386 STATIC_IF_INLINE dlist_node *
00387 dlist_pop_head_node(dlist_head *head)
00388 {
00389 dlist_node *node;
00390
00391 Assert(!dlist_is_empty(head));
00392 node = head->head.next;
00393 dlist_delete(node);
00394 return node;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403 STATIC_IF_INLINE void
00404 dlist_move_head(dlist_head *head, dlist_node *node)
00405 {
00406
00407 if (head->head.next == node)
00408 return;
00409
00410 dlist_delete(node);
00411 dlist_push_head(head, node);
00412
00413 dlist_check(head);
00414 }
00415
00416
00417
00418
00419
00420 STATIC_IF_INLINE bool
00421 dlist_has_next(dlist_head *head, dlist_node *node)
00422 {
00423 return node->next != &head->head;
00424 }
00425
00426
00427
00428
00429
00430 STATIC_IF_INLINE bool
00431 dlist_has_prev(dlist_head *head, dlist_node *node)
00432 {
00433 return node->prev != &head->head;
00434 }
00435
00436
00437
00438
00439 STATIC_IF_INLINE dlist_node *
00440 dlist_next_node(dlist_head *head, dlist_node *node)
00441 {
00442 Assert(dlist_has_next(head, node));
00443 return node->next;
00444 }
00445
00446
00447
00448
00449 STATIC_IF_INLINE dlist_node *
00450 dlist_prev_node(dlist_head *head, dlist_node *node)
00451 {
00452 Assert(dlist_has_prev(head, node));
00453 return node->prev;
00454 }
00455
00456
00457 STATIC_IF_INLINE void *
00458 dlist_head_element_off(dlist_head *head, size_t off)
00459 {
00460 Assert(!dlist_is_empty(head));
00461 return (char *) head->head.next - off;
00462 }
00463
00464
00465
00466
00467 STATIC_IF_INLINE dlist_node *
00468 dlist_head_node(dlist_head *head)
00469 {
00470 return (dlist_node *) dlist_head_element_off(head, 0);
00471 }
00472
00473
00474 STATIC_IF_INLINE void *
00475 dlist_tail_element_off(dlist_head *head, size_t off)
00476 {
00477 Assert(!dlist_is_empty(head));
00478 return (char *) head->head.prev - off;
00479 }
00480
00481
00482
00483
00484 STATIC_IF_INLINE dlist_node *
00485 dlist_tail_node(dlist_head *head)
00486 {
00487 return (dlist_node *) dlist_tail_element_off(head, 0);
00488 }
00489 #endif
00490
00491
00492
00493
00494
00495
00496
00497 #define dlist_container(type, membername, ptr) \
00498 (AssertVariableIsOfTypeMacro(ptr, dlist_node *), \
00499 AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \
00500 ((type *) ((char *) (ptr) - offsetof(type, membername))))
00501
00502
00503
00504
00505
00506
00507 #define dlist_head_element(type, membername, lhead) \
00508 (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \
00509 (type *) dlist_head_element_off(lhead, offsetof(type, membername)))
00510
00511
00512
00513
00514
00515
00516 #define dlist_tail_element(type, membername, lhead) \
00517 (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \
00518 ((type *) dlist_tail_element_off(lhead, offsetof(type, membername))))
00519
00520
00521
00522
00523
00524
00525
00526
00527 #define dlist_foreach(iter, lhead) \
00528 for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \
00529 AssertVariableIsOfTypeMacro(lhead, dlist_head *), \
00530 (iter).end = &(lhead)->head, \
00531 (iter).cur = (iter).end->next ? (iter).end->next : (iter).end; \
00532 (iter).cur != (iter).end; \
00533 (iter).cur = (iter).cur->next)
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 #define dlist_foreach_modify(iter, lhead) \
00545 for (AssertVariableIsOfTypeMacro(iter, dlist_mutable_iter), \
00546 AssertVariableIsOfTypeMacro(lhead, dlist_head *), \
00547 (iter).end = &(lhead)->head, \
00548 (iter).cur = (iter).end->next ? (iter).end->next : (iter).end, \
00549 (iter).next = (iter).cur->next; \
00550 (iter).cur != (iter).end; \
00551 (iter).cur = (iter).next, (iter).next = (iter).cur->next)
00552
00553
00554
00555
00556
00557
00558 #define dlist_reverse_foreach(iter, lhead) \
00559 for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \
00560 AssertVariableIsOfTypeMacro(lhead, dlist_head *), \
00561 (iter).end = &(lhead)->head, \
00562 (iter).cur = (iter).end->prev ? (iter).end->prev : (iter).end; \
00563 (iter).cur != (iter).end; \
00564 (iter).cur = (iter).cur->prev)
00565
00566
00567
00568
00569
00570
00571
00572 #ifndef PG_USE_INLINE
00573 extern void slist_init(slist_head *head);
00574 extern bool slist_is_empty(slist_head *head);
00575 extern void slist_push_head(slist_head *head, slist_node *node);
00576 extern void slist_insert_after(slist_node *after, slist_node *node);
00577 extern slist_node *slist_pop_head_node(slist_head *head);
00578 extern bool slist_has_next(slist_head *head, slist_node *node);
00579 extern slist_node *slist_next_node(slist_head *head, slist_node *node);
00580 extern slist_node *slist_head_node(slist_head *head);
00581
00582
00583 extern void *slist_head_element_off(slist_head *head, size_t off);
00584 #endif
00585
00586 #if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS)
00587
00588
00589
00590
00591 STATIC_IF_INLINE void
00592 slist_init(slist_head *head)
00593 {
00594 head->head.next = NULL;
00595 }
00596
00597
00598
00599
00600 STATIC_IF_INLINE bool
00601 slist_is_empty(slist_head *head)
00602 {
00603 slist_check(head);
00604
00605 return head->head.next == NULL;
00606 }
00607
00608
00609
00610
00611 STATIC_IF_INLINE void
00612 slist_push_head(slist_head *head, slist_node *node)
00613 {
00614 node->next = head->head.next;
00615 head->head.next = node;
00616
00617 slist_check(head);
00618 }
00619
00620
00621
00622
00623 STATIC_IF_INLINE void
00624 slist_insert_after(slist_node *after, slist_node *node)
00625 {
00626 node->next = after->next;
00627 after->next = node;
00628 }
00629
00630
00631
00632
00633 STATIC_IF_INLINE slist_node *
00634 slist_pop_head_node(slist_head *head)
00635 {
00636 slist_node *node;
00637
00638 Assert(!slist_is_empty(head));
00639 node = head->head.next;
00640 head->head.next = node->next;
00641 slist_check(head);
00642 return node;
00643 }
00644
00645
00646
00647
00648 STATIC_IF_INLINE bool
00649 slist_has_next(slist_head *head, slist_node *node)
00650 {
00651 slist_check(head);
00652
00653 return node->next != NULL;
00654 }
00655
00656
00657
00658
00659 STATIC_IF_INLINE slist_node *
00660 slist_next_node(slist_head *head, slist_node *node)
00661 {
00662 Assert(slist_has_next(head, node));
00663 return node->next;
00664 }
00665
00666
00667 STATIC_IF_INLINE void *
00668 slist_head_element_off(slist_head *head, size_t off)
00669 {
00670 Assert(!slist_is_empty(head));
00671 return (char *) head->head.next - off;
00672 }
00673
00674
00675
00676
00677 STATIC_IF_INLINE slist_node *
00678 slist_head_node(slist_head *head)
00679 {
00680 return (slist_node *) slist_head_element_off(head, 0);
00681 }
00682 #endif
00683
00684
00685
00686
00687
00688
00689
00690 #define slist_container(type, membername, ptr) \
00691 (AssertVariableIsOfTypeMacro(ptr, slist_node *), \
00692 AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \
00693 ((type *) ((char *) (ptr) - offsetof(type, membername))))
00694
00695
00696
00697
00698
00699
00700 #define slist_head_element(type, membername, lhead) \
00701 (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \
00702 (type *) slist_head_element_off(lhead, offsetof(type, membername)))
00703
00704
00705
00706
00707
00708
00709
00710
00711 #define slist_foreach(iter, lhead) \
00712 for (AssertVariableIsOfTypeMacro(iter, slist_iter), \
00713 AssertVariableIsOfTypeMacro(lhead, slist_head *), \
00714 (iter).cur = (lhead)->head.next; \
00715 (iter).cur != NULL; \
00716 (iter).cur = (iter).cur->next)
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 #define slist_foreach_modify(iter, lhead) \
00727 for (AssertVariableIsOfTypeMacro(iter, slist_mutable_iter), \
00728 AssertVariableIsOfTypeMacro(lhead, slist_head *), \
00729 (iter).cur = (lhead)->head.next, \
00730 (iter).next = (iter).cur ? (iter).cur->next : NULL; \
00731 (iter).cur != NULL; \
00732 (iter).cur = (iter).next, \
00733 (iter).next = (iter).next ? (iter).next->next : NULL)
00734
00735 #endif