Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/utlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ iterating over them.
|LL_INSERT_INORDER(head,add,cmp); | DL_INSERT_INORDER(head,add,cmp); | CDL_INSERT_INORDER(head,add,cmp);
|LL_CONCAT(head1,head2); | DL_CONCAT(head1,head2); |
|LL_DELETE(head,del); | DL_DELETE(head,del); | CDL_DELETE(head,del);
|LL_REVERSE(head); | DL_REVERSE(head); | CDL_REVERSE(head);
|LL_SORT(head,cmp); | DL_SORT(head,cmp); | CDL_SORT(head,cmp);
|LL_FOREACH(head,elt) {...}| DL_FOREACH(head,elt) {...} | CDL_FOREACH(head,elt) {...}
|LL_FOREACH_SAFE(head,elt,tmp) {...}| DL_FOREACH_SAFE(head,elt,tmp) {...} | CDL_FOREACH_SAFE(head,elt,tmp1,tmp2) {...}
Expand Down Expand Up @@ -281,6 +282,7 @@ the `prev` and `next` fields (as applicable) as trailing arguments.
|LL_INSERT_INORDER2(head,add,cmp,next); | DL_INSERT_INORDER2(head,add,cmp,prev,next); | CDL_INSERT_INORDER2(head,add,cmp,prev,next);
|LL_CONCAT2(head1,head2,next); | DL_CONCAT2(head1,head2,prev,next); |
|LL_DELETE2(head,del,next); | DL_DELETE2(head,del,prev,next); | CDL_DELETE2(head,del,prev,next);
|LL_REVERSE2(head,next); | DL_REVERSE2(head,prev,next); | CDL_REVERSE2(head,prev,next);
|LL_SORT2(head,cmp,next); | DL_SORT2(head,cmp,prev,next); | CDL_SORT2(head,cmp,prev,next);
|LL_FOREACH2(head,elt,next) {...} | DL_FOREACH2(head,elt,next) {...} | CDL_FOREACH2(head,elt,next) {...}
|LL_FOREACH_SAFE2(head,elt,tmp,next) {...} | DL_FOREACH_SAFE2(head,elt,tmp,next) {...} | CDL_FOREACH_SAFE2(head,elt,tmp1,tmp2,prev,next) {...}
Expand Down
117 changes: 117 additions & 0 deletions src/utlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,25 @@ do {
} \
} while (0)

#define LL_REVERSE(head) \
LL_REVERSE2(head,next)

#define LL_REVERSE2(head,next) \
do { \
if (head) { \
LDECLTYPE(head) _curr = (head); \
LDECLTYPE(head) _prev = NULL; \
LDECLTYPE(head) _next; \
while (_curr) { \
_next = _curr->next; \
_curr->next = _prev; \
_prev = _curr; \
_curr = _next; \
} \
(head) = _prev; \
} \
} while (0)

#define LL_REPLACE_ELEM2(head, el, add, next) \
do { \
LDECLTYPE(head) _tmp; \
Expand Down Expand Up @@ -615,6 +634,22 @@ do {
} \
} while (0) \

#undef LL_REVERSE2
#define LL_REVERSE2(head,next) \
do { \
if (head) { \
char *_prev = NULL; \
char *_next = NULL; \
while (head) { \
UTLIST_CASTASGN(_next, (head)->next); \
UTLIST_CASTASGN((head)->next, _prev); \
UTLIST_CASTASGN(_prev, (head)); \
UTLIST_CASTASGN((head), _next); \
} \
UTLIST_CASTASGN((head), _prev); \
} \
} while (0)

#endif /* NO_DECLTYPE */

/******************************************************************************
Expand Down Expand Up @@ -753,6 +788,27 @@ do {
#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2
#define DL_SEARCH2 LL_SEARCH2

#define DL_REVERSE(head) \
DL_REVERSE2(head,prev,next)

#define DL_REVERSE2(head,prev,next) \
do { \
if ((head) && (head)->next) { \
LDECLTYPE(head) _tail = (head); \
LDECLTYPE(head) _curr = (head); \
LDECLTYPE(head) _prev = NULL; \
while (_curr) { \
_prev = _curr->prev; \
_curr->prev = _curr->next; \
_curr->next = _prev; \
_curr = _curr->prev; \
} \
(head) = _prev->prev; \
_tail->next = NULL; \
(head)->prev = _tail; \
} \
} while (0)

#define DL_REPLACE_ELEM2(head, el, add, prev, next) \
do { \
assert((head) != NULL); \
Expand Down Expand Up @@ -855,6 +911,31 @@ do {
} \
} \
} while (0)

#undef DL_REVERSE2
#define DL_REVERSE2(head,prev,next) \
do { \
if ((head) && (head)->next) { \
char *_tail; \
char *_prev; \
char *_tmp; \
UTLIST_CASTASGN(_tail, (head)); \
while (head) { \
UTLIST_CASTASGN(_prev, (head)->prev); \
(head)->prev = (head)->next; \
UTLIST_CASTASGN((head)->next, _prev); \
(head) = (head)->prev; \
} \
UTLIST_CASTASGN((head), _prev); \
(head) = (head)->prev; \
UTLIST_CASTASGN(_tmp, (head)); \
UTLIST_CASTASGN((head), _tail); \
(head)->next = NULL; \
UTLIST_CASTASGN((head), _tmp); \
UTLIST_CASTASGN((head)->prev, _tail); \
} \
} while (0)

#endif /* NO_DECLTYPE */

/******************************************************************************
Expand Down Expand Up @@ -983,6 +1064,24 @@ do {
} \
} while (0)

#define CDL_REVERSE(head) \
CDL_REVERSE2(head,prev,next)

#define CDL_REVERSE2(head,prev,next) \
do { \
if ((head) && (head)->next) { \
LDECLTYPE(head) _curr = (head); \
LDECLTYPE(head) _prev = NULL; \
do { \
_prev = _curr->prev; \
_curr->prev = _curr->next; \
_curr->next = _prev; \
_curr = _curr->prev; \
} while(_curr != (head)); \
(head) = (head)->next; \
} \
} while (0)

#define CDL_REPLACE_ELEM2(head, el, add, prev, next) \
do { \
assert((head) != NULL); \
Expand Down Expand Up @@ -1071,6 +1170,24 @@ do {
UTLIST_RS(head); \
} \
} while (0)

#undef CDL_REVERSE2
#define CDL_REVERSE2(head,prev,next) \
do { \
if ((head) && (head)->next) { \
char *_curr; \
char *_prev; \
UTLIST_CASTASGN(_curr, (head)); \
do { \
UTLIST_CASTASGN(_prev, (head)->prev); \
(head)->prev = (head)->next; \
UTLIST_CASTASGN((head)->next, _prev); \
(head) = (head)->prev; \
} while(_curr != (char*)(head)); \
(head) = (head)->next; \
} \
} while (0)

#endif /* NO_DECLTYPE */

#endif /* UTLIST_H */
2 changes: 1 addition & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PROGS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \
test74 test75 test76 test77 test78 test79 test80 test81 \
test82 test83 test84 test85 test86 test87 test88 test89 \
test90 test91 test92 test93 test94 test95 test96 test97 \
test98 test99 test100
test98 test99 test100 test101 test102 test103
CFLAGS += -I$(HASHDIR)
#CFLAGS += -DHASH_BLOOM=16
#CFLAGS += -O2
Expand Down
13 changes: 13 additions & 0 deletions tests/test101.ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
0
1
2
4
8
16
32
64
128
256
512
1024
2048
38 changes: 38 additions & 0 deletions tests/test101.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include "utlist.h"

typedef struct List {
int value;
struct List *next;
} List;

int main(void) {
List *list = NULL, *node, *tmp;
int i;

for(i = 1; i <= 1024; i <<= 1) {
node = (List*)malloc(sizeof(*node));
node->value = i;
LL_PREPEND(list, node);
}

LL_REVERSE(list);

node = (List*)malloc(sizeof(*node));
node->value = 0;
LL_PREPEND(list, node);

node = (List*)malloc(sizeof(*node));
node->value = 2048;
LL_APPEND(list, node);

LL_FOREACH(list, node) {
printf("%d\n", node->value);
}

LL_FOREACH_SAFE(list, node, tmp) {
LL_DELETE(list, node);
free(node);
}
}
13 changes: 13 additions & 0 deletions tests/test102.ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
2048
1024
512
256
128
64
32
16
8
4
2
1
0
39 changes: 39 additions & 0 deletions tests/test102.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
#include "utlist.h"

typedef struct List {
int value;
struct List *prev;
struct List *next;
} List;

int main(void) {
List *list = NULL, *node, *tmp;
int i;

for(i = 1; i <= 1024; i <<= 1) {
node = (List*)malloc(sizeof(*node));
node->value = i;
DL_APPEND(list, node);
}

DL_REVERSE(list);

node = (List*)malloc(sizeof(*node));
node->value = 0;
DL_APPEND(list, node);

node = (List*)malloc(sizeof(*node));
node->value = 2048;
DL_PREPEND(list, node);

DL_FOREACH(list, node) {
printf("%d\n", node->value);
}

DL_FOREACH_SAFE(list, node, tmp) {
LL_DELETE(list, node);
free(node);
}
}
13 changes: 13 additions & 0 deletions tests/test103.ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
2048
1024
512
256
128
64
32
16
8
4
2
1
0
40 changes: 40 additions & 0 deletions tests/test103.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include "utlist.h"

typedef struct List {
int value;
struct List *prev;
struct List *next;
} List;

int main(void) {
List *list = NULL, *node,
*tmp1, *tmp2;
int i;

for(i = 1; i <= 1024; i <<= 1) {
node = (List*)malloc(sizeof(*node));
node->value = i;
CDL_APPEND(list, node);
}

CDL_REVERSE(list);

node = (List*)malloc(sizeof(*node));
node->value = 0;
CDL_APPEND(list, node);

node = (List*)malloc(sizeof(*node));
node->value = 2048;
CDL_PREPEND(list, node);

CDL_FOREACH(list, node) {
printf("%d\n", node->value);
}

CDL_FOREACH_SAFE(list, node, tmp1, tmp2) {
CDL_DELETE(list, node);
free(node);
}
}
Loading