src/linked_list.c

changeset 475
31bf97fdbf71
parent 474
9c1fccda16bc
child 476
60ff4561dc04
equal deleted inserted replaced
474:9c1fccda16bc 475:31bf97fdbf71
45 i < index ? i++ : i--; 45 i < index ? i++ : i--;
46 } 46 }
47 return cur; 47 return cur;
48 } 48 }
49 49
50 void *cx_linked_list_last(void *begin, ptrdiff_t loc_next) { 50 void *cx_linked_list_first(void *node, ptrdiff_t loc_prev) {
51 assert(loc_next >= 0); 51 return cx_linked_list_last(node, loc_prev);
52 if (begin == NULL) 52 }
53
54 void *cx_linked_list_last(void *node, ptrdiff_t loc_next) {
55 assert(loc_next >= 0);
56 if (node == NULL)
53 return NULL; 57 return NULL;
54 58
55 void *cur = begin; 59 void *cur = node;
56 void *last; 60 void *last;
57 do { 61 do {
58 last = cur; 62 last = cur;
59 } while ((cur = CX_LL_PTR(cur, loc_next)) != NULL); 63 } while ((cur = CX_LL_PTR(cur, loc_next)) != NULL);
60 64
74 } 78 }
75 } 79 }
76 80
77 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) { 81 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) {
78 assert(loc_next >= 0); 82 assert(loc_next >= 0);
83 assert(CX_LL_PTR(new_node, loc_next) == NULL);
79 void *last; 84 void *last;
80 if (end == NULL) { 85 if (end == NULL) {
81 assert(begin != NULL); 86 assert(begin != NULL);
82 last = cx_linked_list_last(*begin, loc_next); 87 last = cx_linked_list_last(*begin, loc_next);
83 } else { 88 } else {
84 last = *end; 89 last = *end;
85 } 90 }
86 if (last == NULL) { 91 if (last == NULL) {
87 assert(begin != NULL); 92 if (begin != NULL) {
88 *begin = new_node; 93 *begin = new_node;
94 }
89 } else { 95 } else {
90 // if there is a last node, update its next pointer 96 // if there is a last node, update its next pointer
91 CX_LL_PTR(last, loc_next) = new_node; 97 CX_LL_PTR(last, loc_next) = new_node;
92 } 98 }
93 99
94 // if there is an end pointer, update it 100 // if there is an end pointer, update it
95 if (end != NULL) { 101 if (end != NULL) {
96 *end = cx_linked_list_last(new_node, loc_next); 102 *end = new_node;
97 } 103 }
98 104
99 // if the nodes use a prev pointer, update it 105 // if the nodes use a prev pointer, update it
100 if (loc_prev >= 0) { 106 if (loc_prev >= 0) {
107 assert(CX_LL_PTR(new_node, loc_prev) == NULL);
101 CX_LL_PTR(new_node, loc_prev) = last; 108 CX_LL_PTR(new_node, loc_prev) = last;
109 }
110 }
111
112 void cx_linked_list_prepend(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node) {
113 assert(loc_next >= 0);
114 assert(CX_LL_PTR(new_node, loc_next) == NULL);
115 void *first;
116 if (begin == NULL) {
117 assert(end != NULL);
118 assert(loc_prev >= 0);
119 first = cx_linked_list_first(*end, loc_prev);
120 } else {
121 first = *begin;
122 }
123 if (first == NULL) {
124 if (end != NULL) {
125 *end = new_node;
126 }
127 } else {
128 CX_LL_PTR(new_node, loc_next) = first;
129 if (loc_prev >= 0) {
130 CX_LL_PTR(first, loc_prev) = new_node;
131 }
132 }
133
134 if (begin != NULL) {
135 assert(loc_prev < 0 || CX_LL_PTR(new_node, loc_prev) == NULL);
136 *begin = new_node;
102 } 137 }
103 } 138 }
104 139
105 void *cx_linked_list_remove(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node) { 140 void *cx_linked_list_remove(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node) {
106 assert(loc_next >= 0); 141 assert(loc_next >= 0);

mercurial