src/list.c

changeset 641
d402fead3386
parent 640
55cc3b373c5e
child 647
2e6e9d9f2159
equal deleted inserted replaced
640:55cc3b373c5e 641:d402fead3386
27 */ 27 */
28 28
29 #include "cx/list.h" 29 #include "cx/list.h"
30 30
31 #include <string.h> 31 #include <string.h>
32
33 // <editor-fold desc="Store Pointers Functionality">
34
35 static _Thread_local CxListComparator cx_pl_cmpfunc_impl;
36
37 static int cx_pl_cmpfunc(
38 void const *l,
39 void const *r
40 ) {
41 void *const *lptr = l;
42 void *const *rptr = r;
43 void const *left = lptr == NULL ? NULL : *lptr;
44 void const *right = rptr == NULL ? NULL : *rptr;
45 return cx_pl_cmpfunc_impl(left, right);
46 }
47
48 static void cx_pl_hack_cmpfunc(struct cx_list_s const *list) {
49 // cast away const - this is the hacky thing
50 struct cx_list_s *l = (struct cx_list_s *) list;
51 cx_pl_cmpfunc_impl = l->cmpfunc;
52 l->cmpfunc = cx_pl_cmpfunc;
53 }
54
55 static void cx_pl_unhack_cmpfunc(struct cx_list_s const *list) {
56 // cast away const - this is the hacky thing
57 struct cx_list_s *l = (struct cx_list_s *) list;
58 l->cmpfunc = cx_pl_cmpfunc_impl;
59 }
60
61 static void cx_pl_destructor(struct cx_list_s *list) {
62 list->climpl->destructor(list);
63 }
64
65 static int cx_pl_insert_element(
66 struct cx_list_s *list,
67 size_t index,
68 void const *element
69 ) {
70 return list->climpl->insert_element(list, index, &element);
71 }
72
73 static size_t cx_pl_insert_array(
74 struct cx_list_s *list,
75 size_t index,
76 void const *array,
77 size_t n
78 ) {
79 return list->climpl->insert_array(list, index, array, n);
80 }
81
82 static int cx_pl_insert_iter(
83 struct cx_mut_iterator_s *iter,
84 void const *elem,
85 int prepend
86 ) {
87 struct cx_list_s *list = iter->src_handle;
88 return list->climpl->insert_iter(iter, &elem, prepend);
89 }
90
91 static int cx_pl_remove(
92 struct cx_list_s *list,
93 size_t index
94 ) {
95 return list->climpl->remove(list, index);
96 }
97
98 static void *cx_pl_at(
99 struct cx_list_s const *list,
100 size_t index
101 ) {
102 void **ptr = list->climpl->at(list, index);
103 return ptr == NULL ? NULL : *ptr;
104 }
105
106 static size_t cx_pl_find(
107 struct cx_list_s const *list,
108 void const *elem
109 ) {
110 cx_pl_hack_cmpfunc(list);
111 size_t ret = list->climpl->find(list, &elem);
112 cx_pl_unhack_cmpfunc(list);
113 return ret;
114 }
115
116 static void cx_pl_sort(struct cx_list_s *list) {
117 cx_pl_hack_cmpfunc(list);
118 list->climpl->sort(list);
119 cx_pl_unhack_cmpfunc(list);
120 }
121
122 static int cx_pl_compare(
123 struct cx_list_s const *list,
124 struct cx_list_s const *other
125 ) {
126 cx_pl_hack_cmpfunc(list);
127 int ret = list->climpl->compare(list, other);
128 cx_pl_unhack_cmpfunc(list);
129 return ret;
130 }
131
132 static void cx_pl_reverse(struct cx_list_s *list) {
133 list->climpl->reverse(list);
134 }
135
136 static void *cx_pl_iter_current(void const *it) {
137 struct cx_iterator_s const *iter = it;
138 void **ptr = iter->base.current_impl(it);
139 return ptr == NULL ? NULL : *ptr;
140 }
141
142 static struct cx_iterator_s cx_pl_iterator(
143 struct cx_list_s const *list,
144 size_t index
145 ) {
146 struct cx_iterator_s iter = list->climpl->iterator(list, index);
147 iter.base.current_impl = iter.base.current;
148 iter.base.current = cx_pl_iter_current;
149 return iter;
150 }
151
152 static cx_list_class cx_pointer_list_class = {
153 cx_pl_destructor,
154 cx_pl_insert_element,
155 cx_pl_insert_array,
156 cx_pl_insert_iter,
157 cx_pl_remove,
158 cx_pl_at,
159 cx_pl_find,
160 cx_pl_sort,
161 cx_pl_compare,
162 cx_pl_reverse,
163 cx_pl_iterator,
164 };
165
166 void cxListStoreObjects(CxList *list) {
167 if (list->climpl != NULL) {
168 list->cl = list->climpl;
169 list->climpl = NULL;
170 }
171 }
172
173 void cxListStorePointers(CxList *list) {
174 list->itemsize = sizeof(void *);
175 list->climpl = list->cl;
176 list->cl = &cx_pointer_list_class;
177 }
178
179 bool cxListIsStoringPointers(CxList *list) {
180 return list->climpl != NULL;
181 }
182
183 // </editor-fold>
32 184
33 void cxListDestroy(CxList *list) { 185 void cxListDestroy(CxList *list) {
34 switch (list->content_destructor_type) { 186 switch (list->content_destructor_type) {
35 case CX_DESTRUCTOR_SIMPLE: { 187 case CX_DESTRUCTOR_SIMPLE: {
36 CxIterator iter = cxListBegin(list); 188 CxIterator iter = cxListBegin(list);

mercurial