TEST_C(DequeTests, DequeAddAt3) { /* index >= size / 2 && index_raw > last_raw */ int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; int f = 6; int g = 999; deque_add_last(deque, &a); deque_add_first(deque, &b); deque_add_first(deque, &c); deque_add_first(deque, &d); deque_add_first(deque, &e); deque_add_first(deque, &f); deque_add_at(deque, &g, 3); const void * const* buff = deque_get_buffer(deque); const void *elem = buff[6]; CHECK_EQUAL_C_POINTER(elem, &g); const void *elem1 = buff[0]; CHECK_EQUAL_C_POINTER(elem1, &b); const void *elem2 = buff[7]; CHECK_EQUAL_C_POINTER(elem2, &c); const void *elem3 = buff[1]; CHECK_EQUAL_C_POINTER(elem3, &a); };
TEST_C(DequeTestsConf, DequeBufferExpansion) { int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; int f = 6; deque_add_first(deque, &a); deque_add_last(deque, &b); deque_add_first(deque, &c); deque_add_last(deque, &d); size_t capacity = deque_capacity(deque); CHECK_EQUAL_C_INT(4, capacity); /* Current layout: _________________ | b | d | c | a | ----------------- L F */ /* This line should trigger the buffer expansion */ deque_add_first(deque, &e); capacity = deque_capacity(deque); CHECK_EQUAL_C_INT(8, capacity); /* The expansion should align the elements.*/ const void * const* buff = deque_get_buffer(deque); const int elem = *((int*) buff[0]); CHECK_EQUAL_C_INT(elem, c); const int elem1 = *((int*) buff[1]); CHECK_EQUAL_C_INT(elem1, a); const int elem2 = *((int*) buff[2]); CHECK_EQUAL_C_INT(elem2, b); const int elem3 = *((int*) buff[3]); CHECK_EQUAL_C_INT(elem3, d); const int elem4 = *((int*) buff[7]); CHECK_EQUAL_C_INT(elem4, e); deque_add_last(deque, &f); const int elem5 = *((int*) buff[4]); CHECK_EQUAL_C_INT(elem5, f); };
TEST_C(DequeTests, DequeGetLast) { int a = 1; int b = 2; int c = 3; deque_add_first(deque, &a); deque_add_last(deque, &b); deque_add_first(deque, &c); int *last; deque_get_last(deque, (void*) &last); CHECK_EQUAL_C_INT(b, *last); };
TEST_C(DequeTests, DequeAddAt4) { /* index < size / 2 && index_raw < last_raw*/ int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; int f = 6; int g = 999; deque_add_last(deque, &a); deque_add_last(deque, &b); deque_add_last(deque, &c); deque_add_last(deque, &d); deque_add_last(deque, &e); deque_add_first(deque, &f); deque_add_at(deque, &g, 1); const void * const*buff = deque_get_buffer(deque); const int elem = *((int*) buff[0]); CHECK_EQUAL_C_INT(elem, g); const int elem1 = *((int*) buff[4]); CHECK_EQUAL_C_INT(elem1, e); const int elem2 = *((int*) buff[6]); CHECK_EQUAL_C_INT(elem2, f); const int elem3 = *((int*) buff[7]); CHECK_EQUAL_C_INT(elem3, a); };
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); };
TEST_C(DequeTests, DequeAddFirst) { int a = 1; int b = 2; int c = 3; deque_add_first(deque, &a); deque_add_first(deque, &b); deque_add_first(deque, &c); CHECK_EQUAL_C_INT(3, deque_size(deque)); size_t m = deque_capacity(deque); const void * const* u = deque_get_buffer(deque); const void *e = u[m - 1]; CHECK_EQUAL_C_POINTER(e, &a); e = u[m - 2]; CHECK_EQUAL_C_POINTER(e, &b); e = u[m - 3]; CHECK_EQUAL_C_POINTER(e, &c); };
/** * Inserts a new element at the specified index within the deque. The index * must be within the range of the Deque. * * @param[in] deque Deque to which this new element is being added * @param[in] element element that is being added * @param[in] index position within the Deque at which this new element is * is being added * * @return CC_OK if the element was successfully added, CC_ERR_OUT_OF_RANGE if * the specified index was not in range, or CC_ERR_ALLOC if the memory * allocation for the new element failed. */ enum cc_stat deque_add_at(Deque *deque, void *element, size_t index) { if (index >= deque->size) return CC_ERR_OUT_OF_RANGE; if (deque->capacity == deque->size && expand_capacity(deque) != CC_OK) return CC_ERR_ALLOC; 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; if (index == 0) return deque_add_first(deque, element); if (index == c) return deque_add_last(deque, element); if (index <= (deque->size / 2) - 1) { if (p < f || f == 0) { /* _________________________________ * | 1 | 2 | 3 | 4 | 5 | . | . | 6 | * --------------------------------- * (p) <-- L F * * Left circular shift from (p) */ const size_t r_move = (f != 0) ? c - f + 1 : 0; const size_t l_move = p; void *e_first = deque->buffer[0]; if (f != 0) { memmove(&(deque->buffer[f - 1]), &(deque->buffer[f]), r_move * sizeof(void*)); } if (p != 0) { memmove(&(deque->buffer[0]), &(deque->buffer[1]), l_move * sizeof(void*)); } deque->buffer[c] = e_first; } else { memmove(&(deque->buffer[f - 1]), &(deque->buffer[f]), index * sizeof(void*)); } deque->first = (deque->first - 1) & c; } else { if (p > l || l == c) { /* _________________________________ * | 1 | . | . | 6 | 5 | 4 | 3 | 2 | * --------------------------------- * L F (p) --> * * Circular right shift from (p) */ void* e_last = deque->buffer[c]; if (p != c) { memmove(&(deque->buffer[p + 1]), &(deque->buffer[p]), (c - p) * sizeof(void*)); } if (l != c) { memmove(&(deque->buffer[1]), &(deque->buffer[0]), (l + 1) * sizeof(void*)); } deque->buffer[0] = e_last; } else { memmove(&(deque->buffer[p + 1]), &(deque->buffer[p]), (deque->size - index) * sizeof(void*)); } deque->last = (deque->last + 1) & c; } deque->buffer[p] = element; deque->size++; return CC_OK; }
/** * Appends an element to the back of the queue. This operation may * fail if the memory allocation for the new element fails. * * @param[in] queue the queue on which this operation is performed * @param[in] element the element being enqueued * * @return CC_OK if the element was successfully added, or CC_ERR_ALLOC * if the memory allocation for the new element has failed. */ enum cc_stat queue_enqueue(Queue *queue, void *element) { return deque_add_first(queue->d, element); }