TEST_C(DequeTests, DequeRemoveLast) { int a = 1; int b = 2; int c = 3; int d = 4; deque_add_first(deque, &a); deque_add_first(deque, &b); deque_add_last(deque, &c); deque_add_last(deque, &d); int *last; deque_get_last(deque, (void*) &last); CHECK_EQUAL_C_INT(d, *last); int *removed; deque_remove_last(deque, (void*) &removed); CHECK_EQUAL_C_INT(d, *removed); deque_get_last(deque, (void*) &last); CHECK_EQUAL_C_INT(c, *last); };
/** * Removes a Deque element from the specified index and optionally sets the * out parameter to the value of the removed element. The index must be within * the bounds of the deque. * * @param[in] deque the deque from which the element is being removed * @param[in] index the index of the element being removed * @param[out] out Pointer to where the removed value is stored, * or NULL if it is to be ignored * * @return CC_OK if the element was successfully removed, or CC_ERR_OUT_OF_RANGE * if the index was out of range. */ enum cc_stat deque_remove_at(Deque *deque, size_t index, void **out) { if (index >= deque->size) return CC_ERR_OUT_OF_RANGE; const size_t c = deque->capacity - 1; const size_t l = deque->last & c; const size_t f = deque->first & c; const size_t p = (deque->first + index) & c; void *removed = deque->buffer[index]; if (index == 0) return deque_remove_first(deque, out); if (index == c) return deque_remove_last(deque, out); if (index <= (deque->size / 2) - 1) { if (p < f) { void *e = deque->buffer[c]; if (f != c) { memmove(&(deque->buffer[f + 1]), &(deque->buffer[f]), (c - f) * sizeof(void*)); } if (p != 0) { memmove(&(deque->buffer[1]), &(deque->buffer[0]), p * sizeof(void*)); } deque->buffer[0] = e; } else { memmove(&(deque->buffer[f + 1]), &(deque->buffer[f]), index * sizeof(void*)); } deque->first = (deque->first + 1) & c; } else { if (p > l) { void *e = deque->buffer[0]; if (p != c) { memmove(&(deque->buffer[p]), &(deque->buffer[p + 1]), (c - p) * sizeof(void*)); } if (p != 0) { memmove(&(deque->buffer[1]), &(deque->buffer[0]), l * sizeof(void*)); } deque->buffer[c] = e; } else { memmove(&(deque->buffer[p]), &(deque->buffer[p + 1]), (l - p) * sizeof(void*)); } deque->last = (deque->last- 1) & c; } deque->size--; if (out) *out = removed; return CC_OK; }
/** * Removes and returns a deque element from the specified index. The index must * be within the bounds of the deque, otherwise NULL is returned. NULL may also * be returned if the removed element was NULL. To resolve this ambiguity call * <code>deque_contains()</code> before this function. * * @param[in] deque the deque from which the element is being removed * @param[in] index the index of the element being removed * * @return the removed element, or NULL if the operation fails */ void *deque_remove_at(Deque *deque, size_t index) { if (index >= deque->size || index == NO_SUCH_INDEX) return NULL; const size_t c = deque->capacity - 1; const size_t l = deque->last & c; const size_t f = deque->first & c; const size_t p = (deque->first + index) & c; void *removed = deque->buffer[index]; if (index == 0) return deque_remove_first(deque); if (index == c) return deque_remove_last(deque); if (index <= (deque->size / 2) - 1) { if (p < f) { void *e = deque->buffer[c]; if (f != c) { memmove(&(deque->buffer[f + 1]), &(deque->buffer[f]), (c - f) * sizeof(void*)); } if (p != 0) { memmove(&(deque->buffer[1]), &(deque->buffer[0]), p * sizeof(void*)); } deque->buffer[0] = e; } else { memmove(&(deque->buffer[f + 1]), &(deque->buffer[f]), index * sizeof(void*)); } deque->first = (deque->first + 1) & c; } else { if (p > l) { void *e = deque->buffer[0]; if (p != c) { memmove(&(deque->buffer[p]), &(deque->buffer[p + 1]), (c - p) * sizeof(void*)); } if (p != 0) { memmove(&(deque->buffer[1]), &(deque->buffer[0]), l * sizeof(void*)); } deque->buffer[c] = e; } else { memmove(&(deque->buffer[p]), &(deque->buffer[p + 1]), (l - p) * sizeof(void*)); } deque->last = (deque->last- 1) & c; } deque->size--; return removed; }
/** * Gets and removes the element at the front of the queue and optionally * sets the out parameter to the value of the removed element. * * @param[in] queue the queue on which this operation is performed * @param[out] out Pointer to where the removed element is stored * * @return CC_OK if the element was found, or CC_ERR_VALUE_NOT_FOUND. */ enum cc_stat queue_poll(Queue *queue, void **out) { return deque_remove_last(queue->d, out); }