aboutsummaryrefslogtreecommitdiff
path: root/list
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-06-15 11:43:10 -0700
committer3gg <3gg@shellblade.net>2024-06-15 11:43:10 -0700
commitbec2d50c843ec4fd98bbbb212848ce4f24b96ebb (patch)
tree59c33bc964e723350886035fe249e41d0f8b397e /list
parent04e3ded4c28c0b559620609daaae7b939d776b61 (diff)
More convenient list iteration.
Diffstat (limited to 'list')
-rw-r--r--list/include/list.h44
-rw-r--r--list/test/list_test.c20
2 files changed, 32 insertions, 32 deletions
diff --git a/list/include/list.h b/list/include/list.h
index facf820..24291e1 100644
--- a/list/include/list.h
+++ b/list/include/list.h
@@ -5,15 +5,15 @@
5#include <stddef.h> 5#include <stddef.h>
6#include <stdlib.h> 6#include <stdlib.h>
7 7
8#define DEF_LIST(type) \ 8#define DEF_LIST(name, type) \
9 typedef struct type##_node { \ 9 typedef struct name##_node { \
10 type val; \ 10 type val; \
11 struct type##_node* prev; \ 11 struct name##_node* prev; \
12 struct type##_node* next; \ 12 struct name##_node* next; \
13 } type##_node; \ 13 } name##_node; \
14 typedef struct type##_list { \ 14 typedef struct name##_list { \
15 type##_node* head; \ 15 name##_node* head; \
16 } type##_list; 16 } name##_list;
17 17
18static inline void* alloc(size_t size) { 18static inline void* alloc(size_t size) {
19 void* ptr = calloc(1, size); 19 void* ptr = calloc(1, size);
@@ -35,7 +35,7 @@ static inline void* alloc(size_t size) {
35 list.head = 0; 35 list.head = 0;
36 36
37/// Prepend a value to the list. 37/// Prepend a value to the list.
38#define list_push(list, value) \ 38#define list_add(list, value) \
39 { \ 39 { \
40 __typeof__(list.head) node = alloc(sizeof(*list.head)); \ 40 __typeof__(list.head) node = alloc(sizeof(*list.head)); \
41 node->val = value; \ 41 node->val = value; \
@@ -86,13 +86,13 @@ static inline void* alloc(size_t size) {
86/// 86///
87/// Use 'value' to refer to the address of the current node's value during 87/// Use 'value' to refer to the address of the current node's value during
88/// iteration. 88/// iteration.
89#define list_foreach(list, body) \ 89#define list_foreach(list, value, body) \
90 { \ 90 { \
91 __typeof__(list.head) node = list.head; \ 91 __typeof__(list.head)* pNode = &list.head; \
92 while (node) { \ 92 while (*pNode) { \
93 const __typeof__(node->val)* value = &node->val; \ 93 __typeof__((*pNode)->val) value = (*pNode)->val; \
94 body; \ 94 body; \
95 node = node->next; \ 95 pNode = &(*pNode)->next; \
96 } \ 96 } \
97 } 97 }
98 98
@@ -100,12 +100,12 @@ static inline void* alloc(size_t size) {
100/// 100///
101/// Use 'value' to refer to the address of the current node's value during 101/// Use 'value' to refer to the address of the current node's value during
102/// iteration. 102/// iteration.
103#define list_foreach_mut(list, body) \ 103#define list_foreach_mut(list, value, body) \
104 { \ 104 { \
105 __typeof__(list.head) node = list.head; \ 105 __typeof__(list.head) node = list.head; \
106 while (node) { \ 106 while (node) { \
107 __typeof__(node->val)* value = &node->val; \ 107 __typeof__(node->val) value = node->val; \
108 body; \ 108 body; \
109 node = node->next; \ 109 node = node->next; \
110 } \ 110 } \
111 } 111 }
diff --git a/list/test/list_test.c b/list/test/list_test.c
index 9ff10c1..418e156 100644
--- a/list/test/list_test.c
+++ b/list/test/list_test.c
@@ -4,20 +4,20 @@
4 4
5#define TEST_LIST_SIZE 10 5#define TEST_LIST_SIZE 10
6 6
7DEF_LIST(int); 7DEF_LIST(int, int);
8 8
9// Iterate over a list. 9// Iterate over a list.
10TEST_CASE(list_traverse) { 10TEST_CASE(list_traverse) {
11 int_list list = make_list(int); 11 int_list list = make_list(int);
12 for (int i = 0; i < TEST_LIST_SIZE; ++i) { 12 for (int i = 0; i < TEST_LIST_SIZE; ++i) {
13 list_push(list, i + 1); 13 list_add(list, i + 1);
14 } 14 }
15 15
16 int count = 0; 16 int count = 0;
17 int sum = 0; 17 int sum = 0;
18 list_foreach(list, { 18 list_foreach(list, value, {
19 count++; 19 count++;
20 sum += *value; 20 sum += value;
21 }); 21 });
22 22
23 TEST_EQUAL(count, TEST_LIST_SIZE); 23 TEST_EQUAL(count, TEST_LIST_SIZE);
@@ -30,16 +30,16 @@ TEST_CASE(list_traverse) {
30TEST_CASE(list_remove_by_value) { 30TEST_CASE(list_remove_by_value) {
31 int_list list = make_list(int); 31 int_list list = make_list(int);
32 for (int i = 0; i < TEST_LIST_SIZE; ++i) { 32 for (int i = 0; i < TEST_LIST_SIZE; ++i) {
33 list_push(list, i + 1); 33 list_add(list, i + 1);
34 } 34 }
35 35
36 list_remove(list, 5); 36 list_remove(list, 5);
37 37
38 int count = 0; 38 int count = 0;
39 int sum = 0; 39 int sum = 0;
40 list_foreach(list, { 40 list_foreach(list, value, {
41 count++; 41 count++;
42 sum += *value; 42 sum += value;
43 }); 43 });
44 44
45 TEST_EQUAL(count, TEST_LIST_SIZE - 1); 45 TEST_EQUAL(count, TEST_LIST_SIZE - 1);
@@ -56,7 +56,7 @@ TEST_CASE(list_remove_by_address) {
56 56
57 int_list list = make_list(int); 57 int_list list = make_list(int);
58 for (int i = 0; i < N; ++i) { 58 for (int i = 0; i < N; ++i) {
59 list_push(list, i + 1); 59 list_add(list, i + 1);
60 ptrs[i] = &list.head->val; 60 ptrs[i] = &list.head->val;
61 } 61 }
62 62
@@ -64,9 +64,9 @@ TEST_CASE(list_remove_by_address) {
64 64
65 int count = 0; 65 int count = 0;
66 int sum = 0; 66 int sum = 0;
67 list_foreach(list, { 67 list_foreach(list, value, {
68 count++; 68 count++;
69 sum += *value; 69 sum += value;
70 }); 70 });
71 71
72 TEST_EQUAL(count, 2); 72 TEST_EQUAL(count, 2);