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; }
SetResult setRemove(Set set, SetElement element) { IF_NULL_RETURN_SET_NULL_ARGUMENT(set) IF_NULL_RETURN_SET_NULL_ARGUMENT(element) set->current = NULL; // iterator is undefined for every setRemove result 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) { return SET_ITEM_DOES_NOT_EXIST; // current element greater } if (cmpResult < 0) { // add element after iterating Node iteratingNode = iteratingNode->next; beforeNode = beforeNode->next; continue; } // cmpResult == 0 => delete the node beforeNode->next = iteratingNode->next; set->freeFunc(iteratingNode->data); free(iteratingNode); set->size--; return SET_SUCCESS; } return SET_ITEM_DOES_NOT_EXIST; }
SetElement setContains(Set set, SetElement element) { IF_NULL_RETURN_NULL(set) IF_NULL_RETURN_NULL(element) IS_SET_VALID(set) Node iteratingNode = set->dummy->next; while (iteratingNode != NULL) { if (iteratingNode->data != NULL && set->cmpFunc(iteratingNode->data, element) == 0) { set->current = iteratingNode; return iteratingNode->data; } iteratingNode = iteratingNode->next; } return NULL; }