Set setCopy(Set set) { IF_NULL_RETURN_NULL(set) IS_SET_VALID(set) Set newSet = setCreate(set->copyFunc, set->freeFunc, set->cmpFunc); IF_NULL_RETURN_NULL(newSet) Node nodeToCopy = set->dummy->next; Node lastCopiedNode = newSet->dummy; newSet->current = NULL; // in case current was undefined in original set while (nodeToCopy != NULL) { Node currNode = malloc(sizeof(*currNode)); if (currNode == NULL) { setDestroy(newSet); return NULL; } if (nodeToCopy->data == NULL) { currNode->data = NULL; } else { currNode->data = set->copyFunc(nodeToCopy->data); if (currNode->data == NULL) { free(currNode); setDestroy(newSet); return NULL; } } if (nodeToCopy == set->current) { newSet->current = currNode; } currNode->next = NULL; lastCopiedNode->next = currNode; lastCopiedNode = currNode; nodeToCopy = nodeToCopy->next; } newSet->size = setGetSize(set); return newSet; }
SetResult setAdd(Set set, SetElement element) { IF_NULL_RETURN_SET_NULL_ARGUMENT(set) IF_NULL_RETURN_SET_NULL_ARGUMENT(element) Node iteratingNode = set->dummy->next; Node beforeNode = set->dummy; while (iteratingNode != NULL) { assert(iteratingNode->data != NULL); int cmpResult = set->cmpFunc(iteratingNode->data, element); if (cmpResult > 0) { break; // Need to add element before iteratingNode } if (cmpResult < 0) { // add element after iterating Node iteratingNode = iteratingNode->next; beforeNode = beforeNode->next; continue; } return SET_ITEM_ALREADY_EXISTS; // cmpResult == 0 } Node newNode = malloc(sizeof(*newNode)); if (newNode == NULL) { return SET_OUT_OF_MEMORY; } newNode->data = set->copyFunc(element); if (newNode->data == NULL) { free(newNode); return SET_OUT_OF_MEMORY; } newNode->next = iteratingNode; beforeNode->next = newNode; set->size++; set->current = NULL; return SET_SUCCESS; }