src/map.c

changeset 1449
bbca398783ed
parent 1446
5732947cbcc2
child 1450
09a73312d5ec
equal deleted inserted replaced
1448:0f0fe7311b76 1449:bbca398783ed
142 142
143 int cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func, 143 int cxMapClone(CxMap *dst, const CxMap *src, cx_clone_func clone_func,
144 const CxAllocator *clone_allocator, void *data) { 144 const CxAllocator *clone_allocator, void *data) {
145 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; 145 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator;
146 CxMapIterator src_iter = cxMapIterator(src); 146 CxMapIterator src_iter = cxMapIterator(src);
147 if (cxCollectionStoresPointers(dst)) { 147 for (size_t i = 0; i < cxMapSize(src); i++) {
148 for (size_t i = 0; i < cxMapSize(src); i++) { 148 const CxMapEntry *entry = cxIteratorCurrent(src_iter);
149 const CxMapEntry *entry = cxIteratorCurrent(src_iter); 149 void **dst_mem = cxMapEmplace(dst, *(entry->key));
150 void **dst_mem = cxMapEmplace(dst, *(entry->key)); 150 if (dst_mem == NULL) {
151 if (dst_mem == NULL) { 151 return 1;
152 return 1; 152 }
153 } 153 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem;
154 void *dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); 154 void *dst_ptr = clone_func(target, entry->value, clone_allocator, data);
155 if (dst_ptr == NULL) { 155 if (dst_ptr == NULL) {
156 cx_map_remove_uninitialized_entry(dst, *(entry->key)); 156 cx_map_remove_uninitialized_entry(dst, *(entry->key));
157 return 1; 157 return 1;
158 } 158 }
159 if (cxCollectionStoresPointers(dst)) {
159 *dst_mem = dst_ptr; 160 *dst_mem = dst_ptr;
160 cxIteratorNext(src_iter); 161 }
161 } 162 cxIteratorNext(src_iter);
162 } else {
163 for (size_t i = 0; i < cxMapSize(src); i++) {
164 const CxMapEntry *entry = cxIteratorCurrent(src_iter);
165 void *dst_mem = cxMapEmplace(dst, *(entry->key));
166 if (dst_mem == NULL) {
167 return 1;
168 }
169 if (clone_func(dst_mem, entry->value, clone_allocator, data) == NULL) {
170 cx_map_remove_uninitialized_entry(dst, *(entry->key));
171 return 1;
172 }
173 cxIteratorNext(src_iter);
174 }
175 } 163 }
176 return 0; 164 return 0;
177 } 165 }
178 166
179 int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend, 167 int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend,
180 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { 168 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) {
181 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; 169 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator;
182 170
183 const bool map_was_not_empty = cxMapSize(dst) > 0; 171 const bool map_was_not_empty = cxMapSize(dst) > 0;
184 CxMapIterator src_iter = cxMapIterator(minuend); 172 CxMapIterator src_iter = cxMapIterator(minuend);
185 if (cxCollectionStoresPointers(dst)) { 173 cx_foreach(const CxMapEntry *, entry, src_iter) {
186 cx_foreach(const CxMapEntry *, entry, src_iter) { 174 if (cxMapContains(subtrahend, *entry->key)) {
187 if (cxMapContains(subtrahend, *entry->key)) { 175 if (map_was_not_empty) {
188 if (map_was_not_empty) { 176 cxMapRemove(dst, *entry->key);
189 cxMapRemove(dst, *entry->key); 177 }
190 } 178 } else {
191 } else { 179 void** dst_mem = cxMapEmplace(dst, *entry->key);
192 void** dst_mem = cxMapEmplace(dst, *entry->key); 180 if (dst_mem == NULL) {
193 if (dst_mem == NULL) { 181 return 1;
194 return 1; 182 }
195 } 183 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem;
196 184 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data);
197 void* dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); 185 if (dst_ptr == NULL) {
198 if (dst_ptr == NULL) { 186 cx_map_remove_uninitialized_entry(dst, *(entry->key));
199 cx_map_remove_uninitialized_entry(dst, *(entry->key)); 187 return 1;
200 return 1; 188 }
201 } 189 if (cxCollectionStoresPointers(dst)) {
202 *dst_mem = dst_ptr; 190 *dst_mem = dst_ptr;
203 }
204 }
205 } else {
206 cx_foreach(const CxMapEntry *, entry, src_iter) {
207 if (cxMapContains(subtrahend, *entry->key)) {
208 if (map_was_not_empty) {
209 cxMapRemove(dst, *entry->key);
210 }
211 } else {
212 void* dst_mem = cxMapEmplace(dst, *entry->key);
213 if (dst_mem == NULL) {
214 return 1;
215 }
216 if (NULL == clone_func(dst_mem, entry->value, clone_allocator, data)) {
217 cx_map_remove_uninitialized_entry(dst, *entry->key);
218 return 1;
219 }
220 } 191 }
221 } 192 }
222 } 193 }
223 return 0; 194 return 0;
224 } 195 }
225 196
226 int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys, 197 int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys,
227 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) { 198 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data) {
228 const bool map_was_not_empty = cxMapSize(dst) > 0; 199 const bool map_was_not_empty = cxMapSize(dst) > 0;
229 CxMapIterator src_iter = cxMapIterator(src); 200 CxMapIterator src_iter = cxMapIterator(src);
230 if (cxCollectionStoresPointers(dst)) { 201 cx_foreach(const CxMapEntry *, entry, src_iter) {
231 cx_foreach(const CxMapEntry *, entry, src_iter) { 202 if (cxListContains(keys, entry->key)) {
232 if (cxListContains(keys, entry->key)) { 203 if (map_was_not_empty) {
233 if (map_was_not_empty) { 204 cxMapRemove(dst, *entry->key);
234 cxMapRemove(dst, *entry->key); 205 }
235 } 206 } else {
236 } else { 207 void** dst_mem = cxMapEmplace(dst, *entry->key);
237 void** dst_mem = cxMapEmplace(dst, *entry->key); 208 if (dst_mem == NULL) {
238 if (dst_mem == NULL) { 209 return 1;
239 return 1; 210 }
240 } 211 void *target = cxCollectionStoresPointers(dst) ? NULL : dst_mem;
241 212 void* dst_ptr = clone_func(target, entry->value, clone_allocator, data);
242 void* dst_ptr = clone_func(NULL, entry->value, clone_allocator, data); 213 if (dst_ptr == NULL) {
243 if (dst_ptr == NULL) { 214 cx_map_remove_uninitialized_entry(dst, *(entry->key));
244 cx_map_remove_uninitialized_entry(dst, *(entry->key)); 215 return 1;
245 return 1; 216 }
246 } 217 if (cxCollectionStoresPointers(dst)) {
247 *dst_mem = dst_ptr; 218 *dst_mem = dst_ptr;
248 }
249 }
250 } else {
251 cx_foreach(const CxMapEntry *, entry, src_iter) {
252 if (cxListContains(keys, entry->key)) {
253 if (map_was_not_empty) {
254 cxMapRemove(dst, *entry->key);
255 }
256 } else {
257 void* dst_mem = cxMapEmplace(dst, *entry->key);
258 if (dst_mem == NULL) {
259 return 1;
260 }
261 if (NULL == clone_func(dst_mem, entry->value, clone_allocator, data)) {
262 cx_map_remove_uninitialized_entry(dst, *entry->key);
263 return 1;
264 }
265 } 219 }
266 } 220 }
267 } 221 }
268 return 0; 222 return 0;
269 } 223 }

mercurial