mirror of
https://github.com/bkthomps/Containers.git
synced 2025-11-16 12:34:47 +00:00
Make c89 compatible (#27)
This commit is contained in:
@@ -3,7 +3,7 @@ project(Containers C)
|
||||
|
||||
set(CMAKE_C_STANDARD 90)
|
||||
|
||||
set(CMAKE_C_FLAGS "-g -O0 -Wall -fprofile-arcs -ftest-coverage")
|
||||
set(CMAKE_C_FLAGS "-pedantic -Werror -g -O0 -Wall -fprofile-arcs -ftest-coverage")
|
||||
|
||||
add_executable(Containers tst/test.c tst/test.h
|
||||
src/array.c src/array.h tst/array.c
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[](https://codedocs.xyz/bkthomps/Containers/)
|
||||
[](https://www.codacy.com/app/bkthomps/Containers?utm_source=github.com&utm_medium=referral&utm_content=bkthomps/Containers&utm_campaign=Badge_Grade)
|
||||
[](https://www.codefactor.io/repository/github/bkthomps/containers)
|
||||
[](https://en.wikipedia.org/wiki/C_(programming_language))
|
||||
[](https://en.wikipedia.org/wiki/C_(programming_language))
|
||||
[](https://lbesson.mit-license.org/)
|
||||
|
||||
# Containers
|
||||
|
||||
13
src/array.c
13
src/array.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "array.h"
|
||||
|
||||
@@ -41,10 +41,11 @@ struct internal_array {
|
||||
*/
|
||||
array array_init(const int element_count, const size_t data_size)
|
||||
{
|
||||
struct internal_array *init;
|
||||
if (element_count <= 0 || data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_array *const init = malloc(sizeof(struct internal_array));
|
||||
init = malloc(sizeof(struct internal_array));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -99,7 +100,7 @@ void *array_get_data(array me)
|
||||
/*
|
||||
* Determines if the input is illegal.
|
||||
*/
|
||||
static bool array_is_illegal_input(array me, const int index)
|
||||
static int array_is_illegal_input(array me, const int index)
|
||||
{
|
||||
return index < 0 || index >= me->item_count;
|
||||
}
|
||||
@@ -119,7 +120,8 @@ int array_set(array me, const int index, void *const data)
|
||||
if (array_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
|
||||
memcpy((char *) me->data + index * me->bytes_per_item, data,
|
||||
me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,7 +140,8 @@ int array_get(void *const data, array me, const int index)
|
||||
if (array_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(data, me->data + index * me->bytes_per_item, me->bytes_per_item);
|
||||
memcpy(data, (char *) me->data + index * me->bytes_per_item,
|
||||
me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
10
src/array.h
10
src/array.h
@@ -23,26 +23,24 @@
|
||||
#ifndef CONTAINERS_ARRAY_H
|
||||
#define CONTAINERS_ARRAY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The array data structure, which is a static contiguous array.
|
||||
*/
|
||||
typedef struct internal_array *array;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
array array_init(int element_count, size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int array_size(array me);
|
||||
void array_copy_to_array(void *arr, array me);
|
||||
void *array_get_data(array me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int array_set(array me, int index, void *data);
|
||||
int array_get(void *data, array me, int index);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
array array_destroy(array me);
|
||||
|
||||
#endif /* CONTAINERS_ARRAY_H */
|
||||
|
||||
114
src/deque.c
114
src/deque.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "deque.h"
|
||||
|
||||
@@ -49,10 +49,12 @@ struct node {
|
||||
*/
|
||||
deque deque_init(const size_t data_size)
|
||||
{
|
||||
struct internal_deque *init;
|
||||
struct node *block;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_deque *const init = malloc(sizeof(struct internal_deque));
|
||||
init = malloc(sizeof(struct internal_deque));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -65,7 +67,7 @@ deque deque_init(const size_t data_size)
|
||||
free(init);
|
||||
return NULL;
|
||||
}
|
||||
struct node *const block = init->block;
|
||||
block = init->block;
|
||||
block->data = malloc(BLOCK_SIZE * init->data_size);
|
||||
if (!block->data) {
|
||||
free(init->block);
|
||||
@@ -94,9 +96,9 @@ int deque_size(deque me)
|
||||
*
|
||||
* @param me the deque to check if empty
|
||||
*
|
||||
* @return true if empty
|
||||
* @return 1 if the deque is empty, otherwise 0
|
||||
*/
|
||||
bool deque_is_empty(deque me)
|
||||
int deque_is_empty(deque me)
|
||||
{
|
||||
return deque_size(me) == 0;
|
||||
}
|
||||
@@ -112,6 +114,7 @@ bool deque_is_empty(deque me)
|
||||
*/
|
||||
int deque_trim(deque me)
|
||||
{
|
||||
int i;
|
||||
const int start_block = me->start_index / BLOCK_SIZE;
|
||||
const int end_block = (me->end_index - 1) / BLOCK_SIZE;
|
||||
const int new_block_count = end_block - start_block + 1;
|
||||
@@ -119,7 +122,6 @@ int deque_trim(deque me)
|
||||
if (!new_block) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < start_block; i++) {
|
||||
const struct node block_item = me->block[i];
|
||||
free(block_item.data);
|
||||
@@ -149,7 +151,7 @@ void deque_copy_to_array(void *const arr, deque me)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < deque_size(me); i++) {
|
||||
deque_get_at(arr + i * me->data_size, me, i);
|
||||
deque_get_at((char *) arr + i * me->data_size, me, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +166,7 @@ void deque_copy_to_array(void *const arr, deque me)
|
||||
*/
|
||||
int deque_push_front(deque me, void *const data)
|
||||
{
|
||||
struct node block_item;
|
||||
int block_index = me->start_index / BLOCK_SIZE;
|
||||
int inner_index = me->start_index % BLOCK_SIZE;
|
||||
if (inner_index == -1) {
|
||||
@@ -171,7 +174,9 @@ int deque_push_front(deque me, void *const data)
|
||||
inner_index = BLOCK_SIZE - 1;
|
||||
}
|
||||
if (inner_index == BLOCK_SIZE - 1) {
|
||||
struct node *block_item_reference;
|
||||
if (block_index == -1) {
|
||||
int i;
|
||||
const int old_block_count = me->block_count;
|
||||
const int new_block_count =
|
||||
(int) (RESIZE_RATIO * me->block_count) + 1;
|
||||
@@ -189,22 +194,22 @@ int deque_push_front(deque me, void *const data)
|
||||
block_index = added_blocks - 1;
|
||||
me->start_index += added_blocks * BLOCK_SIZE;
|
||||
me->end_index += added_blocks * BLOCK_SIZE;
|
||||
int i;
|
||||
for (i = 0; i < added_blocks; i++) {
|
||||
struct node *const block_item = &me->block[i];
|
||||
block_item->data = NULL;
|
||||
struct node *const block_item_copy = &me->block[i];
|
||||
block_item_copy->data = NULL;
|
||||
}
|
||||
}
|
||||
struct node *const block_item = &me->block[block_index];
|
||||
if (!block_item->data) {
|
||||
block_item->data = malloc(BLOCK_SIZE * me->data_size);
|
||||
if (!block_item->data) {
|
||||
block_item_reference = &me->block[block_index];
|
||||
if (!block_item_reference->data) {
|
||||
block_item_reference->data = malloc(BLOCK_SIZE * me->data_size);
|
||||
if (!block_item_reference->data) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(block_item.data + inner_index * me->data_size, data, me->data_size);
|
||||
block_item = me->block[block_index];
|
||||
memcpy((char *) block_item.data + inner_index * me->data_size, data,
|
||||
me->data_size);
|
||||
me->start_index--;
|
||||
return 0;
|
||||
}
|
||||
@@ -220,10 +225,13 @@ int deque_push_front(deque me, void *const data)
|
||||
*/
|
||||
int deque_push_back(deque me, void *const data)
|
||||
{
|
||||
struct node block_item;
|
||||
const int block_index = me->end_index / BLOCK_SIZE;
|
||||
const int inner_index = me->end_index % BLOCK_SIZE;
|
||||
if (inner_index == 0) {
|
||||
struct node *block_item_reference;
|
||||
if (block_index == me->block_count) {
|
||||
int i;
|
||||
const int new_block_count =
|
||||
(int) (RESIZE_RATIO * me->block_count) + 1;
|
||||
void *temp = realloc(me->block,
|
||||
@@ -233,22 +241,22 @@ int deque_push_back(deque me, void *const data)
|
||||
}
|
||||
me->block = temp;
|
||||
me->block_count = new_block_count;
|
||||
int i;
|
||||
for (i = block_index; i < me->block_count; i++) {
|
||||
struct node *const block_item = &me->block[i];
|
||||
block_item->data = NULL;
|
||||
struct node *const block_item_copy = &me->block[i];
|
||||
block_item_copy->data = NULL;
|
||||
}
|
||||
}
|
||||
struct node *const block_item = &me->block[block_index];
|
||||
if (!block_item->data) {
|
||||
block_item->data = malloc(BLOCK_SIZE * me->data_size);
|
||||
if (!block_item->data) {
|
||||
block_item_reference = &me->block[block_index];
|
||||
if (!block_item_reference->data) {
|
||||
block_item_reference->data = malloc(BLOCK_SIZE * me->data_size);
|
||||
if (!block_item_reference->data) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(block_item.data + inner_index * me->data_size, data, me->data_size);
|
||||
block_item = me->block[block_index];
|
||||
memcpy((char *) block_item.data + inner_index * me->data_size, data,
|
||||
me->data_size);
|
||||
me->end_index++;
|
||||
return 0;
|
||||
}
|
||||
@@ -264,14 +272,18 @@ int deque_push_back(deque me, void *const data)
|
||||
*/
|
||||
int deque_pop_front(void *const data, deque me)
|
||||
{
|
||||
int block_index;
|
||||
int inner_index;
|
||||
struct node block_item;
|
||||
if (deque_is_empty(me)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
me->start_index++;
|
||||
const int block_index = me->start_index / BLOCK_SIZE;
|
||||
const int inner_index = me->start_index % BLOCK_SIZE;
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(data, block_item.data + inner_index * me->data_size, me->data_size);
|
||||
block_index = me->start_index / BLOCK_SIZE;
|
||||
inner_index = me->start_index % BLOCK_SIZE;
|
||||
block_item = me->block[block_index];
|
||||
memcpy(data, (char *) block_item.data + inner_index * me->data_size,
|
||||
me->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -286,14 +298,18 @@ int deque_pop_front(void *const data, deque me)
|
||||
*/
|
||||
int deque_pop_back(void *const data, deque me)
|
||||
{
|
||||
int block_index;
|
||||
int inner_index;
|
||||
struct node block_item;
|
||||
if (deque_is_empty(me)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
me->end_index--;
|
||||
const int block_index = me->end_index / BLOCK_SIZE;
|
||||
const int inner_index = me->end_index % BLOCK_SIZE;
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(data, block_item.data + inner_index * me->data_size, me->data_size);
|
||||
block_index = me->end_index / BLOCK_SIZE;
|
||||
inner_index = me->end_index % BLOCK_SIZE;
|
||||
block_item = me->block[block_index];
|
||||
memcpy(data, (char *) block_item.data + inner_index * me->data_size,
|
||||
me->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -323,14 +339,18 @@ int deque_set_first(deque me, void *const data)
|
||||
*/
|
||||
int deque_set_at(deque me, int index, void *const data)
|
||||
{
|
||||
int block_index;
|
||||
int inner_index;
|
||||
struct node block_item;
|
||||
if (index < 0 || index >= deque_size(me)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
index += me->start_index + 1;
|
||||
const int block_index = index / BLOCK_SIZE;
|
||||
const int inner_index = index % BLOCK_SIZE;
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(block_item.data + inner_index * me->data_size, data, me->data_size);
|
||||
block_index = index / BLOCK_SIZE;
|
||||
inner_index = index % BLOCK_SIZE;
|
||||
block_item = me->block[block_index];
|
||||
memcpy((char *) block_item.data + inner_index * me->data_size, data,
|
||||
me->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -374,14 +394,18 @@ int deque_get_first(void *const data, deque me)
|
||||
*/
|
||||
int deque_get_at(void *const data, deque me, int index)
|
||||
{
|
||||
int block_index;
|
||||
int inner_index;
|
||||
struct node block_item;
|
||||
if (index < 0 || index >= deque_size(me)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
index += me->start_index + 1;
|
||||
const int block_index = index / BLOCK_SIZE;
|
||||
const int inner_index = index % BLOCK_SIZE;
|
||||
const struct node block_item = me->block[block_index];
|
||||
memcpy(data, block_item.data + inner_index * me->data_size, me->data_size);
|
||||
block_index = index / BLOCK_SIZE;
|
||||
inner_index = index % BLOCK_SIZE;
|
||||
block_item = me->block[block_index];
|
||||
memcpy(data, (char *) block_item.data + inner_index * me->data_size,
|
||||
me->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -409,16 +433,18 @@ int deque_get_last(void *const data, deque me)
|
||||
*/
|
||||
int deque_clear(deque me)
|
||||
{
|
||||
void *temp_block_data;
|
||||
int i;
|
||||
struct node *block;
|
||||
struct node *const temp_block = malloc(sizeof(struct node));
|
||||
if (!temp_block) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
void *const temp_block_data = malloc(BLOCK_SIZE * me->data_size);
|
||||
temp_block_data = malloc(BLOCK_SIZE * me->data_size);
|
||||
if (!temp_block_data) {
|
||||
free(temp_block);
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->block_count; i++) {
|
||||
const struct node block_item = me->block[i];
|
||||
free(block_item.data);
|
||||
@@ -428,7 +454,7 @@ int deque_clear(deque me)
|
||||
me->end_index = me->start_index + 1;
|
||||
me->block_count = 1;
|
||||
me->block = temp_block;
|
||||
struct node *const block = me->block;
|
||||
block = me->block;
|
||||
block->data = temp_block_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
18
src/deque.h
18
src/deque.h
@@ -23,41 +23,39 @@
|
||||
#ifndef CONTAINERS_DEQUE_H
|
||||
#define CONTAINERS_DEQUE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The deque data structure, which is a doubly-ended queue.
|
||||
*/
|
||||
typedef struct internal_deque *deque;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
deque deque_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int deque_size(deque me);
|
||||
bool deque_is_empty(deque me);
|
||||
int deque_is_empty(deque me);
|
||||
int deque_trim(deque me);
|
||||
void deque_copy_to_array(void *arr, deque me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int deque_push_front(deque me, void *data);
|
||||
int deque_push_back(deque me, void *data);
|
||||
|
||||
// Removing
|
||||
/* Removing */
|
||||
int deque_pop_front(void *data, deque me);
|
||||
int deque_pop_back(void *data, deque me);
|
||||
|
||||
// Setting
|
||||
/* Setting */
|
||||
int deque_set_first(deque me, void *data);
|
||||
int deque_set_at(deque me, int index, void *data);
|
||||
int deque_set_last(deque me, void *data);
|
||||
|
||||
// Getting
|
||||
/* Getting */
|
||||
int deque_get_first(void *data, deque me);
|
||||
int deque_get_at(void *data, deque me, int index);
|
||||
int deque_get_last(void *data, deque me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int deque_clear(deque me);
|
||||
deque deque_destroy(deque me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "forward_list.h"
|
||||
|
||||
@@ -46,11 +46,11 @@ struct node {
|
||||
*/
|
||||
forward_list forward_list_init(const size_t data_size)
|
||||
{
|
||||
struct internal_forward_list *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_forward_list *const init =
|
||||
malloc(sizeof(struct internal_forward_list));
|
||||
init = malloc(sizeof(struct internal_forward_list));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -77,9 +77,9 @@ int forward_list_size(forward_list me)
|
||||
*
|
||||
* @param me the singly-linked list to check
|
||||
*
|
||||
* @return true if the singly-linked list is empty
|
||||
* @return 1 if the singly-linked list is empty, otherwise 0
|
||||
*/
|
||||
bool forward_list_is_empty(forward_list me)
|
||||
int forward_list_is_empty(forward_list me)
|
||||
{
|
||||
return forward_list_size(me) == 0;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ void forward_list_copy_to_array(void *const arr, forward_list me)
|
||||
struct node *traverse = me->head;
|
||||
int offset = 0;
|
||||
while (traverse) {
|
||||
memcpy(arr + offset, traverse->data, me->bytes_per_item);
|
||||
memcpy((char *) arr + offset, traverse->data, me->bytes_per_item);
|
||||
offset += me->bytes_per_item;
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -141,10 +141,11 @@ int forward_list_add_first(forward_list me, void *const data)
|
||||
*/
|
||||
int forward_list_add_at(forward_list me, const int index, void *const data)
|
||||
{
|
||||
struct node *add;
|
||||
if (index < 0 || index > me->item_count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const add = malloc(sizeof(struct node));
|
||||
add = malloc(sizeof(struct node));
|
||||
if (!add) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -183,7 +184,7 @@ int forward_list_add_last(forward_list me, void *const data)
|
||||
/*
|
||||
* Determines if the input is illegal.
|
||||
*/
|
||||
static bool forward_list_is_illegal_input(forward_list me, const int index)
|
||||
static int forward_list_is_illegal_input(forward_list me, const int index)
|
||||
{
|
||||
return index < 0 || index >= me->item_count;
|
||||
}
|
||||
@@ -275,10 +276,11 @@ int forward_list_set_first(forward_list me, void *const data)
|
||||
*/
|
||||
int forward_list_set_at(forward_list me, const int index, void *const data)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (forward_list_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const traverse = forward_list_get_node_at(me, index);
|
||||
traverse = forward_list_get_node_at(me, index);
|
||||
memcpy(traverse->data, data, me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
@@ -323,10 +325,11 @@ int forward_list_get_first(void *const data, forward_list me)
|
||||
*/
|
||||
int forward_list_get_at(void *const data, forward_list me, const int index)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (forward_list_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const traverse = forward_list_get_node_at(me, index);
|
||||
traverse = forward_list_get_node_at(me, index);
|
||||
memcpy(data, traverse->data, me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,42 +23,40 @@
|
||||
#ifndef CONTAINERS_FORWARD_LIST_H
|
||||
#define CONTAINERS_FORWARD_LIST_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The forward_list data structure, which is a singly-linked list.
|
||||
*/
|
||||
typedef struct internal_forward_list *forward_list;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
forward_list forward_list_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int forward_list_size(forward_list me);
|
||||
bool forward_list_is_empty(forward_list me);
|
||||
int forward_list_is_empty(forward_list me);
|
||||
void forward_list_copy_to_array(void *arr, forward_list me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int forward_list_add_first(forward_list me, void *data);
|
||||
int forward_list_add_at(forward_list me, int index, void *data);
|
||||
int forward_list_add_last(forward_list me, void *data);
|
||||
|
||||
// Removing
|
||||
/* Removing */
|
||||
int forward_list_remove_first(forward_list me);
|
||||
int forward_list_remove_at(forward_list me, int index);
|
||||
int forward_list_remove_last(forward_list me);
|
||||
|
||||
// Setting
|
||||
/* Setting */
|
||||
int forward_list_set_first(forward_list me, void *data);
|
||||
int forward_list_set_at(forward_list me, int index, void *data);
|
||||
int forward_list_set_last(forward_list me, void *data);
|
||||
|
||||
// Getting
|
||||
/* Getting */
|
||||
int forward_list_get_first(void *data, forward_list me);
|
||||
int forward_list_get_at(void *data, forward_list me, int index);
|
||||
int forward_list_get_last(void *data, forward_list me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void forward_list_clear(forward_list me);
|
||||
forward_list forward_list_destroy(forward_list me);
|
||||
|
||||
|
||||
30
src/list.c
30
src/list.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "list.h"
|
||||
|
||||
@@ -48,10 +48,11 @@ struct node {
|
||||
*/
|
||||
list list_init(const size_t data_size)
|
||||
{
|
||||
struct internal_list *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_list *const init = malloc(sizeof(struct internal_list));
|
||||
init = malloc(sizeof(struct internal_list));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -79,9 +80,9 @@ int list_size(list me)
|
||||
*
|
||||
* @param me the doubly-linked list to check
|
||||
*
|
||||
* @return true if the list is empty
|
||||
* @return 1 if the list is empty, otherwise 0
|
||||
*/
|
||||
bool list_is_empty(list me)
|
||||
int list_is_empty(list me)
|
||||
{
|
||||
return list_size(me) == 0;
|
||||
}
|
||||
@@ -97,7 +98,7 @@ void list_copy_to_array(void *const arr, list me)
|
||||
struct node *traverse = me->head;
|
||||
int offset = 0;
|
||||
while (traverse) {
|
||||
memcpy(arr + offset, traverse->data, me->bytes_per_item);
|
||||
memcpy((char *) arr + offset, traverse->data, me->bytes_per_item);
|
||||
offset += me->bytes_per_item;
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -189,6 +190,8 @@ int list_add_first(list me, void *const data)
|
||||
*/
|
||||
int list_add_at(list me, const int index, void *const data)
|
||||
{
|
||||
struct node *traverse;
|
||||
struct node *add;
|
||||
if (index < 0 || index > me->item_count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -198,9 +201,9 @@ int list_add_at(list me, const int index, void *const data)
|
||||
if (index == me->item_count) {
|
||||
return list_add_last(me, data);
|
||||
}
|
||||
// The new node will go right before this node.
|
||||
struct node *const traverse = list_get_node_at(me, index);
|
||||
struct node *const add = malloc(sizeof(struct node));
|
||||
/* The new node will go right before this node. */
|
||||
traverse = list_get_node_at(me, index);
|
||||
add = malloc(sizeof(struct node));
|
||||
if (!add) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -253,7 +256,7 @@ int list_add_last(list me, void *const data)
|
||||
/*
|
||||
* Determines if the input is illegal.
|
||||
*/
|
||||
static bool list_is_illegal_input(list me, const int index)
|
||||
static int list_is_illegal_input(list me, const int index)
|
||||
{
|
||||
return index < 0 || index >= me->item_count;
|
||||
}
|
||||
@@ -282,10 +285,11 @@ int list_remove_first(list me)
|
||||
*/
|
||||
int list_remove_at(list me, const int index)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (list_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const traverse = list_get_node_at(me, index);
|
||||
traverse = list_get_node_at(me, index);
|
||||
if (index == 0) {
|
||||
traverse->next->prev = NULL;
|
||||
me->head = traverse->next;
|
||||
@@ -341,10 +345,11 @@ int list_set_first(list me, void *const data)
|
||||
*/
|
||||
int list_set_at(list me, const int index, void *const data)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (list_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const traverse = list_get_node_at(me, index);
|
||||
traverse = list_get_node_at(me, index);
|
||||
memcpy(traverse->data, data, me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
@@ -389,10 +394,11 @@ int list_get_first(void *const data, list me)
|
||||
*/
|
||||
int list_get_at(void *const data, list me, const int index)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (list_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
struct node *const traverse = list_get_node_at(me, index);
|
||||
traverse = list_get_node_at(me, index);
|
||||
memcpy(data, traverse->data, me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
18
src/list.h
18
src/list.h
@@ -23,42 +23,40 @@
|
||||
#ifndef CONTAINERS_LIST_H
|
||||
#define CONTAINERS_LIST_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The list data structure, which is a doubly-linked list.
|
||||
*/
|
||||
typedef struct internal_list *list;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
list list_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int list_size(list me);
|
||||
bool list_is_empty(list me);
|
||||
int list_is_empty(list me);
|
||||
void list_copy_to_array(void *arr, list me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int list_add_first(list me, void *data);
|
||||
int list_add_at(list me, int index, void *data);
|
||||
int list_add_last(list me, void *data);
|
||||
|
||||
// Removing
|
||||
/* Removing */
|
||||
int list_remove_first(list me);
|
||||
int list_remove_at(list me, int index);
|
||||
int list_remove_last(list me);
|
||||
|
||||
// Setting
|
||||
/* Setting */
|
||||
int list_set_first(list me, void *data);
|
||||
int list_set_at(list me, int index, void *data);
|
||||
int list_set_last(list me, void *data);
|
||||
|
||||
// Getting
|
||||
/* Getting */
|
||||
int list_get_first(void *data, list me);
|
||||
int list_get_at(void *data, list me, int index);
|
||||
int list_get_last(void *data, list me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void list_clear(list me);
|
||||
list list_destroy(list me);
|
||||
|
||||
|
||||
92
src/map.c
92
src/map.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "map.h"
|
||||
|
||||
@@ -56,10 +56,11 @@ map map_init(const size_t key_size,
|
||||
const size_t value_size,
|
||||
int (*const comparator)(const void *const, const void *const))
|
||||
{
|
||||
struct internal_map *init;
|
||||
if (key_size == 0 || value_size == 0 || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_map *const init = malloc(sizeof(struct internal_map));
|
||||
init = malloc(sizeof(struct internal_map));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -88,9 +89,9 @@ int map_size(map me)
|
||||
*
|
||||
* @param me the map to check
|
||||
*
|
||||
* @return true if the map is empty
|
||||
* @return 1 if the map is empty, otherwise 0
|
||||
*/
|
||||
bool map_is_empty(map me)
|
||||
int map_is_empty(map me)
|
||||
{
|
||||
return map_size(me) == 0;
|
||||
}
|
||||
@@ -119,8 +120,9 @@ static void map_rotate_left(map me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
map_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->left;
|
||||
grand_child = child->left;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -136,8 +138,9 @@ static void map_rotate_right(map me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
map_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->right;
|
||||
grand_child = child->right;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -208,7 +211,7 @@ static struct node *map_repair(map me,
|
||||
grand_child->balance = 0;
|
||||
return grand_child;
|
||||
}
|
||||
// Impossible to get here.
|
||||
/* Impossible to get here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -226,13 +229,13 @@ static void map_insert_balance(map me, struct node *const item)
|
||||
} else {
|
||||
parent->balance++;
|
||||
}
|
||||
// If balance is zero after modification, then the tree is balanced.
|
||||
/* If balance is zero after modification, then the tree is balanced. */
|
||||
if (parent->balance == 0) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
// After one repair, the tree is balanced.
|
||||
/* After one repair, the tree is balanced. */
|
||||
map_repair(me, parent, child, grand_child);
|
||||
return;
|
||||
}
|
||||
@@ -288,6 +291,7 @@ static struct node *map_create_node(map me,
|
||||
*/
|
||||
int map_put(map me, void *const key, void *const value)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (!me->root) {
|
||||
struct node *insert = map_create_node(me, key, value, NULL);
|
||||
if (!insert) {
|
||||
@@ -296,8 +300,8 @@ int map_put(map me, void *const key, void *const value)
|
||||
me->root = insert;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->root;
|
||||
while (true) {
|
||||
traverse = me->root;
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -337,9 +341,9 @@ static struct node *map_equal_match(map me, const void *const key)
|
||||
{
|
||||
struct node *traverse = me->root;
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
while (true) {
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -366,16 +370,16 @@ static struct node *map_equal_match(map me, const void *const key)
|
||||
* @param me the map to get from
|
||||
* @param key the key to search for
|
||||
*
|
||||
* @return true if the map contained the key-value pair
|
||||
* @return 1 if the map contained the key-value pair, otherwise 0
|
||||
*/
|
||||
bool map_get(void *const value, map me, void *const key)
|
||||
int map_get(void *const value, map me, void *const key)
|
||||
{
|
||||
struct node *const traverse = map_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
memcpy(value, traverse->value, me->value_size);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,9 +388,9 @@ bool map_get(void *const value, map me, void *const key)
|
||||
* @param me the map to check for the element
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the map contained the element
|
||||
* @return 1 if the map contained the element, otherwise 0
|
||||
*/
|
||||
bool map_contains(map me, void *const key)
|
||||
int map_contains(map me, void *const key)
|
||||
{
|
||||
return map_equal_match(me, key) != NULL;
|
||||
}
|
||||
@@ -396,7 +400,7 @@ bool map_contains(map me, void *const key)
|
||||
*/
|
||||
static struct node *map_repair_pivot(map me,
|
||||
struct node *const item,
|
||||
const bool is_left_pivot)
|
||||
const int is_left_pivot)
|
||||
{
|
||||
struct node *const child = is_left_pivot ? item->right : item->left;
|
||||
struct node *const grand_child =
|
||||
@@ -409,42 +413,44 @@ static struct node *map_repair_pivot(map me,
|
||||
*/
|
||||
static void map_delete_balance(map me,
|
||||
struct node *item,
|
||||
const bool is_left_deleted)
|
||||
const int is_left_deleted)
|
||||
{
|
||||
struct node *child;
|
||||
struct node *parent;
|
||||
if (is_left_deleted) {
|
||||
item->balance++;
|
||||
} else {
|
||||
item->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification, then the tree is balanced. */
|
||||
if (item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (item->balance > 1 || item->balance < -1) {
|
||||
item = map_repair_pivot(me, item, is_left_deleted);
|
||||
if (!item->parent || item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct node *child = item;
|
||||
struct node *parent = item->parent;
|
||||
child = item;
|
||||
parent = item->parent;
|
||||
while (parent) {
|
||||
if (parent->left == child) {
|
||||
parent->balance++;
|
||||
} else {
|
||||
parent->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* The tree is balanced if balance is -1 or +1 after modification. */
|
||||
if (parent->balance == -1 || parent->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
child = map_repair_pivot(me, parent, parent->left == child);
|
||||
parent = child->parent;
|
||||
// If balance is -1 or +1 after modification or the parent is NULL,
|
||||
// then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification or the parent is */
|
||||
/* NULL, then the tree is balanced. */
|
||||
if (!parent || child->balance == -1 || child->balance == 1) {
|
||||
return;
|
||||
}
|
||||
@@ -461,18 +467,18 @@ static void map_delete_balance(map me,
|
||||
static void map_remove_no_children(map me, const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent and no children, then the only node is traverse.
|
||||
/* If no parent and no children, then the only node is traverse. */
|
||||
if (!parent) {
|
||||
me->root = NULL;
|
||||
return;
|
||||
}
|
||||
// No re-reference needed since traverse has no children.
|
||||
/* No re-reference needed since traverse has no children. */
|
||||
if (parent->left == traverse) {
|
||||
parent->left = NULL;
|
||||
map_delete_balance(me, parent, true);
|
||||
map_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
parent->right = NULL;
|
||||
map_delete_balance(me, parent, false);
|
||||
map_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +488,7 @@ static void map_remove_no_children(map me, const struct node *const traverse)
|
||||
static void map_remove_one_child(map me, const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent, make the child of traverse the new root.
|
||||
/* If no parent, make the child of traverse the new root. */
|
||||
if (!parent) {
|
||||
if (traverse->left) {
|
||||
traverse->left->parent = NULL;
|
||||
@@ -493,7 +499,7 @@ static void map_remove_one_child(map me, const struct node *const traverse)
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The parent of traverse now references the child of traverse.
|
||||
/* The parent of traverse now references the child of traverse. */
|
||||
if (parent->left == traverse) {
|
||||
if (traverse->left) {
|
||||
parent->left = traverse->left;
|
||||
@@ -502,7 +508,7 @@ static void map_remove_one_child(map me, const struct node *const traverse)
|
||||
parent->left = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
map_delete_balance(me, parent, true);
|
||||
map_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
if (traverse->left) {
|
||||
parent->right = traverse->left;
|
||||
@@ -511,7 +517,7 @@ static void map_remove_one_child(map me, const struct node *const traverse)
|
||||
parent->right = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
map_delete_balance(me, parent, false);
|
||||
map_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +528,7 @@ static void map_remove_two_children(map me, const struct node *const traverse)
|
||||
{
|
||||
struct node *item;
|
||||
struct node *parent;
|
||||
const bool is_left_deleted = traverse->right->left != NULL;
|
||||
const int is_left_deleted = traverse->right->left != NULL;
|
||||
if (!is_left_deleted) {
|
||||
item = traverse->right;
|
||||
parent = item;
|
||||
@@ -581,16 +587,16 @@ static void map_remove_element(map me, struct node *const traverse)
|
||||
* @param me the map to remove an element from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the map contained the key-value pair
|
||||
* @return 1 if the map contained the key-value pair, otherwise 0
|
||||
*/
|
||||
bool map_remove(map me, void *const key)
|
||||
int map_remove(map me, void *const key)
|
||||
{
|
||||
struct node *const traverse = map_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
map_remove_element(me, traverse);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
18
src/map.h
18
src/map.h
@@ -23,30 +23,28 @@
|
||||
#ifndef CONTAINERS_MAP_H
|
||||
#define CONTAINERS_MAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The map data structure, which is a collection of key-value pairs, sorted by
|
||||
* keys, keys are unique.
|
||||
*/
|
||||
typedef struct internal_map *map;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
map map_init(size_t key_size,
|
||||
size_t value_size,
|
||||
int (*comparator)(const void *const one, const void *const two));
|
||||
|
||||
// Capacity
|
||||
/* Capacity */
|
||||
int map_size(map me);
|
||||
bool map_is_empty(map me);
|
||||
int map_is_empty(map me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int map_put(map me, void *key, void *value);
|
||||
bool map_get(void *value, map me, void *key);
|
||||
bool map_contains(map me, void *key);
|
||||
bool map_remove(map me, void *key);
|
||||
int map_get(void *value, map me, void *key);
|
||||
int map_contains(map me, void *key);
|
||||
int map_remove(map me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void map_clear(map me);
|
||||
map map_destroy(map me);
|
||||
|
||||
|
||||
111
src/multimap.c
111
src/multimap.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "multimap.h"
|
||||
|
||||
@@ -69,12 +69,12 @@ multimap multimap_init(const size_t key_size,
|
||||
int (*const value_comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_multimap *init;
|
||||
if (key_size == 0 || value_size == 0
|
||||
|| !key_comparator || !value_comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_multimap *const init =
|
||||
malloc(sizeof(struct internal_multimap));
|
||||
init = malloc(sizeof(struct internal_multimap));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -105,9 +105,9 @@ int multimap_size(multimap me)
|
||||
*
|
||||
* @param me the multi-map to check
|
||||
*
|
||||
* @return true if the multi-map is empty
|
||||
* @return 1 if the multi-map is empty, otherwise 0
|
||||
*/
|
||||
bool multimap_is_empty(multimap me)
|
||||
int multimap_is_empty(multimap me)
|
||||
{
|
||||
return multimap_size(me) == 0;
|
||||
}
|
||||
@@ -136,8 +136,9 @@ static void multimap_rotate_left(multimap me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
multimap_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->left;
|
||||
grand_child = child->left;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -153,8 +154,9 @@ static void multimap_rotate_right(multimap me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
multimap_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->right;
|
||||
grand_child = child->right;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -225,7 +227,7 @@ static struct node *multimap_repair(multimap me,
|
||||
grand_child->balance = 0;
|
||||
return grand_child;
|
||||
}
|
||||
// Impossible to get here.
|
||||
/* Impossible to get here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -243,13 +245,13 @@ static void multimap_insert_balance(multimap me, struct node *const item)
|
||||
} else {
|
||||
parent->balance++;
|
||||
}
|
||||
// If balance is zero after modification, then the tree is balanced.
|
||||
/* If balance is zero after modification, then the tree is balanced. */
|
||||
if (parent->balance == 0) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
// After one repair, the tree is balanced.
|
||||
/* After one repair, the tree is balanced. */
|
||||
multimap_repair(me, parent, child, grand_child);
|
||||
return;
|
||||
}
|
||||
@@ -324,6 +326,7 @@ static struct node *multimap_create_node(multimap me,
|
||||
*/
|
||||
int multimap_put(multimap me, void *const key, void *const value)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (!me->root) {
|
||||
struct node *insert = multimap_create_node(me, key, value, NULL);
|
||||
if (!insert) {
|
||||
@@ -332,8 +335,8 @@ int multimap_put(multimap me, void *const key, void *const value)
|
||||
me->root = insert;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->root;
|
||||
while (true) {
|
||||
traverse = me->root;
|
||||
for (;;) {
|
||||
const int compare = me->key_comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -381,9 +384,9 @@ static struct node *multimap_equal_match(multimap me, const void *const key)
|
||||
{
|
||||
struct node *traverse = me->root;
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
while (true) {
|
||||
for (;;) {
|
||||
const int compare = me->key_comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -426,18 +429,19 @@ void multimap_get_start(multimap me, void *const key)
|
||||
* @param value the value to be copied to from iteration
|
||||
* @param me the multi-map to iterate over
|
||||
*
|
||||
* @return true if there exist no more values for the key which is being
|
||||
* iterated over
|
||||
* @return 1 if there exist no more values for the key which is being iterated
|
||||
* over, otherwise 0
|
||||
*/
|
||||
bool multimap_get_next(void *const value, multimap me)
|
||||
int multimap_get_next(void *const value, multimap me)
|
||||
{
|
||||
const struct value_node *item;
|
||||
if (!me->iterate_get) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
const struct value_node *const item = me->iterate_get;
|
||||
item = me->iterate_get;
|
||||
memcpy(value, item->value, me->value_size);
|
||||
me->iterate_get = item->next;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,9 +467,9 @@ int multimap_count(multimap me, void *const key)
|
||||
* @param me the multi-map to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the multi-map contained the key
|
||||
* @return 1 if the multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool multimap_contains(multimap me, void *const key)
|
||||
int multimap_contains(multimap me, void *const key)
|
||||
{
|
||||
return multimap_equal_match(me, key) != NULL;
|
||||
}
|
||||
@@ -475,7 +479,7 @@ bool multimap_contains(multimap me, void *const key)
|
||||
*/
|
||||
static struct node *multimap_repair_pivot(multimap me,
|
||||
struct node *const item,
|
||||
const bool is_left_pivot)
|
||||
const int is_left_pivot)
|
||||
{
|
||||
struct node *const child = is_left_pivot ? item->right : item->left;
|
||||
struct node *const grand_child =
|
||||
@@ -488,42 +492,44 @@ static struct node *multimap_repair_pivot(multimap me,
|
||||
*/
|
||||
static void multimap_delete_balance(multimap me,
|
||||
struct node *item,
|
||||
const bool is_left_deleted)
|
||||
const int is_left_deleted)
|
||||
{
|
||||
struct node *child;
|
||||
struct node *parent;
|
||||
if (is_left_deleted) {
|
||||
item->balance++;
|
||||
} else {
|
||||
item->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification, then the tree is balanced. */
|
||||
if (item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (item->balance > 1 || item->balance < -1) {
|
||||
item = multimap_repair_pivot(me, item, is_left_deleted);
|
||||
if (!item->parent || item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct node *child = item;
|
||||
struct node *parent = item->parent;
|
||||
child = item;
|
||||
parent = item->parent;
|
||||
while (parent) {
|
||||
if (parent->left == child) {
|
||||
parent->balance++;
|
||||
} else {
|
||||
parent->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* The tree is balanced if balance is -1 or +1 after modification. */
|
||||
if (parent->balance == -1 || parent->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
child = multimap_repair_pivot(me, parent, parent->left == child);
|
||||
parent = child->parent;
|
||||
// If balance is -1 or +1 after modification or the parent is NULL,
|
||||
// then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification or the parent is */
|
||||
/* NULL, then the tree is balanced. */
|
||||
if (!parent || child->balance == -1 || child->balance == 1) {
|
||||
return;
|
||||
}
|
||||
@@ -541,18 +547,18 @@ static void multimap_remove_no_children(multimap me,
|
||||
const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent and no children, then the only node is traverse.
|
||||
/* If no parent and no children, then the only node is traverse. */
|
||||
if (!parent) {
|
||||
me->root = NULL;
|
||||
return;
|
||||
}
|
||||
// No re-reference needed since traverse has no children.
|
||||
/* No re-reference needed since traverse has no children. */
|
||||
if (parent->left == traverse) {
|
||||
parent->left = NULL;
|
||||
multimap_delete_balance(me, parent, true);
|
||||
multimap_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
parent->right = NULL;
|
||||
multimap_delete_balance(me, parent, false);
|
||||
multimap_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,7 +569,7 @@ static void multimap_remove_one_child(multimap me,
|
||||
const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent, make the child of traverse the new root.
|
||||
/* If no parent, make the child of traverse the new root. */
|
||||
if (!parent) {
|
||||
if (traverse->left) {
|
||||
traverse->left->parent = NULL;
|
||||
@@ -574,7 +580,7 @@ static void multimap_remove_one_child(multimap me,
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The parent of traverse now references the child of traverse.
|
||||
/* The parent of traverse now references the child of traverse. */
|
||||
if (parent->left == traverse) {
|
||||
if (traverse->left) {
|
||||
parent->left = traverse->left;
|
||||
@@ -583,7 +589,7 @@ static void multimap_remove_one_child(multimap me,
|
||||
parent->left = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
multimap_delete_balance(me, parent, true);
|
||||
multimap_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
if (traverse->left) {
|
||||
parent->right = traverse->left;
|
||||
@@ -592,7 +598,7 @@ static void multimap_remove_one_child(multimap me,
|
||||
parent->right = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
multimap_delete_balance(me, parent, false);
|
||||
multimap_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +610,7 @@ static void multimap_remove_two_children(multimap me,
|
||||
{
|
||||
struct node *item;
|
||||
struct node *parent;
|
||||
const bool is_left_deleted = traverse->right->left != NULL;
|
||||
const int is_left_deleted = traverse->right->left != NULL;
|
||||
if (!is_left_deleted) {
|
||||
item = traverse->right;
|
||||
parent = item;
|
||||
@@ -662,15 +668,16 @@ static void multimap_remove_element(multimap me, struct node *const traverse)
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove
|
||||
*
|
||||
* @return true if the multi-map contained the key
|
||||
* @return 1 if the multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool multimap_remove(multimap me, void *const key, void *const value)
|
||||
int multimap_remove(multimap me, void *const key, void *const value)
|
||||
{
|
||||
struct value_node *current;
|
||||
struct node *const traverse = multimap_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct value_node *current = traverse->head;
|
||||
current = traverse->head;
|
||||
if (me->value_comparator(current->value, value) == 0) {
|
||||
traverse->head = current->next;
|
||||
} else {
|
||||
@@ -681,7 +688,7 @@ bool multimap_remove(multimap me, void *const key, void *const value)
|
||||
current = current->next;
|
||||
}
|
||||
if (!current) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
previous->next = current->next;
|
||||
}
|
||||
@@ -692,7 +699,7 @@ bool multimap_remove(multimap me, void *const key, void *const value)
|
||||
multimap_remove_element(me, traverse);
|
||||
}
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -718,16 +725,16 @@ static void multimap_remove_all_element(multimap me,
|
||||
* @param me the multi-map to remove a key-value pair from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the multi-map contained the key
|
||||
* @return 1 if the multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool multimap_remove_all(multimap me, void *const key)
|
||||
int multimap_remove_all(multimap me, void *const key)
|
||||
{
|
||||
struct node *const traverse = multimap_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
multimap_remove_all_element(me, traverse);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,15 +23,13 @@
|
||||
#ifndef CONTAINERS_MULTIMAP_H
|
||||
#define CONTAINERS_MULTIMAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The multimap data structure, which is a collection of key-value pairs, sorted
|
||||
* by keys.
|
||||
*/
|
||||
typedef struct internal_multimap *multimap;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
multimap multimap_init(size_t key_size,
|
||||
size_t value_size,
|
||||
int (*key_comparator)(const void *const one,
|
||||
@@ -39,20 +37,20 @@ multimap multimap_init(size_t key_size,
|
||||
int (*value_comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Capacity
|
||||
/* Capacity */
|
||||
int multimap_size(multimap me);
|
||||
bool multimap_is_empty(multimap me);
|
||||
int multimap_is_empty(multimap me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int multimap_put(multimap me, void *key, void *value);
|
||||
void multimap_get_start(multimap me, void *key);
|
||||
bool multimap_get_next(void *value, multimap me);
|
||||
int multimap_get_next(void *value, multimap me);
|
||||
int multimap_count(multimap me, void *key);
|
||||
bool multimap_contains(multimap me, void *key);
|
||||
bool multimap_remove(multimap me, void *key, void *value);
|
||||
bool multimap_remove_all(multimap me, void *key);
|
||||
int multimap_contains(multimap me, void *key);
|
||||
int multimap_remove(multimap me, void *key, void *value);
|
||||
int multimap_remove_all(multimap me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void multimap_clear(multimap me);
|
||||
multimap multimap_destroy(multimap me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "multiset.h"
|
||||
|
||||
@@ -55,11 +55,11 @@ multiset multiset_init(const size_t key_size,
|
||||
int (*const comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_multiset *init;
|
||||
if (key_size == 0 || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_multiset *const init =
|
||||
malloc(sizeof(struct internal_multiset));
|
||||
init = malloc(sizeof(struct internal_multiset));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -87,9 +87,9 @@ int multiset_size(multiset me)
|
||||
*
|
||||
* @param me the multi-set to check
|
||||
*
|
||||
* @return true if the multi-set is empty
|
||||
* @return 1 if the multi-set is empty, otherwise 0
|
||||
*/
|
||||
bool multiset_is_empty(multiset me)
|
||||
int multiset_is_empty(multiset me)
|
||||
{
|
||||
return multiset_size(me) == 0;
|
||||
}
|
||||
@@ -118,8 +118,9 @@ static void multiset_rotate_left(multiset me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
multiset_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->left;
|
||||
grand_child = child->left;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -135,8 +136,9 @@ static void multiset_rotate_right(multiset me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
multiset_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->right;
|
||||
grand_child = child->right;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -207,7 +209,7 @@ static struct node *multiset_repair(multiset me,
|
||||
grand_child->balance = 0;
|
||||
return grand_child;
|
||||
}
|
||||
// Impossible to get here.
|
||||
/* Impossible to get here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -225,13 +227,13 @@ static void multiset_insert_balance(multiset me, struct node *const item)
|
||||
} else {
|
||||
parent->balance++;
|
||||
}
|
||||
// If balance is zero after modification, then the tree is balanced.
|
||||
/* If balance is zero after modification, then the tree is balanced. */
|
||||
if (parent->balance == 0) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
// After one repair, the tree is balanced.
|
||||
/* After one repair, the tree is balanced. */
|
||||
multiset_repair(me, parent, child, grand_child);
|
||||
return;
|
||||
}
|
||||
@@ -278,6 +280,7 @@ static struct node *multiset_create_node(multiset me,
|
||||
*/
|
||||
int multiset_put(multiset me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (!me->root) {
|
||||
struct node *insert = multiset_create_node(me, key, NULL);
|
||||
if (!insert) {
|
||||
@@ -286,8 +289,8 @@ int multiset_put(multiset me, void *const key)
|
||||
me->root = insert;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->root;
|
||||
while (true) {
|
||||
traverse = me->root;
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -328,9 +331,9 @@ static struct node *multiset_equal_match(multiset me, const void *const key)
|
||||
{
|
||||
struct node *traverse = me->root;
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
while (true) {
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -373,9 +376,9 @@ int multiset_count(multiset me, void *const key)
|
||||
* @param me the multi-set to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the multiset contained the key
|
||||
* @return 1 if the multiset contained the key, otherwise 0
|
||||
*/
|
||||
bool multiset_contains(multiset me, void *const key)
|
||||
int multiset_contains(multiset me, void *const key)
|
||||
{
|
||||
return multiset_equal_match(me, key) != NULL;
|
||||
}
|
||||
@@ -385,7 +388,7 @@ bool multiset_contains(multiset me, void *const key)
|
||||
*/
|
||||
static struct node *multiset_repair_pivot(multiset me,
|
||||
struct node *const item,
|
||||
const bool is_left_pivot)
|
||||
const int is_left_pivot)
|
||||
{
|
||||
struct node *const child = is_left_pivot ? item->right : item->left;
|
||||
struct node *const grand_child =
|
||||
@@ -398,42 +401,44 @@ static struct node *multiset_repair_pivot(multiset me,
|
||||
*/
|
||||
static void multiset_delete_balance(multiset me,
|
||||
struct node *item,
|
||||
const bool is_left_deleted)
|
||||
const int is_left_deleted)
|
||||
{
|
||||
struct node *child;
|
||||
struct node *parent;
|
||||
if (is_left_deleted) {
|
||||
item->balance++;
|
||||
} else {
|
||||
item->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification, then the tree is balanced. */
|
||||
if (item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (item->balance > 1 || item->balance < -1) {
|
||||
item = multiset_repair_pivot(me, item, is_left_deleted);
|
||||
if (!item->parent || item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct node *child = item;
|
||||
struct node *parent = item->parent;
|
||||
child = item;
|
||||
parent = item->parent;
|
||||
while (parent) {
|
||||
if (parent->left == child) {
|
||||
parent->balance++;
|
||||
} else {
|
||||
parent->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* The tree is balanced if balance is -1 or +1 after modification. */
|
||||
if (parent->balance == -1 || parent->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
child = multiset_repair_pivot(me, parent, parent->left == child);
|
||||
parent = child->parent;
|
||||
// If balance is -1 or +1 after modification or the parent is NULL,
|
||||
// then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification or the parent is */
|
||||
/* NULL, then the tree is balanced. */
|
||||
if (!parent || child->balance == -1 || child->balance == 1) {
|
||||
return;
|
||||
}
|
||||
@@ -451,18 +456,18 @@ static void multiset_remove_no_children(multiset me,
|
||||
const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent and no children, then the only node is traverse.
|
||||
/* If no parent and no children, then the only node is traverse. */
|
||||
if (!parent) {
|
||||
me->root = NULL;
|
||||
return;
|
||||
}
|
||||
// No re-reference needed since traverse has no children.
|
||||
/* No re-reference needed since traverse has no children. */
|
||||
if (parent->left == traverse) {
|
||||
parent->left = NULL;
|
||||
multiset_delete_balance(me, parent, true);
|
||||
multiset_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
parent->right = NULL;
|
||||
multiset_delete_balance(me, parent, false);
|
||||
multiset_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +478,7 @@ static void multiset_remove_one_child(multiset me,
|
||||
const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent, make the child of traverse the new root.
|
||||
/* If no parent, make the child of traverse the new root. */
|
||||
if (!parent) {
|
||||
if (traverse->left) {
|
||||
traverse->left->parent = NULL;
|
||||
@@ -484,7 +489,7 @@ static void multiset_remove_one_child(multiset me,
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The parent of traverse now references the child of traverse.
|
||||
/* The parent of traverse now references the child of traverse. */
|
||||
if (parent->left == traverse) {
|
||||
if (traverse->left) {
|
||||
parent->left = traverse->left;
|
||||
@@ -493,7 +498,7 @@ static void multiset_remove_one_child(multiset me,
|
||||
parent->left = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
multiset_delete_balance(me, parent, true);
|
||||
multiset_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
if (traverse->left) {
|
||||
parent->right = traverse->left;
|
||||
@@ -502,7 +507,7 @@ static void multiset_remove_one_child(multiset me,
|
||||
parent->right = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
multiset_delete_balance(me, parent, false);
|
||||
multiset_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +519,7 @@ static void multiset_remove_two_children(multiset me,
|
||||
{
|
||||
struct node *item;
|
||||
struct node *parent;
|
||||
const bool is_left_deleted = traverse->right->left != NULL;
|
||||
const int is_left_deleted = traverse->right->left != NULL;
|
||||
if (!is_left_deleted) {
|
||||
item = traverse->right;
|
||||
parent = item;
|
||||
@@ -571,20 +576,20 @@ static void multiset_remove_element(multiset me, struct node *const traverse)
|
||||
* @param me the multi-set to remove a key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the multi-set contained the key
|
||||
* @return 1 if the multi-set contained the key, otherwise 0
|
||||
*/
|
||||
bool multiset_remove(multiset me, void *const key)
|
||||
int multiset_remove(multiset me, void *const key)
|
||||
{
|
||||
struct node *const traverse = multiset_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
traverse->count--;
|
||||
if (traverse->count == 0) {
|
||||
multiset_remove_element(me, traverse);
|
||||
}
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -593,17 +598,17 @@ bool multiset_remove(multiset me, void *const key)
|
||||
* @param me the multi-set to remove a key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the multi-set contained the key
|
||||
* @return 1 if the multi-set contained the key, otherwise 0
|
||||
*/
|
||||
bool multiset_remove_all(multiset me, void *const key)
|
||||
int multiset_remove_all(multiset me, void *const key)
|
||||
{
|
||||
struct node *const traverse = multiset_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
me->size -= traverse->count;
|
||||
multiset_remove_element(me, traverse);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,31 +23,29 @@
|
||||
#ifndef CONTAINERS_MULTISET_H
|
||||
#define CONTAINERS_MULTISET_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The multiset data structure, which is a collection of key-value pairs, sorted
|
||||
* by keys, keys are unique
|
||||
*/
|
||||
typedef struct internal_multiset *multiset;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
multiset multiset_init(size_t key_size,
|
||||
int (*comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Capacity
|
||||
/* Capacity */
|
||||
int multiset_size(multiset me);
|
||||
bool multiset_is_empty(multiset me);
|
||||
int multiset_is_empty(multiset me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int multiset_put(multiset me, void *key);
|
||||
int multiset_count(multiset me, void *key);
|
||||
bool multiset_contains(multiset me, void *key);
|
||||
bool multiset_remove(multiset me, void *key);
|
||||
bool multiset_remove_all(multiset me, void *key);
|
||||
int multiset_contains(multiset me, void *key);
|
||||
int multiset_remove(multiset me, void *key);
|
||||
int multiset_remove_all(multiset me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void multiset_clear(multiset me);
|
||||
multiset multiset_destroy(multiset me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "vector.h"
|
||||
#include "priority_queue.h"
|
||||
@@ -46,11 +46,11 @@ priority_queue priority_queue_init(const size_t data_size,
|
||||
int (*comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_priority_queue *init;
|
||||
if (data_size == 0 || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_priority_queue *const init =
|
||||
malloc(sizeof(struct internal_priority_queue));
|
||||
init = malloc(sizeof(struct internal_priority_queue));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -81,9 +81,9 @@ int priority_queue_size(priority_queue me)
|
||||
*
|
||||
* @param me the priority queue to check
|
||||
*
|
||||
* @return true if the priority queue is empty
|
||||
* @return 1 if the priority queue is empty, otherwise 0
|
||||
*/
|
||||
bool priority_queue_is_empty(priority_queue me)
|
||||
int priority_queue_is_empty(priority_queue me)
|
||||
{
|
||||
return vector_is_empty(me->data);
|
||||
}
|
||||
@@ -99,28 +99,35 @@ bool priority_queue_is_empty(priority_queue me)
|
||||
*/
|
||||
int priority_queue_push(priority_queue me, void *const data)
|
||||
{
|
||||
int rc;
|
||||
void *vector_storage;
|
||||
int index;
|
||||
int parent_index;
|
||||
void *data_index;
|
||||
void *data_parent_index;
|
||||
void *const temp = malloc(me->data_size);
|
||||
if (!temp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
const int rc = vector_add_last(me->data, data);
|
||||
rc = vector_add_last(me->data, data);
|
||||
if (rc != 0) {
|
||||
free(temp);
|
||||
return rc;
|
||||
}
|
||||
void *const vector_storage = vector_get_data(me->data);
|
||||
int index = vector_size(me->data) - 1;
|
||||
int parent_index = (index - 1) / 2;
|
||||
void *data_index = vector_storage + index * me->data_size;
|
||||
void *data_parent_index = vector_storage + parent_index * me->data_size;
|
||||
vector_storage = vector_get_data(me->data);
|
||||
index = vector_size(me->data) - 1;
|
||||
parent_index = (index - 1) / 2;
|
||||
data_index = (char *) vector_storage + index * me->data_size;
|
||||
data_parent_index = (char *) vector_storage + parent_index * me->data_size;
|
||||
while (index > 0 && me->comparator(data_index, data_parent_index) > 0) {
|
||||
memcpy(temp, data_parent_index, me->data_size);
|
||||
memcpy(data_parent_index, data_index, me->data_size);
|
||||
memcpy(data_index, temp, me->data_size);
|
||||
index = parent_index;
|
||||
parent_index = (index - 1) / 2;
|
||||
data_index = vector_storage + index * me->data_size;
|
||||
data_parent_index = vector_storage + parent_index * me->data_size;
|
||||
data_index = (char *) vector_storage + index * me->data_size;
|
||||
data_parent_index =
|
||||
(char *) vector_storage + parent_index * me->data_size;
|
||||
}
|
||||
free(temp);
|
||||
return 0;
|
||||
@@ -132,36 +139,44 @@ int priority_queue_push(priority_queue me, void *const data)
|
||||
* @param data the data to have copied from the priority queue
|
||||
* @param me the priority queue to pop the next element from
|
||||
*
|
||||
* @return true if the priority queue contained elements
|
||||
* @return 1 if the priority queue contained elements, otherwise 0
|
||||
*/
|
||||
bool priority_queue_pop(void *const data, priority_queue me)
|
||||
int priority_queue_pop(void *const data, priority_queue me)
|
||||
{
|
||||
void *vector_storage;
|
||||
int size;
|
||||
void *temp;
|
||||
int index;
|
||||
int left_index;
|
||||
int right_index;
|
||||
void *data_index;
|
||||
void *data_left_index;
|
||||
void *data_right_index;
|
||||
const int rc = vector_get_first(data, me->data);
|
||||
if (rc != 0) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
void *const vector_storage = vector_get_data(me->data);
|
||||
const int size = vector_size(me->data) - 1;
|
||||
void *const temp = vector_storage + size * me->data_size;
|
||||
vector_storage = vector_get_data(me->data);
|
||||
size = vector_size(me->data) - 1;
|
||||
temp = (char *) vector_storage + size * me->data_size;
|
||||
memcpy(vector_storage, temp, me->data_size);
|
||||
int index = 0;
|
||||
int left_index = 1;
|
||||
int right_index = 2;
|
||||
void *data_index = vector_storage;
|
||||
void *data_left_index = vector_storage + left_index * me->data_size;
|
||||
void *data_right_index = vector_storage + right_index * me->data_size;
|
||||
while (true) {
|
||||
left_index = 1;
|
||||
right_index = 2;
|
||||
data_index = vector_storage;
|
||||
data_left_index = (char *) vector_storage + left_index * me->data_size;
|
||||
data_right_index = (char *) vector_storage + right_index * me->data_size;
|
||||
for (;;) {
|
||||
if (right_index < size &&
|
||||
me->comparator(data_right_index, data_left_index) > 0 &&
|
||||
me->comparator(data_right_index, data_index) > 0) {
|
||||
// Swap parent and right child then continue down right child.
|
||||
/* Swap parent and right child then continue down right child. */
|
||||
memcpy(temp, data_index, me->data_size);
|
||||
memcpy(data_index, data_right_index, me->data_size);
|
||||
memcpy(data_right_index, temp, me->data_size);
|
||||
index = right_index;
|
||||
} else if (left_index < size &&
|
||||
me->comparator(data_left_index, data_index) > 0) {
|
||||
// Swap parent and left child then continue down left child.
|
||||
/* Swap parent and left child then continue down left child. */
|
||||
memcpy(temp, data_index, me->data_size);
|
||||
memcpy(data_index, data_left_index, me->data_size);
|
||||
memcpy(data_left_index, temp, me->data_size);
|
||||
@@ -171,12 +186,13 @@ bool priority_queue_pop(void *const data, priority_queue me)
|
||||
}
|
||||
left_index = 2 * index + 1;
|
||||
right_index = 2 * index + 2;
|
||||
data_index = vector_storage + index * me->data_size;
|
||||
data_left_index = vector_storage + left_index * me->data_size;
|
||||
data_right_index = vector_storage + right_index * me->data_size;
|
||||
data_index = (char *) vector_storage + index * me->data_size;
|
||||
data_left_index = (char *) vector_storage + left_index * me->data_size;
|
||||
data_right_index =
|
||||
(char *) vector_storage + right_index * me->data_size;
|
||||
}
|
||||
vector_remove_last(me->data);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,9 +202,9 @@ bool priority_queue_pop(void *const data, priority_queue me)
|
||||
* queue
|
||||
* @param me the priority queue to copy from
|
||||
*
|
||||
* @return true if the priority queue contained elements
|
||||
* @return 1 if the priority queue contained elements, otherwise 0
|
||||
*/
|
||||
bool priority_queue_front(void *const data, priority_queue me)
|
||||
int priority_queue_front(void *const data, priority_queue me)
|
||||
{
|
||||
return vector_get_first(data, me->data) == 0;
|
||||
}
|
||||
|
||||
@@ -23,33 +23,31 @@
|
||||
#ifndef CONTAINERS_PRIORITY_QUEUE_H
|
||||
#define CONTAINERS_PRIORITY_QUEUE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The priority_queue data structure, which adapts a container to provide a
|
||||
* priority queue. Adapts the vector container.
|
||||
*/
|
||||
typedef struct internal_priority_queue *priority_queue;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
priority_queue priority_queue_init(size_t data_size,
|
||||
int (*comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int priority_queue_size(priority_queue me);
|
||||
bool priority_queue_is_empty(priority_queue me);
|
||||
int priority_queue_is_empty(priority_queue me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int priority_queue_push(priority_queue me, void *data);
|
||||
|
||||
// Removing
|
||||
bool priority_queue_pop(void *data, priority_queue me);
|
||||
/* Removing */
|
||||
int priority_queue_pop(void *data, priority_queue me);
|
||||
|
||||
// Getting
|
||||
bool priority_queue_front(void *data, priority_queue me);
|
||||
/* Getting */
|
||||
int priority_queue_front(void *data, priority_queue me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int priority_queue_clear(priority_queue me);
|
||||
priority_queue priority_queue_destroy(priority_queue me);
|
||||
|
||||
|
||||
19
src/queue.c
19
src/queue.c
@@ -40,10 +40,11 @@ struct internal_queue {
|
||||
*/
|
||||
queue queue_init(const size_t data_size)
|
||||
{
|
||||
struct internal_queue *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_queue *const init = malloc(sizeof(struct internal_queue));
|
||||
init = malloc(sizeof(struct internal_queue));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -74,9 +75,9 @@ int queue_size(queue me)
|
||||
*
|
||||
* @param me the queue to check if empty
|
||||
*
|
||||
* @return true if the queue is empty
|
||||
* @return 1 if the queue is empty, otherwise 0
|
||||
*/
|
||||
bool queue_is_empty(queue me)
|
||||
int queue_is_empty(queue me)
|
||||
{
|
||||
return deque_is_empty(me->deque_data);
|
||||
}
|
||||
@@ -125,9 +126,9 @@ int queue_push(queue me, void *const data)
|
||||
* @param data the data to have copied from the queue
|
||||
* @param me the queue to pop the next element from
|
||||
*
|
||||
* @return true if the queue contained elements
|
||||
* @return 1 if the queue contained elements, otherwise 0
|
||||
*/
|
||||
bool queue_pop(void *const data, queue me)
|
||||
int queue_pop(void *const data, queue me)
|
||||
{
|
||||
me->trim_count++;
|
||||
if (TRIM_RATIO * me->trim_count >= queue_size(me)) {
|
||||
@@ -143,9 +144,9 @@ bool queue_pop(void *const data, queue me)
|
||||
* @param data the copy of the front element of the queue
|
||||
* @param me the queue to copy from
|
||||
*
|
||||
* @return true if the queue contained elements
|
||||
* @return 1 if the queue contained elements, otherwise 0
|
||||
*/
|
||||
bool queue_front(void *const data, queue me)
|
||||
int queue_front(void *const data, queue me)
|
||||
{
|
||||
return deque_get_first(data, me->deque_data) == 0;
|
||||
}
|
||||
@@ -156,9 +157,9 @@ bool queue_front(void *const data, queue me)
|
||||
* @param data the copy of the back element of the queue
|
||||
* @param me the queue to copy from
|
||||
*
|
||||
* @return true if the queue contained elements
|
||||
* @return 1 if the queue contained elements, otherwise 0
|
||||
*/
|
||||
bool queue_back(void *const data, queue me)
|
||||
int queue_back(void *const data, queue me)
|
||||
{
|
||||
return deque_get_last(data, me->deque_data) == 0;
|
||||
}
|
||||
|
||||
22
src/queue.h
22
src/queue.h
@@ -23,34 +23,32 @@
|
||||
#ifndef CONTAINERS_QUEUE_H
|
||||
#define CONTAINERS_QUEUE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The queue data structure, which adapts a container to provide a queue
|
||||
* (first-in first-out). Adapts the deque container.
|
||||
*/
|
||||
typedef struct internal_queue *queue;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
queue queue_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int queue_size(queue me);
|
||||
bool queue_is_empty(queue me);
|
||||
int queue_is_empty(queue me);
|
||||
int queue_trim(queue me);
|
||||
void queue_copy_to_array(void *arr, queue me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int queue_push(queue me, void *data);
|
||||
|
||||
// Removing
|
||||
bool queue_pop(void *data, queue me);
|
||||
/* Removing */
|
||||
int queue_pop(void *data, queue me);
|
||||
|
||||
// Getting
|
||||
bool queue_front(void *data, queue me);
|
||||
bool queue_back(void *data, queue me);
|
||||
/* Getting */
|
||||
int queue_front(void *data, queue me);
|
||||
int queue_back(void *data, queue me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int queue_clear(queue me);
|
||||
queue queue_destroy(queue me);
|
||||
|
||||
|
||||
84
src/set.c
84
src/set.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "set.h"
|
||||
|
||||
@@ -52,10 +52,11 @@ struct node {
|
||||
set set_init(const size_t key_size,
|
||||
int (*const comparator)(const void *const, const void *const))
|
||||
{
|
||||
struct internal_set *init;
|
||||
if (key_size == 0 || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_set *const init = malloc(sizeof(struct internal_set));
|
||||
init = malloc(sizeof(struct internal_set));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -83,9 +84,9 @@ int set_size(set me)
|
||||
*
|
||||
* @param me the set to check
|
||||
*
|
||||
* @return true if the set is empty
|
||||
* @return 1 if the set is empty, otherwise 0
|
||||
*/
|
||||
bool set_is_empty(set me)
|
||||
int set_is_empty(set me)
|
||||
{
|
||||
return set_size(me) == 0;
|
||||
}
|
||||
@@ -114,8 +115,9 @@ static void set_rotate_left(set me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
set_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->left;
|
||||
grand_child = child->left;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -131,8 +133,9 @@ static void set_rotate_right(set me,
|
||||
struct node *const parent,
|
||||
struct node *const child)
|
||||
{
|
||||
struct node *grand_child;
|
||||
set_reference_parent(me, parent, child);
|
||||
struct node *const grand_child = child->right;
|
||||
grand_child = child->right;
|
||||
if (grand_child) {
|
||||
grand_child->parent = parent;
|
||||
}
|
||||
@@ -203,7 +206,7 @@ static struct node *set_repair(set me,
|
||||
grand_child->balance = 0;
|
||||
return grand_child;
|
||||
}
|
||||
// Impossible to get here.
|
||||
/* Impossible to get here. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -221,13 +224,13 @@ static void set_insert_balance(set me, struct node *const item)
|
||||
} else {
|
||||
parent->balance++;
|
||||
}
|
||||
// If balance is zero after modification, then the tree is balanced.
|
||||
/* If balance is zero after modification, then the tree is balanced. */
|
||||
if (parent->balance == 0) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
// After one repair, the tree is balanced.
|
||||
/* After one repair, the tree is balanced. */
|
||||
set_repair(me, parent, child, grand_child);
|
||||
return;
|
||||
}
|
||||
@@ -273,6 +276,7 @@ static struct node *set_create_node(set me,
|
||||
*/
|
||||
int set_put(set me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
if (!me->root) {
|
||||
struct node *insert = set_create_node(me, key, NULL);
|
||||
if (!insert) {
|
||||
@@ -281,8 +285,8 @@ int set_put(set me, void *const key)
|
||||
me->root = insert;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->root;
|
||||
while (true) {
|
||||
traverse = me->root;
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -321,9 +325,9 @@ static struct node *set_equal_match(set me, const void *const key)
|
||||
{
|
||||
struct node *traverse = me->root;
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
while (true) {
|
||||
for (;;) {
|
||||
const int compare = me->comparator(key, traverse->key);
|
||||
if (compare < 0) {
|
||||
if (traverse->left) {
|
||||
@@ -349,9 +353,9 @@ static struct node *set_equal_match(set me, const void *const key)
|
||||
* @param me the set to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the set contained the key
|
||||
* @return 1 if the set contained the key, otherwise 0
|
||||
*/
|
||||
bool set_contains(set me, void *const key)
|
||||
int set_contains(set me, void *const key)
|
||||
{
|
||||
return set_equal_match(me, key) != NULL;
|
||||
}
|
||||
@@ -361,7 +365,7 @@ bool set_contains(set me, void *const key)
|
||||
*/
|
||||
static struct node *set_repair_pivot(set me,
|
||||
struct node *const item,
|
||||
const bool is_left_pivot)
|
||||
const int is_left_pivot)
|
||||
{
|
||||
struct node *const child = is_left_pivot ? item->right : item->left;
|
||||
struct node *const grand_child =
|
||||
@@ -374,42 +378,44 @@ static struct node *set_repair_pivot(set me,
|
||||
*/
|
||||
static void set_delete_balance(set me,
|
||||
struct node *item,
|
||||
const bool is_left_deleted)
|
||||
const int is_left_deleted)
|
||||
{
|
||||
struct node *child;
|
||||
struct node *parent;
|
||||
if (is_left_deleted) {
|
||||
item->balance++;
|
||||
} else {
|
||||
item->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification, then the tree is balanced. */
|
||||
if (item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (item->balance > 1 || item->balance < -1) {
|
||||
item = set_repair_pivot(me, item, is_left_deleted);
|
||||
if (!item->parent || item->balance == -1 || item->balance == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct node *child = item;
|
||||
struct node *parent = item->parent;
|
||||
child = item;
|
||||
parent = item->parent;
|
||||
while (parent) {
|
||||
if (parent->left == child) {
|
||||
parent->balance++;
|
||||
} else {
|
||||
parent->balance--;
|
||||
}
|
||||
// If balance is -1 or +1 after modification, then the tree is balanced.
|
||||
/* The tree is balanced if balance is -1 or +1 after modification. */
|
||||
if (parent->balance == -1 || parent->balance == 1) {
|
||||
return;
|
||||
}
|
||||
// Must re-balance if not in {-1, 0, 1}
|
||||
/* Must re-balance if not in {-1, 0, 1} */
|
||||
if (parent->balance > 1 || parent->balance < -1) {
|
||||
child = set_repair_pivot(me, parent, parent->left == child);
|
||||
parent = child->parent;
|
||||
// If balance is -1 or +1 after modification or the parent is NULL,
|
||||
// then the tree is balanced.
|
||||
/* If balance is -1 or +1 after modification or the parent is */
|
||||
/* NULL, then the tree is balanced. */
|
||||
if (!parent || child->balance == -1 || child->balance == 1) {
|
||||
return;
|
||||
}
|
||||
@@ -426,18 +432,18 @@ static void set_delete_balance(set me,
|
||||
static void set_remove_no_children(set me, const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent and no children, then the only node is traverse.
|
||||
/* If no parent and no children, then the only node is traverse. */
|
||||
if (!parent) {
|
||||
me->root = NULL;
|
||||
return;
|
||||
}
|
||||
// No re-reference needed since traverse has no children.
|
||||
/* No re-reference needed since traverse has no children. */
|
||||
if (parent->left == traverse) {
|
||||
parent->left = NULL;
|
||||
set_delete_balance(me, parent, true);
|
||||
set_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
parent->right = NULL;
|
||||
set_delete_balance(me, parent, false);
|
||||
set_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +453,7 @@ static void set_remove_no_children(set me, const struct node *const traverse)
|
||||
static void set_remove_one_child(set me, const struct node *const traverse)
|
||||
{
|
||||
struct node *const parent = traverse->parent;
|
||||
// If no parent, make the child of traverse the new root.
|
||||
/* If no parent, make the child of traverse the new root. */
|
||||
if (!parent) {
|
||||
if (traverse->left) {
|
||||
traverse->left->parent = NULL;
|
||||
@@ -458,7 +464,7 @@ static void set_remove_one_child(set me, const struct node *const traverse)
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The parent of traverse now references the child of traverse.
|
||||
/* The parent of traverse now references the child of traverse. */
|
||||
if (parent->left == traverse) {
|
||||
if (traverse->left) {
|
||||
parent->left = traverse->left;
|
||||
@@ -467,7 +473,7 @@ static void set_remove_one_child(set me, const struct node *const traverse)
|
||||
parent->left = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
set_delete_balance(me, parent, true);
|
||||
set_delete_balance(me, parent, 1);
|
||||
} else {
|
||||
if (traverse->left) {
|
||||
parent->right = traverse->left;
|
||||
@@ -476,7 +482,7 @@ static void set_remove_one_child(set me, const struct node *const traverse)
|
||||
parent->right = traverse->right;
|
||||
traverse->right->parent = parent;
|
||||
}
|
||||
set_delete_balance(me, parent, false);
|
||||
set_delete_balance(me, parent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,7 +493,7 @@ static void set_remove_two_children(set me, const struct node *const traverse)
|
||||
{
|
||||
struct node *item;
|
||||
struct node *parent;
|
||||
const bool is_left_deleted = traverse->right->left != NULL;
|
||||
const int is_left_deleted = traverse->right->left != NULL;
|
||||
if (!is_left_deleted) {
|
||||
item = traverse->right;
|
||||
parent = item;
|
||||
@@ -545,16 +551,16 @@ static void set_remove_element(set me, struct node *const traverse)
|
||||
* @param me the set to remove an key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the set contained the key
|
||||
* @return 1 if the set contained the key, otherwise 0
|
||||
*/
|
||||
bool set_remove(set me, void *const key)
|
||||
int set_remove(set me, void *const key)
|
||||
{
|
||||
struct node *const traverse = set_equal_match(me, key);
|
||||
if (!traverse) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
set_remove_element(me, traverse);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
16
src/set.h
16
src/set.h
@@ -23,27 +23,25 @@
|
||||
#ifndef CONTAINERS_SET_H
|
||||
#define CONTAINERS_SET_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The set data structure, which is a collection of unique keys, sorted by keys.
|
||||
*/
|
||||
typedef struct internal_set *set;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
set set_init(size_t key_size,
|
||||
int (*comparator)(const void *const one, const void *const two));
|
||||
|
||||
// Capacity
|
||||
/* Capacity */
|
||||
int set_size(set me);
|
||||
bool set_is_empty(set me);
|
||||
int set_is_empty(set me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int set_put(set me, void *key);
|
||||
bool set_contains(set me, void *key);
|
||||
bool set_remove(set me, void *key);
|
||||
int set_contains(set me, void *key);
|
||||
int set_remove(set me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
void set_clear(set me);
|
||||
set set_destroy(set me);
|
||||
|
||||
|
||||
15
src/stack.c
15
src/stack.c
@@ -38,10 +38,11 @@ struct internal_stack {
|
||||
*/
|
||||
stack stack_init(const size_t data_size)
|
||||
{
|
||||
struct internal_stack *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_stack *const init = malloc(sizeof(struct internal_stack));
|
||||
init = malloc(sizeof(struct internal_stack));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -70,9 +71,9 @@ int stack_size(stack me)
|
||||
*
|
||||
* @param me the stack to check if empty
|
||||
*
|
||||
* @return true if the stack is empty
|
||||
* @return 1 if the stack is empty, otherwise 0
|
||||
*/
|
||||
bool stack_is_empty(stack me)
|
||||
int stack_is_empty(stack me)
|
||||
{
|
||||
return deque_is_empty(me->deque_data);
|
||||
}
|
||||
@@ -122,9 +123,9 @@ int stack_push(stack me, void *const data)
|
||||
* @param data the copy of the element being removed
|
||||
* @param me the stack to remove the top element from
|
||||
*
|
||||
* @return true if the stack contained elements
|
||||
* @return 1 if the stack contained elements, otherwise 0
|
||||
*/
|
||||
bool stack_pop(void *const data, stack me)
|
||||
int stack_pop(void *const data, stack me)
|
||||
{
|
||||
return deque_pop_back(data, me->deque_data) == 0;
|
||||
}
|
||||
@@ -135,9 +136,9 @@ bool stack_pop(void *const data, stack me)
|
||||
* @param data the copy of the top element of the stack
|
||||
* @param me the stack to copy from
|
||||
*
|
||||
* @return true if the stack contained elements
|
||||
* @return 1 if the stack contained elements, otherwise 0
|
||||
*/
|
||||
bool stack_top(void *const data, stack me)
|
||||
int stack_top(void *const data, stack me)
|
||||
{
|
||||
return deque_get_last(data, me->deque_data) == 0;
|
||||
}
|
||||
|
||||
20
src/stack.h
20
src/stack.h
@@ -23,33 +23,31 @@
|
||||
#ifndef CONTAINERS_STACK_H
|
||||
#define CONTAINERS_STACK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The stack data structure, which adapts a container to provide a stack
|
||||
* (last-in first-out). Adapts the deque container.
|
||||
*/
|
||||
typedef struct internal_stack *stack;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
stack stack_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int stack_size(stack me);
|
||||
bool stack_is_empty(stack me);
|
||||
int stack_is_empty(stack me);
|
||||
int stack_trim(stack me);
|
||||
void stack_copy_to_array(void *arr, stack me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int stack_push(stack me, void *data);
|
||||
|
||||
// Removing
|
||||
bool stack_pop(void *data, stack me);
|
||||
/* Removing */
|
||||
int stack_pop(void *data, stack me);
|
||||
|
||||
// Getting
|
||||
bool stack_top(void *data, stack me);
|
||||
/* Getting */
|
||||
int stack_top(void *data, stack me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int stack_clear(stack me);
|
||||
stack stack_destroy(stack me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "unordered_map.h"
|
||||
|
||||
@@ -51,8 +51,8 @@ struct node {
|
||||
* second hash to prevent hashing clusters if the user-defined hash is
|
||||
* sub-optimal.
|
||||
*/
|
||||
static inline unsigned long unordered_map_hash(unordered_map me,
|
||||
const void *const key)
|
||||
static unsigned long unordered_map_hash(unordered_map me,
|
||||
const void *const key)
|
||||
{
|
||||
unsigned long hash = me->hash(key);
|
||||
hash ^= (hash >> 20UL) ^ (hash >> 12UL);
|
||||
@@ -80,11 +80,11 @@ unordered_map unordered_map_init(const size_t key_size,
|
||||
int (*comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_unordered_map *init;
|
||||
if (key_size == 0 || value_size == 0 || !hash || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_unordered_map *const init =
|
||||
malloc(sizeof(struct internal_unordered_map));
|
||||
init = malloc(sizeof(struct internal_unordered_map));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -107,13 +107,14 @@ unordered_map unordered_map_init(const size_t key_size,
|
||||
*/
|
||||
static void unordered_map_add_item(unordered_map me, struct node *const add)
|
||||
{
|
||||
struct node *traverse;
|
||||
const int index = (int) (add->hash % me->capacity);
|
||||
add->next = NULL;
|
||||
if (!me->buckets[index]) {
|
||||
me->buckets[index] = add;
|
||||
return;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
while (traverse->next) {
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -131,13 +132,13 @@ static void unordered_map_add_item(unordered_map me, struct node *const add)
|
||||
*/
|
||||
int unordered_map_rehash(unordered_map me)
|
||||
{
|
||||
int i;
|
||||
struct node **old_buckets = me->buckets;
|
||||
me->buckets = calloc((size_t) me->capacity, sizeof(struct node *));
|
||||
if (!me->buckets) {
|
||||
me->buckets = old_buckets;
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -168,9 +169,9 @@ int unordered_map_size(unordered_map me)
|
||||
*
|
||||
* @param me the unordered map to check
|
||||
*
|
||||
* @return true if the unordered map is empty
|
||||
* @return 1 if the unordered map is empty, otherwise 0
|
||||
*/
|
||||
bool unordered_map_is_empty(unordered_map me)
|
||||
int unordered_map_is_empty(unordered_map me)
|
||||
{
|
||||
return unordered_map_size(me) == 0;
|
||||
}
|
||||
@@ -180,6 +181,7 @@ bool unordered_map_is_empty(unordered_map me)
|
||||
*/
|
||||
static int unordered_map_resize(unordered_map me)
|
||||
{
|
||||
int i;
|
||||
const int old_capacity = me->capacity;
|
||||
const int new_capacity = (int) (me->capacity * RESIZE_RATIO);
|
||||
struct node **old_buckets = me->buckets;
|
||||
@@ -189,7 +191,6 @@ static int unordered_map_resize(unordered_map me)
|
||||
return -ENOMEM;
|
||||
}
|
||||
me->capacity = new_capacity;
|
||||
int i;
|
||||
for (i = 0; i < old_capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -205,10 +206,10 @@ static int unordered_map_resize(unordered_map me)
|
||||
/*
|
||||
* Determines if an element is equal to the key.
|
||||
*/
|
||||
inline static bool unordered_map_is_equal(unordered_map me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
static int unordered_map_is_equal(unordered_map me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
{
|
||||
return item->hash == hash && me->comparator(item->key, key) == 0;
|
||||
}
|
||||
@@ -296,9 +297,9 @@ int unordered_map_put(unordered_map me, void *const key, void *const value)
|
||||
* @param me the unordered map to get from
|
||||
* @param key the key to search for
|
||||
*
|
||||
* @return true if the unordered map contained the key-value pair
|
||||
* @return 1 if the unordered map contained the key-value pair, otherwise 0
|
||||
*/
|
||||
bool unordered_map_get(void *const value, unordered_map me, void *const key)
|
||||
int unordered_map_get(void *const value, unordered_map me, void *const key)
|
||||
{
|
||||
const unsigned long hash = unordered_map_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
@@ -306,11 +307,11 @@ bool unordered_map_get(void *const value, unordered_map me, void *const key)
|
||||
while (traverse) {
|
||||
if (unordered_map_is_equal(me, traverse, hash, key)) {
|
||||
memcpy(value, traverse->value, me->value_size);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,20 +320,20 @@ bool unordered_map_get(void *const value, unordered_map me, void *const key)
|
||||
* @param me the unordered map to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the unordered map contained the key
|
||||
* @return 1 if the unordered map contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_map_contains(unordered_map me, void *const key)
|
||||
int unordered_map_contains(unordered_map me, void *const key)
|
||||
{
|
||||
const unsigned long hash = unordered_map_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
const struct node *traverse = me->buckets[index];
|
||||
while (traverse) {
|
||||
if (unordered_map_is_equal(me, traverse, hash, key)) {
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,23 +342,24 @@ bool unordered_map_contains(unordered_map me, void *const key)
|
||||
* @param me the unordered map to remove an key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the unordered map contained the key
|
||||
* @return 1 if the unordered map contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_map_remove(unordered_map me, void *const key)
|
||||
int unordered_map_remove(unordered_map me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
const unsigned long hash = unordered_map_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
if (!me->buckets[index]) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
if (unordered_map_is_equal(me, traverse, hash, key)) {
|
||||
me->buckets[index] = traverse->next;
|
||||
free(traverse->key);
|
||||
free(traverse->value);
|
||||
free(traverse);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
while (traverse->next) {
|
||||
if (unordered_map_is_equal(me, traverse->next, hash, key)) {
|
||||
@@ -367,11 +369,11 @@ bool unordered_map_remove(unordered_map me, void *const key)
|
||||
free(backup->value);
|
||||
free(backup);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,12 +386,12 @@ bool unordered_map_remove(unordered_map me, void *const key)
|
||||
*/
|
||||
int unordered_map_clear(unordered_map me)
|
||||
{
|
||||
int i;
|
||||
struct node **temp =
|
||||
calloc((size_t) STARTING_BUCKETS, sizeof(struct node *));
|
||||
if (!temp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = me->buckets[i];
|
||||
while (traverse) {
|
||||
|
||||
@@ -23,33 +23,31 @@
|
||||
#ifndef CONTAINERS_UNORDERED_MAP_H
|
||||
#define CONTAINERS_UNORDERED_MAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The unordered_map data structure, which is a collection of key-value pairs,
|
||||
* hashed by keys, keys are unique
|
||||
*/
|
||||
typedef struct internal_unordered_map *unordered_map;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
unordered_map unordered_map_init(size_t key_size,
|
||||
size_t value_size,
|
||||
unsigned long (*hash)(const void *const key),
|
||||
int (*comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int unordered_map_rehash(unordered_map me);
|
||||
int unordered_map_size(unordered_map me);
|
||||
bool unordered_map_is_empty(unordered_map me);
|
||||
int unordered_map_is_empty(unordered_map me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int unordered_map_put(unordered_map me, void *key, void *value);
|
||||
bool unordered_map_get(void *value, unordered_map me, void *key);
|
||||
bool unordered_map_contains(unordered_map me, void *key);
|
||||
bool unordered_map_remove(unordered_map me, void *key);
|
||||
int unordered_map_get(void *value, unordered_map me, void *key);
|
||||
int unordered_map_contains(unordered_map me, void *key);
|
||||
int unordered_map_remove(unordered_map me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int unordered_map_clear(unordered_map me);
|
||||
unordered_map unordered_map_destroy(unordered_map me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "unordered_multimap.h"
|
||||
|
||||
@@ -55,8 +55,8 @@ struct node {
|
||||
* second hash to prevent hashing clusters if the user-defined hash is
|
||||
* sub-optimal.
|
||||
*/
|
||||
static inline unsigned long unordered_multimap_hash(unordered_multimap me,
|
||||
const void *const key)
|
||||
static unsigned long unordered_multimap_hash(unordered_multimap me,
|
||||
const void *const key)
|
||||
{
|
||||
unsigned long hash = me->hash(key);
|
||||
hash ^= (hash >> 20UL) ^ (hash >> 12UL);
|
||||
@@ -89,12 +89,12 @@ unordered_multimap_init(const size_t key_size,
|
||||
int (*value_comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_unordered_multimap *init;
|
||||
if (key_size == 0 || value_size == 0
|
||||
|| !hash || !key_comparator || !value_comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_unordered_multimap *const init =
|
||||
malloc(sizeof(struct internal_unordered_multimap));
|
||||
init = malloc(sizeof(struct internal_unordered_multimap));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -127,13 +127,14 @@ unordered_multimap_init(const size_t key_size,
|
||||
static void unordered_multimap_add_item(unordered_multimap me,
|
||||
struct node *const add)
|
||||
{
|
||||
struct node *traverse;
|
||||
const int index = (int) (add->hash % me->capacity);
|
||||
add->next = NULL;
|
||||
if (!me->buckets[index]) {
|
||||
me->buckets[index] = add;
|
||||
return;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
while (traverse->next) {
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -151,13 +152,13 @@ static void unordered_multimap_add_item(unordered_multimap me,
|
||||
*/
|
||||
int unordered_multimap_rehash(unordered_multimap me)
|
||||
{
|
||||
int i;
|
||||
struct node **old_buckets = me->buckets;
|
||||
me->buckets = calloc((size_t) me->capacity, sizeof(struct node *));
|
||||
if (!me->buckets) {
|
||||
me->buckets = old_buckets;
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -188,9 +189,9 @@ int unordered_multimap_size(unordered_multimap me)
|
||||
*
|
||||
* @param me the unordered multi-map to check
|
||||
*
|
||||
* @return true if the unordered multi-map is empty
|
||||
* @return 1 if the unordered multi-map is empty, otherwise 0
|
||||
*/
|
||||
bool unordered_multimap_is_empty(unordered_multimap me)
|
||||
int unordered_multimap_is_empty(unordered_multimap me)
|
||||
{
|
||||
return unordered_multimap_size(me) == 0;
|
||||
}
|
||||
@@ -200,6 +201,7 @@ bool unordered_multimap_is_empty(unordered_multimap me)
|
||||
*/
|
||||
static int unordered_multimap_resize(unordered_multimap me)
|
||||
{
|
||||
int i;
|
||||
const int old_capacity = me->capacity;
|
||||
const int new_capacity = (int) (me->capacity * RESIZE_RATIO);
|
||||
struct node **old_buckets = me->buckets;
|
||||
@@ -209,7 +211,6 @@ static int unordered_multimap_resize(unordered_multimap me)
|
||||
return -ENOMEM;
|
||||
}
|
||||
me->capacity = new_capacity;
|
||||
int i;
|
||||
for (i = 0; i < old_capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -225,10 +226,10 @@ static int unordered_multimap_resize(unordered_multimap me)
|
||||
/*
|
||||
* Determines if an element is equal to the key.
|
||||
*/
|
||||
inline static bool unordered_multimap_is_equal(unordered_multimap me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
static int unordered_multimap_is_equal(unordered_multimap me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
{
|
||||
return item->hash == hash && me->key_comparator(item->key, key) == 0;
|
||||
}
|
||||
@@ -314,11 +315,13 @@ int unordered_multimap_put(unordered_multimap me,
|
||||
*/
|
||||
void unordered_multimap_get_start(unordered_multimap me, void *const key)
|
||||
{
|
||||
int index;
|
||||
struct node *traverse;
|
||||
me->iterate_hash = unordered_multimap_hash(me, key);
|
||||
memcpy(me->iterate_key, key, me->key_size);
|
||||
me->iterate_element = NULL;
|
||||
const int index = (int) (me->iterate_hash % me->capacity);
|
||||
struct node *traverse = me->buckets[index];
|
||||
index = (int) (me->iterate_hash % me->capacity);
|
||||
traverse = me->buckets[index];
|
||||
while (traverse) {
|
||||
if (unordered_multimap_is_equal(me, traverse, me->iterate_hash, key)) {
|
||||
me->iterate_element = traverse;
|
||||
@@ -336,28 +339,30 @@ void unordered_multimap_get_start(unordered_multimap me, void *const key)
|
||||
* @param value the value to be copied to from iteration
|
||||
* @param me the unordered multi-map to iterate over
|
||||
*
|
||||
* @return true if there exist no more values for the key which is being
|
||||
* iterated over
|
||||
* @return 1 if there exist no more values for the key which is being iterated
|
||||
* over, otherwise 0
|
||||
*/
|
||||
bool unordered_multimap_get_next(void *const value, unordered_multimap me)
|
||||
int unordered_multimap_get_next(void *const value, unordered_multimap me)
|
||||
{
|
||||
struct node *item;
|
||||
struct node *traverse;
|
||||
if (!me->iterate_element) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *const item = me->iterate_element;
|
||||
struct node *traverse = item->next;
|
||||
item = me->iterate_element;
|
||||
traverse = item->next;
|
||||
while (traverse) {
|
||||
if (unordered_multimap_is_equal(me, traverse, me->iterate_hash,
|
||||
me->iterate_key)) {
|
||||
me->iterate_element = traverse;
|
||||
memcpy(value, item->value, me->value_size);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
me->iterate_element = NULL;
|
||||
memcpy(value, item->value, me->value_size);
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,20 +394,20 @@ int unordered_multimap_count(unordered_multimap me, void *const key)
|
||||
* @param me the unordered multi-map to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the unordered multi-map contained the key
|
||||
* @return 1 if the unordered multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multimap_contains(unordered_multimap me, void *const key)
|
||||
int unordered_multimap_contains(unordered_multimap me, void *const key)
|
||||
{
|
||||
const unsigned long hash = unordered_multimap_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
const struct node *traverse = me->buckets[index];
|
||||
while (traverse) {
|
||||
if (unordered_multimap_is_equal(me, traverse, hash, key)) {
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,26 +417,28 @@ bool unordered_multimap_contains(unordered_multimap me, void *const key)
|
||||
* @param key the key to remove
|
||||
* @param value the value to remove
|
||||
*
|
||||
* @return true if the unordered multi-map contained the key
|
||||
* @return 1 if the unordered multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multimap_remove(unordered_multimap me,
|
||||
void *const key,
|
||||
void *const value)
|
||||
int unordered_multimap_remove(unordered_multimap me,
|
||||
void *const key,
|
||||
void *const value)
|
||||
{
|
||||
struct node *traverse;
|
||||
int is_key_equal;
|
||||
const unsigned long hash = unordered_multimap_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
if (!me->buckets[index]) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
bool is_key_equal = unordered_multimap_is_equal(me, traverse, hash, key);
|
||||
traverse = me->buckets[index];
|
||||
is_key_equal = unordered_multimap_is_equal(me, traverse, hash, key);
|
||||
if (is_key_equal && me->value_comparator(traverse->value, value) == 0) {
|
||||
me->buckets[index] = traverse->next;
|
||||
free(traverse->key);
|
||||
free(traverse->value);
|
||||
free(traverse);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
while (traverse->next) {
|
||||
is_key_equal =
|
||||
@@ -443,11 +450,11 @@ bool unordered_multimap_remove(unordered_multimap me,
|
||||
free(backup->value);
|
||||
free(backup);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -457,14 +464,14 @@ bool unordered_multimap_remove(unordered_multimap me,
|
||||
* @param me the unordered multi-map to remove a key-value pair from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the unordered multi-map contained the key
|
||||
* @return 1 if the unordered multi-map contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multimap_remove_all(unordered_multimap me, void *const key)
|
||||
int unordered_multimap_remove_all(unordered_multimap me, void *const key)
|
||||
{
|
||||
const unsigned long hash = unordered_multimap_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
bool was_modified = false;
|
||||
while (true) {
|
||||
int was_modified = 0;
|
||||
for (;;) {
|
||||
struct node *traverse = me->buckets[index];
|
||||
if (!traverse) {
|
||||
break;
|
||||
@@ -475,7 +482,7 @@ bool unordered_multimap_remove_all(unordered_multimap me, void *const key)
|
||||
free(traverse->value);
|
||||
free(traverse);
|
||||
me->size--;
|
||||
was_modified = true;
|
||||
was_modified = 1;
|
||||
continue;
|
||||
}
|
||||
while (traverse->next) {
|
||||
@@ -486,7 +493,7 @@ bool unordered_multimap_remove_all(unordered_multimap me, void *const key)
|
||||
free(backup->value);
|
||||
free(backup);
|
||||
me->size--;
|
||||
was_modified = true;
|
||||
was_modified = 1;
|
||||
continue;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
@@ -506,12 +513,12 @@ bool unordered_multimap_remove_all(unordered_multimap me, void *const key)
|
||||
*/
|
||||
int unordered_multimap_clear(unordered_multimap me)
|
||||
{
|
||||
int i;
|
||||
struct node **temp =
|
||||
calloc((size_t) STARTING_BUCKETS, sizeof(struct node *));
|
||||
if (!temp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = me->buckets[i];
|
||||
while (traverse) {
|
||||
|
||||
@@ -23,15 +23,13 @@
|
||||
#ifndef CONTAINERS_UNORDERED_MULTIMAP_H
|
||||
#define CONTAINERS_UNORDERED_MULTIMAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The unordered_multimap data structure, which is a collection of key-value
|
||||
* pairs, hashed by keys.
|
||||
*/
|
||||
typedef struct internal_unordered_multimap *unordered_multimap;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
unordered_multimap
|
||||
unordered_multimap_init(size_t key_size,
|
||||
size_t value_size,
|
||||
@@ -41,21 +39,21 @@ unordered_multimap_init(size_t key_size,
|
||||
int (*value_comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int unordered_multimap_rehash(unordered_multimap me);
|
||||
int unordered_multimap_size(unordered_multimap me);
|
||||
bool unordered_multimap_is_empty(unordered_multimap me);
|
||||
int unordered_multimap_is_empty(unordered_multimap me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int unordered_multimap_put(unordered_multimap me, void *key, void *value);
|
||||
void unordered_multimap_get_start(unordered_multimap me, void *key);
|
||||
bool unordered_multimap_get_next(void *value, unordered_multimap me);
|
||||
int unordered_multimap_get_next(void *value, unordered_multimap me);
|
||||
int unordered_multimap_count(unordered_multimap me, void *key);
|
||||
bool unordered_multimap_contains(unordered_multimap me, void *key);
|
||||
bool unordered_multimap_remove(unordered_multimap me, void *key, void *value);
|
||||
bool unordered_multimap_remove_all(unordered_multimap me, void *key);
|
||||
int unordered_multimap_contains(unordered_multimap me, void *key);
|
||||
int unordered_multimap_remove(unordered_multimap me, void *key, void *value);
|
||||
int unordered_multimap_remove_all(unordered_multimap me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int unordered_multimap_clear(unordered_multimap me);
|
||||
unordered_multimap unordered_multimap_destroy(unordered_multimap me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "unordered_multiset.h"
|
||||
|
||||
@@ -51,8 +51,8 @@ struct node {
|
||||
* second hash to prevent hashing clusters if the user-defined hash is
|
||||
* sub-optimal.
|
||||
*/
|
||||
static inline unsigned long unordered_multiset_hash(unordered_multiset me,
|
||||
const void *const key)
|
||||
static unsigned long unordered_multiset_hash(unordered_multiset me,
|
||||
const void *const key)
|
||||
{
|
||||
unsigned long hash = me->hash(key);
|
||||
hash ^= (hash >> 20UL) ^ (hash >> 12UL);
|
||||
@@ -77,11 +77,11 @@ unordered_multiset_init(const size_t key_size,
|
||||
unsigned long (*hash)(const void *const),
|
||||
int (*comparator)(const void *const, const void *const))
|
||||
{
|
||||
struct internal_unordered_multiset *init;
|
||||
if (key_size == 0 || !hash || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_unordered_multiset *const init =
|
||||
malloc(sizeof(struct internal_unordered_multiset));
|
||||
init = malloc(sizeof(struct internal_unordered_multiset));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -105,13 +105,14 @@ unordered_multiset_init(const size_t key_size,
|
||||
static void unordered_multiset_add_item(unordered_multiset me,
|
||||
struct node *const add)
|
||||
{
|
||||
struct node *traverse;
|
||||
const int index = (int) (add->hash % me->capacity);
|
||||
add->next = NULL;
|
||||
if (!me->buckets[index]) {
|
||||
me->buckets[index] = add;
|
||||
return;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
while (traverse->next) {
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -129,13 +130,13 @@ static void unordered_multiset_add_item(unordered_multiset me,
|
||||
*/
|
||||
int unordered_multiset_rehash(unordered_multiset me)
|
||||
{
|
||||
int i;
|
||||
struct node **old_buckets = me->buckets;
|
||||
me->buckets = calloc((size_t) me->capacity, sizeof(struct node *));
|
||||
if (!me->buckets) {
|
||||
me->buckets = old_buckets;
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -166,9 +167,9 @@ int unordered_multiset_size(unordered_multiset me)
|
||||
*
|
||||
* @param me the unordered multi-set to check
|
||||
*
|
||||
* @return true if the unordered multi-set is empty
|
||||
* @return 1 if the unordered multi-set is empty, otherwise 0
|
||||
*/
|
||||
bool unordered_multiset_is_empty(unordered_multiset me)
|
||||
int unordered_multiset_is_empty(unordered_multiset me)
|
||||
{
|
||||
return unordered_multiset_size(me) == 0;
|
||||
}
|
||||
@@ -178,6 +179,7 @@ bool unordered_multiset_is_empty(unordered_multiset me)
|
||||
*/
|
||||
static int unordered_multiset_resize(unordered_multiset me)
|
||||
{
|
||||
int i;
|
||||
const int old_capacity = me->capacity;
|
||||
const int new_capacity = (int) (me->capacity * RESIZE_RATIO);
|
||||
struct node **old_buckets = me->buckets;
|
||||
@@ -187,7 +189,6 @@ static int unordered_multiset_resize(unordered_multiset me)
|
||||
return -ENOMEM;
|
||||
}
|
||||
me->capacity = new_capacity;
|
||||
int i;
|
||||
for (i = 0; i < old_capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -203,10 +204,10 @@ static int unordered_multiset_resize(unordered_multiset me)
|
||||
/*
|
||||
* Determines if an element is equal to the key.
|
||||
*/
|
||||
inline static bool unordered_multiset_is_equal(unordered_multiset me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
static int unordered_multiset_is_equal(unordered_multiset me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
{
|
||||
return item->hash == hash && me->comparator(item->key, key) == 0;
|
||||
}
|
||||
@@ -310,9 +311,9 @@ int unordered_multiset_count(unordered_multiset me, void *const key)
|
||||
* @param me the unordered multi-set to check for the key
|
||||
* @param key the key to check
|
||||
*
|
||||
* @return true if the unordered multi-set contained the key
|
||||
* @return 1 if the unordered multi-set contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multiset_contains(unordered_multiset me, void *const key)
|
||||
int unordered_multiset_contains(unordered_multiset me, void *const key)
|
||||
{
|
||||
return unordered_multiset_count(me, key) > 0;
|
||||
}
|
||||
@@ -323,16 +324,17 @@ bool unordered_multiset_contains(unordered_multiset me, void *const key)
|
||||
* @param me the unordered multi-set to remove a key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the unordered multi-set contained the key
|
||||
* @return 1 if the unordered multi-set contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multiset_remove(unordered_multiset me, void *const key)
|
||||
int unordered_multiset_remove(unordered_multiset me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
const unsigned long hash = unordered_multiset_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
if (!me->buckets[index]) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
if (unordered_multiset_is_equal(me, traverse, hash, key)) {
|
||||
traverse->count--;
|
||||
if (traverse->count == 0) {
|
||||
@@ -342,7 +344,7 @@ bool unordered_multiset_remove(unordered_multiset me, void *const key)
|
||||
me->used--;
|
||||
}
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
while (traverse->next) {
|
||||
if (unordered_multiset_is_equal(me, traverse->next, hash, key)) {
|
||||
@@ -355,11 +357,11 @@ bool unordered_multiset_remove(unordered_multiset me, void *const key)
|
||||
me->used--;
|
||||
}
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,23 +371,24 @@ bool unordered_multiset_remove(unordered_multiset me, void *const key)
|
||||
* @param me the unordered multi-set to remove a key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the unordered multi-set contained the key
|
||||
* @return 1 if the unordered multi-set contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_multiset_remove_all(unordered_multiset me, void *const key)
|
||||
int unordered_multiset_remove_all(unordered_multiset me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
const unsigned long hash = unordered_multiset_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
if (!me->buckets[index]) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
if (unordered_multiset_is_equal(me, traverse, hash, key)) {
|
||||
me->buckets[index] = traverse->next;
|
||||
me->size -= traverse->count;
|
||||
free(traverse->key);
|
||||
free(traverse);
|
||||
me->used--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
while (traverse->next) {
|
||||
if (unordered_multiset_is_equal(me, traverse->next, hash, key)) {
|
||||
@@ -395,11 +398,11 @@ bool unordered_multiset_remove_all(unordered_multiset me, void *const key)
|
||||
free(backup->key);
|
||||
free(backup);
|
||||
me->used--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,12 +415,12 @@ bool unordered_multiset_remove_all(unordered_multiset me, void *const key)
|
||||
*/
|
||||
int unordered_multiset_clear(unordered_multiset me)
|
||||
{
|
||||
int i;
|
||||
struct node **temp =
|
||||
calloc((size_t) STARTING_BUCKETS, sizeof(struct node *));
|
||||
if (!temp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = me->buckets[i];
|
||||
while (traverse) {
|
||||
|
||||
@@ -23,34 +23,32 @@
|
||||
#ifndef CONTAINERS_UNORDERED_MULTISET_H
|
||||
#define CONTAINERS_UNORDERED_MULTISET_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The unordered_multiset data structure, which is a collection of keys, hashed
|
||||
* by keys.
|
||||
*/
|
||||
typedef struct internal_unordered_multiset *unordered_multiset;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
unordered_multiset
|
||||
unordered_multiset_init(size_t key_size,
|
||||
unsigned long (*hash)(const void *const key),
|
||||
int (*comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int unordered_multiset_rehash(unordered_multiset me);
|
||||
int unordered_multiset_size(unordered_multiset me);
|
||||
bool unordered_multiset_is_empty(unordered_multiset me);
|
||||
int unordered_multiset_is_empty(unordered_multiset me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int unordered_multiset_put(unordered_multiset me, void *key);
|
||||
int unordered_multiset_count(unordered_multiset me, void *key);
|
||||
bool unordered_multiset_contains(unordered_multiset me, void *key);
|
||||
bool unordered_multiset_remove(unordered_multiset me, void *key);
|
||||
bool unordered_multiset_remove_all(unordered_multiset me, void *key);
|
||||
int unordered_multiset_contains(unordered_multiset me, void *key);
|
||||
int unordered_multiset_remove(unordered_multiset me, void *key);
|
||||
int unordered_multiset_remove_all(unordered_multiset me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int unordered_multiset_clear(unordered_multiset me);
|
||||
unordered_multiset unordered_multiset_destroy(unordered_multiset me);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "unordered_set.h"
|
||||
|
||||
@@ -49,8 +49,7 @@ struct node {
|
||||
* second hash to prevent hashing clusters if the user-defined hash is
|
||||
* sub-optimal.
|
||||
*/
|
||||
static inline unsigned long unordered_set_hash(unordered_set me,
|
||||
const void *const key)
|
||||
static unsigned long unordered_set_hash(unordered_set me, const void *const key)
|
||||
{
|
||||
unsigned long hash = me->hash(key);
|
||||
hash ^= (hash >> 20UL) ^ (hash >> 12UL);
|
||||
@@ -75,11 +74,11 @@ unordered_set unordered_set_init(const size_t key_size,
|
||||
int (*comparator)(const void *const,
|
||||
const void *const))
|
||||
{
|
||||
struct internal_unordered_set *init;
|
||||
if (key_size == 0 || !hash || !comparator) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_unordered_set *const init =
|
||||
malloc(sizeof(struct internal_unordered_set));
|
||||
init = malloc(sizeof(struct internal_unordered_set));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -101,13 +100,14 @@ unordered_set unordered_set_init(const size_t key_size,
|
||||
*/
|
||||
static void unordered_set_add_item(unordered_set me, struct node *const add)
|
||||
{
|
||||
struct node *traverse;
|
||||
const int index = (int) (add->hash % me->capacity);
|
||||
add->next = NULL;
|
||||
if (!me->buckets[index]) {
|
||||
me->buckets[index] = add;
|
||||
return;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
while (traverse->next) {
|
||||
traverse = traverse->next;
|
||||
}
|
||||
@@ -125,13 +125,13 @@ static void unordered_set_add_item(unordered_set me, struct node *const add)
|
||||
*/
|
||||
int unordered_set_rehash(unordered_set me)
|
||||
{
|
||||
int i;
|
||||
struct node **old_buckets = me->buckets;
|
||||
me->buckets = calloc((size_t) me->capacity, sizeof(struct node *));
|
||||
if (!me->buckets) {
|
||||
me->buckets = old_buckets;
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -162,9 +162,9 @@ int unordered_set_size(unordered_set me)
|
||||
*
|
||||
* @param me the unordered set to check
|
||||
*
|
||||
* @return true if the unordered set is empty
|
||||
* @return 1 if the unordered set is empty, otherwise 0
|
||||
*/
|
||||
bool unordered_set_is_empty(unordered_set me)
|
||||
int unordered_set_is_empty(unordered_set me)
|
||||
{
|
||||
return unordered_set_size(me) == 0;
|
||||
}
|
||||
@@ -174,6 +174,7 @@ bool unordered_set_is_empty(unordered_set me)
|
||||
*/
|
||||
static int unordered_set_resize(unordered_set me)
|
||||
{
|
||||
int i;
|
||||
const int old_capacity = me->capacity;
|
||||
const int new_capacity = (int) (me->capacity * RESIZE_RATIO);
|
||||
struct node **old_buckets = me->buckets;
|
||||
@@ -183,7 +184,6 @@ static int unordered_set_resize(unordered_set me)
|
||||
return -ENOMEM;
|
||||
}
|
||||
me->capacity = new_capacity;
|
||||
int i;
|
||||
for (i = 0; i < old_capacity; i++) {
|
||||
struct node *traverse = old_buckets[i];
|
||||
while (traverse) {
|
||||
@@ -199,10 +199,10 @@ static int unordered_set_resize(unordered_set me)
|
||||
/*
|
||||
* Determines if an element is equal to the key.
|
||||
*/
|
||||
inline static bool unordered_set_is_equal(unordered_set me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
static int unordered_set_is_equal(unordered_set me,
|
||||
const struct node *const item,
|
||||
const unsigned long hash,
|
||||
const void *const key)
|
||||
{
|
||||
return item->hash == hash && me->comparator(item->key, key) == 0;
|
||||
}
|
||||
@@ -278,20 +278,20 @@ int unordered_set_put(unordered_set me, void *const key)
|
||||
* @param me the unordered set to check for the element
|
||||
* @param key the element to check
|
||||
*
|
||||
* @return true if the unordered set contained the element
|
||||
* @return 1 if the unordered set contained the element, otherwise 0
|
||||
*/
|
||||
bool unordered_set_contains(unordered_set me, void *const key)
|
||||
int unordered_set_contains(unordered_set me, void *const key)
|
||||
{
|
||||
const unsigned long hash = unordered_set_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
const struct node *traverse = me->buckets[index];
|
||||
while (traverse) {
|
||||
if (unordered_set_is_equal(me, traverse, hash, key)) {
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,22 +300,23 @@ bool unordered_set_contains(unordered_set me, void *const key)
|
||||
* @param me the unordered set to remove an key from
|
||||
* @param key the key to remove
|
||||
*
|
||||
* @return true if the unordered set contained the key
|
||||
* @return 1 if the unordered set contained the key, otherwise 0
|
||||
*/
|
||||
bool unordered_set_remove(unordered_set me, void *const key)
|
||||
int unordered_set_remove(unordered_set me, void *const key)
|
||||
{
|
||||
struct node *traverse;
|
||||
const unsigned long hash = unordered_set_hash(me, key);
|
||||
const int index = (int) (hash % me->capacity);
|
||||
if (!me->buckets[index]) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
struct node *traverse = me->buckets[index];
|
||||
traverse = me->buckets[index];
|
||||
if (unordered_set_is_equal(me, traverse, hash, key)) {
|
||||
me->buckets[index] = traverse->next;
|
||||
free(traverse->key);
|
||||
free(traverse);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
while (traverse->next) {
|
||||
if (unordered_set_is_equal(me, traverse->next, hash, key)) {
|
||||
@@ -324,11 +325,11 @@ bool unordered_set_remove(unordered_set me, void *const key)
|
||||
free(backup->key);
|
||||
free(backup);
|
||||
me->size--;
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
traverse = traverse->next;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,12 +342,12 @@ bool unordered_set_remove(unordered_set me, void *const key)
|
||||
*/
|
||||
int unordered_set_clear(unordered_set me)
|
||||
{
|
||||
int i;
|
||||
struct node **temp =
|
||||
calloc((size_t) STARTING_BUCKETS, sizeof(struct node *));
|
||||
if (!temp) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < me->capacity; i++) {
|
||||
struct node *traverse = me->buckets[i];
|
||||
while (traverse) {
|
||||
|
||||
@@ -23,31 +23,29 @@
|
||||
#ifndef CONTAINERS_UNORDERED_SET_H
|
||||
#define CONTAINERS_UNORDERED_SET_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The unordered_set data structure, which is a collection of unique keys,
|
||||
* hashed by keys.
|
||||
*/
|
||||
typedef struct internal_unordered_set *unordered_set;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
unordered_set unordered_set_init(size_t key_size,
|
||||
unsigned long (*hash)(const void *const key),
|
||||
int (*comparator)(const void *const one,
|
||||
const void *const two));
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int unordered_set_rehash(unordered_set me);
|
||||
int unordered_set_size(unordered_set me);
|
||||
bool unordered_set_is_empty(unordered_set me);
|
||||
int unordered_set_is_empty(unordered_set me);
|
||||
|
||||
// Accessing
|
||||
/* Accessing */
|
||||
int unordered_set_put(unordered_set me, void *key);
|
||||
bool unordered_set_contains(unordered_set me, void *key);
|
||||
bool unordered_set_remove(unordered_set me, void *key);
|
||||
int unordered_set_contains(unordered_set me, void *key);
|
||||
int unordered_set_remove(unordered_set me, void *key);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int unordered_set_clear(unordered_set me);
|
||||
unordered_set unordered_set_destroy(unordered_set me);
|
||||
|
||||
|
||||
28
src/vector.c
28
src/vector.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "vector.h"
|
||||
|
||||
@@ -44,10 +44,11 @@ struct internal_vector {
|
||||
*/
|
||||
vector vector_init(const size_t data_size)
|
||||
{
|
||||
struct internal_vector *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
struct internal_vector *const init = malloc(sizeof(struct internal_vector));
|
||||
init = malloc(sizeof(struct internal_vector));
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -91,9 +92,9 @@ int vector_capacity(vector me)
|
||||
*
|
||||
* @param me the vector to check
|
||||
*
|
||||
* @return true if the vector is empty
|
||||
* @return 1 if the vector is empty, otherwise 0
|
||||
*/
|
||||
bool vector_is_empty(vector me)
|
||||
int vector_is_empty(vector me)
|
||||
{
|
||||
return vector_size(me) == 0;
|
||||
}
|
||||
@@ -210,11 +211,12 @@ int vector_add_at(vector me, const int index, void *const data)
|
||||
me->item_capacity = new_space;
|
||||
}
|
||||
if (index != me->item_count) {
|
||||
memmove(me->data + (index + 1) * me->bytes_per_item,
|
||||
me->data + index * me->bytes_per_item,
|
||||
memmove((char *) me->data + (index + 1) * me->bytes_per_item,
|
||||
(char *) me->data + index * me->bytes_per_item,
|
||||
(me->item_count - index) * me->bytes_per_item);
|
||||
}
|
||||
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
|
||||
memcpy((char *) me->data + index * me->bytes_per_item, data,
|
||||
me->bytes_per_item);
|
||||
me->item_count++;
|
||||
return 0;
|
||||
}
|
||||
@@ -236,7 +238,7 @@ int vector_add_last(vector me, void *const data)
|
||||
/*
|
||||
* Determines if the input is illegal.
|
||||
*/
|
||||
static bool vector_is_illegal_input(vector me, const int index)
|
||||
static int vector_is_illegal_input(vector me, const int index)
|
||||
{
|
||||
return index < 0 || index >= me->item_count;
|
||||
}
|
||||
@@ -269,8 +271,8 @@ int vector_remove_at(vector me, const int index)
|
||||
return -EINVAL;
|
||||
}
|
||||
me->item_count--;
|
||||
memmove(me->data + index * me->bytes_per_item,
|
||||
me->data + (index + 1) * me->bytes_per_item,
|
||||
memmove((char *) me->data + index * me->bytes_per_item,
|
||||
(char *) me->data + (index + 1) * me->bytes_per_item,
|
||||
(me->item_count - index) * me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
@@ -321,7 +323,8 @@ int vector_set_at(vector me, const int index, void *const data)
|
||||
if (vector_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
|
||||
memcpy((char *) me->data + index * me->bytes_per_item, data,
|
||||
me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -368,7 +371,8 @@ int vector_get_at(void *const data, vector me, const int index)
|
||||
if (vector_is_illegal_input(me, index)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(data, me->data + index * me->bytes_per_item, me->bytes_per_item);
|
||||
memcpy(data, (char *) me->data + index * me->bytes_per_item,
|
||||
me->bytes_per_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
18
src/vector.h
18
src/vector.h
@@ -23,46 +23,44 @@
|
||||
#ifndef CONTAINERS_VECTOR_H
|
||||
#define CONTAINERS_VECTOR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* The vector data structure, which is a dynamic contiguous array.
|
||||
*/
|
||||
typedef struct internal_vector *vector;
|
||||
|
||||
// Starting
|
||||
/* Starting */
|
||||
vector vector_init(size_t data_size);
|
||||
|
||||
// Utility
|
||||
/* Utility */
|
||||
int vector_size(vector me);
|
||||
int vector_capacity(vector me);
|
||||
bool vector_is_empty(vector me);
|
||||
int vector_is_empty(vector me);
|
||||
int vector_reserve(vector me, int size);
|
||||
int vector_trim(vector me);
|
||||
void vector_copy_to_array(void *arr, vector me);
|
||||
void *vector_get_data(vector me);
|
||||
|
||||
// Adding
|
||||
/* Adding */
|
||||
int vector_add_first(vector me, void *data);
|
||||
int vector_add_at(vector me, int index, void *data);
|
||||
int vector_add_last(vector me, void *data);
|
||||
|
||||
// Removing
|
||||
/* Removing */
|
||||
int vector_remove_first(vector me);
|
||||
int vector_remove_at(vector me, int index);
|
||||
int vector_remove_last(vector me);
|
||||
|
||||
// Setting
|
||||
/* Setting */
|
||||
int vector_set_first(vector me, void *data);
|
||||
int vector_set_at(vector me, int index, void *data);
|
||||
int vector_set_last(vector me, void *data);
|
||||
|
||||
// Getting
|
||||
/* Getting */
|
||||
int vector_get_first(void *data, vector me);
|
||||
int vector_get_at(void *data, vector me, int index);
|
||||
int vector_get_last(void *data, vector me);
|
||||
|
||||
// Ending
|
||||
/* Ending */
|
||||
int vector_clear(vector me);
|
||||
vector vector_destroy(vector me);
|
||||
|
||||
|
||||
19
tst/array.c
19
tst/array.c
@@ -3,38 +3,41 @@
|
||||
|
||||
void test_array(void)
|
||||
{
|
||||
array me;
|
||||
int i;
|
||||
int *data;
|
||||
int arr[10] = {0};
|
||||
int get;
|
||||
assert(!array_init(-1, sizeof(int)));
|
||||
assert(!array_init(1, 0));
|
||||
array me = array_init(10, sizeof(int));
|
||||
me = array_init(10, sizeof(int));
|
||||
assert(me);
|
||||
assert(array_size(me) == 10);
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
array_get(&get, me, i);
|
||||
assert(get == 0);
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
array_set(me, i, &i);
|
||||
array_get(&get, me, i);
|
||||
assert(get == i);
|
||||
}
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
array_get(&get, me, i);
|
||||
assert(get == i);
|
||||
}
|
||||
int arr[10] = {0};
|
||||
array_copy_to_array(arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(arr[i] == i);
|
||||
}
|
||||
int *const data = array_get_data(me);
|
||||
data = array_get_data(me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(data[i] == i);
|
||||
}
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
assert(array_set(me, -1, &get) == -EINVAL);
|
||||
assert(array_get(&get, me, -1) == -EINVAL);
|
||||
me = array_destroy(me);
|
||||
|
||||
28
tst/deque.c
28
tst/deque.c
@@ -3,31 +3,36 @@
|
||||
|
||||
void test_deque(void)
|
||||
{
|
||||
assert(!deque_init(0));
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
deque me = deque_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
int trimmed[5] = {0};
|
||||
int arr[3] = {0};
|
||||
deque me;
|
||||
int get;
|
||||
int add;
|
||||
int set;
|
||||
int i;
|
||||
assert(!deque_init(0));
|
||||
me = deque_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(deque_size(me) == 0);
|
||||
assert(deque_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
deque_push_front(me, &val[i]);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
deque_get_first(&get, me);
|
||||
assert(get == val[i]);
|
||||
}
|
||||
assert(deque_size(me) == 10);
|
||||
assert(!deque_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
deque_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
deque_get_at(&get, me, i);
|
||||
assert(get == val[9 - i]);
|
||||
assert(get_arr[i] == val[9 - i]);
|
||||
}
|
||||
int trimmed[5] = {0};
|
||||
int get = 5;
|
||||
get = 5;
|
||||
deque_trim(me);
|
||||
for (i = 0; i < 7; i++) {
|
||||
deque_pop_back(&get, me);
|
||||
@@ -38,7 +43,7 @@ void test_deque(void)
|
||||
for (i = 0; i < 3; i++) {
|
||||
assert(10 - i == trimmed[i]);
|
||||
}
|
||||
int add = 3;
|
||||
add = 3;
|
||||
deque_push_back(me, &add);
|
||||
add = -2;
|
||||
deque_push_back(me, &add);
|
||||
@@ -78,13 +83,12 @@ void test_deque(void)
|
||||
assert(get == 8);
|
||||
deque_get_last(&get, me);
|
||||
assert(get == 3);
|
||||
int set = 12;
|
||||
set = 12;
|
||||
deque_set_first(me, &set);
|
||||
set = 13;
|
||||
deque_set_at(me, 1, &set);
|
||||
set = 14;
|
||||
deque_set_last(me, &set);
|
||||
int arr[3] = {0};
|
||||
deque_copy_to_array(arr, me);
|
||||
assert(arr[0] == 12);
|
||||
assert(arr[1] == 13);
|
||||
@@ -108,7 +112,7 @@ void test_deque(void)
|
||||
assert(deque_is_empty(me));
|
||||
me = deque_destroy(me);
|
||||
assert(!me);
|
||||
// Testing automatic trim
|
||||
/* Testing automatic trim */
|
||||
me = deque_init(sizeof(int));
|
||||
for (i = 0; i < 100; i++) {
|
||||
deque_push_back(me, &i);
|
||||
|
||||
@@ -3,26 +3,32 @@
|
||||
|
||||
void test_forward_list(void)
|
||||
{
|
||||
assert(!forward_list_init(0));
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
forward_list me = forward_list_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
int trimmed[5] = {0};
|
||||
int arr[3] = {0};
|
||||
int add;
|
||||
forward_list me;
|
||||
int get;
|
||||
int set;
|
||||
int i;
|
||||
assert(!forward_list_init(0));
|
||||
me = forward_list_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(forward_list_size(me) == 0);
|
||||
assert(forward_list_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
forward_list_add_first(me, &val[i]);
|
||||
assert(forward_list_size(me) == i + 1);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
forward_list_get_first(&get, me);
|
||||
assert(get == val[i]);
|
||||
}
|
||||
assert(forward_list_size(me) == 10);
|
||||
assert(!forward_list_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
forward_list_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
forward_list_get_at(&get, me, i);
|
||||
assert(get == val[9 - i]);
|
||||
assert(get_arr[i] == val[9 - i]);
|
||||
@@ -30,20 +36,19 @@ void test_forward_list(void)
|
||||
for (i = 0; i < 7; i++) {
|
||||
forward_list_remove_last(me);
|
||||
}
|
||||
int trimmed[5] = {0};
|
||||
forward_list_copy_to_array(trimmed, me);
|
||||
assert(forward_list_size(me) == 3);
|
||||
for (i = 0; i < 3; i++) {
|
||||
assert(10 - i == trimmed[i]);
|
||||
}
|
||||
int add = 3;
|
||||
add = 3;
|
||||
forward_list_add_last(me, &add);
|
||||
add = -1;
|
||||
forward_list_add_at(me, 1, &add);
|
||||
add = -2;
|
||||
forward_list_add_last(me, &add);
|
||||
assert(forward_list_size(me) == 6);
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
forward_list_get_first(&get, me);
|
||||
assert(get == 10);
|
||||
get = 0xdeadbeef;
|
||||
@@ -73,13 +78,12 @@ void test_forward_list(void)
|
||||
assert(get == 9);
|
||||
forward_list_get_last(&get, me);
|
||||
assert(get == 3);
|
||||
int set = 12;
|
||||
set = 12;
|
||||
forward_list_set_first(me, &set);
|
||||
set = 13;
|
||||
forward_list_set_at(me, 1, &set);
|
||||
set = 14;
|
||||
forward_list_set_last(me, &set);
|
||||
int arr[3] = {0};
|
||||
forward_list_copy_to_array(arr, me);
|
||||
assert(arr[0] == 12);
|
||||
assert(arr[1] == 13);
|
||||
|
||||
32
tst/list.c
32
tst/list.c
@@ -3,26 +3,34 @@
|
||||
|
||||
void test_list(void)
|
||||
{
|
||||
assert(!list_init(0));
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
list me = list_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
int trimmed[5] = {0};
|
||||
int arr[3] = {0};
|
||||
list me;
|
||||
int first;
|
||||
int index;
|
||||
int add;
|
||||
int get;
|
||||
int set;
|
||||
int i;
|
||||
assert(!list_init(0));
|
||||
me = list_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(list_size(me) == 0);
|
||||
assert(list_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
list_add_first(me, &val[i]);
|
||||
assert(list_size(me) == i + 1);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
list_get_first(&get, me);
|
||||
assert(get == val[i]);
|
||||
}
|
||||
assert(list_size(me) == 10);
|
||||
assert(!list_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
list_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
list_get_at(&get, me, i);
|
||||
assert(get == val[9 - i]);
|
||||
assert(get_arr[i] == val[9 - i]);
|
||||
@@ -30,21 +38,20 @@ void test_list(void)
|
||||
for (i = 0; i < 7; i++) {
|
||||
list_remove_last(me);
|
||||
}
|
||||
int trimmed[5] = {0};
|
||||
list_copy_to_array(trimmed, me);
|
||||
assert(list_size(me) == 3);
|
||||
for (i = 0; i < 3; i++) {
|
||||
assert(10 - i == trimmed[i]);
|
||||
}
|
||||
int index = list_size(me);
|
||||
int add = 3;
|
||||
index = list_size(me);
|
||||
add = 3;
|
||||
list_add_at(me, index, &add);
|
||||
add = -1;
|
||||
list_add_at(me, 1, &add);
|
||||
add = -2;
|
||||
list_add_last(me, &add);
|
||||
assert(list_size(me) == 6);
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
list_get_first(&get, me);
|
||||
assert(get == 10);
|
||||
get = 0xdeadbeef;
|
||||
@@ -68,7 +75,7 @@ void test_list(void)
|
||||
list_remove_last(me);
|
||||
get = 34;
|
||||
list_add_at(me, 0, &get);
|
||||
int first = 0xdeadbeef;
|
||||
first = 0xdeadbeef;
|
||||
list_get_first(&first, me);
|
||||
assert(first == get);
|
||||
list_remove_first(me);
|
||||
@@ -80,13 +87,12 @@ void test_list(void)
|
||||
assert(get == 9);
|
||||
list_get_last(&get, me);
|
||||
assert(get == 3);
|
||||
int set = 12;
|
||||
set = 12;
|
||||
list_set_first(me, &set);
|
||||
set = 13;
|
||||
list_set_at(me, 1, &set);
|
||||
set = 14;
|
||||
list_set_last(me, &set);
|
||||
int arr[3] = {0};
|
||||
list_copy_to_array(arr, me);
|
||||
assert(arr[0] == 12);
|
||||
assert(arr[1] == 13);
|
||||
|
||||
505
tst/map.c
505
tst/map.c
@@ -10,15 +10,26 @@ static int compare_int(const void *const one, const void *const two)
|
||||
|
||||
void test_map(void)
|
||||
{
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
map me;
|
||||
int key;
|
||||
int value;
|
||||
int num;
|
||||
int count;
|
||||
int flip;
|
||||
int p;
|
||||
int i;
|
||||
int j;
|
||||
assert(!map_init(0, sizeof(int), compare_int));
|
||||
assert(!map_init(sizeof(int), 0, compare_int));
|
||||
assert(!map_init(sizeof(int), sizeof(int), NULL));
|
||||
map me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
assert(me);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
int key = 4;
|
||||
int value = 9;
|
||||
key = 4;
|
||||
value = 9;
|
||||
map_put(me, &key, &value);
|
||||
assert(map_size(me) == 1);
|
||||
value = 5;
|
||||
@@ -34,8 +45,6 @@ void test_map(void)
|
||||
map_put(me, &key, &value);
|
||||
assert(map_size(me) == 2);
|
||||
assert(map_contains(me, &key));
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
map_put(me, &val_arr[i], &value);
|
||||
assert(map_contains(me, &val_arr[i]));
|
||||
@@ -44,243 +53,11 @@ void test_map(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(map_contains(me, &val_arr[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (val_arr[j] == i) {
|
||||
contains = true;
|
||||
}
|
||||
}
|
||||
assert(map_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
assert(!map_remove(me, &num));
|
||||
assert(map_size(me) == 9);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 6;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 8);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 4;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 7);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 7;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 6);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 9;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 5);
|
||||
assert(!map_contains(me, &num));
|
||||
num = -5;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 4);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 0;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 3);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 1;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 2);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 5;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 1);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 2;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 0);
|
||||
assert(!map_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &value);
|
||||
assert(map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 1000);
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_remove(me, &i);
|
||||
assert(!map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
map_clear(me);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &value);
|
||||
assert(map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 1000);
|
||||
map_clear(me);
|
||||
key = 0xdeadbeef;
|
||||
assert(!map_remove(me, &key));
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
me = map_destroy(me);
|
||||
assert(!me);
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
assert(me);
|
||||
// left-left
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
// right-right
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
// left-right
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
// right-left
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
// Two children edge case.
|
||||
key = 8;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 11;
|
||||
map_put(me, &key, &num);
|
||||
key = 2;
|
||||
map_put(me, &key, &num);
|
||||
key = 6;
|
||||
map_put(me, &key, &num);
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
key = 15;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
key = 7;
|
||||
map_put(me, &key, &num);
|
||||
key = 9;
|
||||
map_put(me, &key, &num);
|
||||
key = 12;
|
||||
map_put(me, &key, &num);
|
||||
key = 13;
|
||||
map_put(me, &key, &num);
|
||||
key = 16;
|
||||
map_put(me, &key, &num);
|
||||
key = 14;
|
||||
map_put(me, &key, &num);
|
||||
map_clear(me);
|
||||
// Two children edge case.
|
||||
key = 8;
|
||||
map_put(me, &key, &num);
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
key = 12;
|
||||
map_put(me, &key, &num);
|
||||
key = 2;
|
||||
map_put(me, &key, &num);
|
||||
key = 6;
|
||||
map_put(me, &key, &num);
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
key = 15;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 7;
|
||||
map_put(me, &key, &num);
|
||||
key = 9;
|
||||
map_put(me, &key, &num);
|
||||
key = 11;
|
||||
map_put(me, &key, &num);
|
||||
key = 13;
|
||||
map_put(me, &key, &num);
|
||||
key = 16;
|
||||
map_put(me, &key, &num);
|
||||
key = 14;
|
||||
map_put(me, &key, &num);
|
||||
map_clear(me);
|
||||
// Add a lot of items.
|
||||
int count = 0;
|
||||
bool flip = false;
|
||||
for (i = 1234; i < 82400; i++) {
|
||||
key = i % 765;
|
||||
const bool is_already_present = map_contains(me, &key);
|
||||
map_put(me, &key, &num);
|
||||
const bool is_now_present = map_contains(me, &key);
|
||||
assert(is_now_present);
|
||||
if (!is_already_present && is_now_present) {
|
||||
count++;
|
||||
}
|
||||
if (i == 1857 && !flip) {
|
||||
i *= -1;
|
||||
flip = true;
|
||||
}
|
||||
}
|
||||
assert(count == map_size(me));
|
||||
map_put(me, &key, &num);
|
||||
map_destroy(me);
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 1);
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 1);
|
||||
assert(!map_is_empty(me));
|
||||
assert(map_contains(me, &key));
|
||||
key = 7;
|
||||
assert(!map_contains(me, &key));
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 2);
|
||||
assert(map_contains(me, &key));
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
for (i = 0; i < 10; i++) {
|
||||
map_put(me, &c[i], &num);
|
||||
assert(map_contains(me, &c[i]));
|
||||
}
|
||||
assert(map_size(me) == 9);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(map_contains(me, &c[i]));
|
||||
}
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(map_contains(me, &i) == contains);
|
||||
@@ -325,7 +102,239 @@ void test_map(void)
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 0);
|
||||
assert(!map_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &value);
|
||||
assert(map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 1000);
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_remove(me, &i);
|
||||
assert(!map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
map_clear(me);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &value);
|
||||
assert(map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 1000);
|
||||
map_clear(me);
|
||||
key = 0xdeadbeef;
|
||||
assert(!map_remove(me, &key));
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
me = map_destroy(me);
|
||||
assert(!me);
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
assert(me);
|
||||
/* left-left */
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
/* right-right */
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
/* left-right */
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
/* right-left */
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 0xdeadbeef;
|
||||
map_contains(me, &key);
|
||||
map_clear(me);
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 11;
|
||||
map_put(me, &key, &num);
|
||||
key = 2;
|
||||
map_put(me, &key, &num);
|
||||
key = 6;
|
||||
map_put(me, &key, &num);
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
key = 15;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
key = 7;
|
||||
map_put(me, &key, &num);
|
||||
key = 9;
|
||||
map_put(me, &key, &num);
|
||||
key = 12;
|
||||
map_put(me, &key, &num);
|
||||
key = 13;
|
||||
map_put(me, &key, &num);
|
||||
key = 16;
|
||||
map_put(me, &key, &num);
|
||||
key = 14;
|
||||
map_put(me, &key, &num);
|
||||
map_clear(me);
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
map_put(me, &key, &num);
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
key = 12;
|
||||
map_put(me, &key, &num);
|
||||
key = 2;
|
||||
map_put(me, &key, &num);
|
||||
key = 6;
|
||||
map_put(me, &key, &num);
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
key = 15;
|
||||
map_put(me, &key, &num);
|
||||
key = 1;
|
||||
map_put(me, &key, &num);
|
||||
key = 3;
|
||||
map_put(me, &key, &num);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
key = 7;
|
||||
map_put(me, &key, &num);
|
||||
key = 9;
|
||||
map_put(me, &key, &num);
|
||||
key = 11;
|
||||
map_put(me, &key, &num);
|
||||
key = 13;
|
||||
map_put(me, &key, &num);
|
||||
key = 16;
|
||||
map_put(me, &key, &num);
|
||||
key = 14;
|
||||
map_put(me, &key, &num);
|
||||
map_clear(me);
|
||||
/* Add a lot of items. */
|
||||
count = 0;
|
||||
flip = 0;
|
||||
for (i = 1234; i < 82400; i++) {
|
||||
int is_already_present;
|
||||
int is_now_present;
|
||||
key = i % 765;
|
||||
is_already_present = map_contains(me, &key);
|
||||
map_put(me, &key, &num);
|
||||
is_now_present = map_contains(me, &key);
|
||||
assert(is_now_present);
|
||||
if (!is_already_present && is_now_present) {
|
||||
count++;
|
||||
}
|
||||
if (i == 1857 && !flip) {
|
||||
i *= -1;
|
||||
flip = 1;
|
||||
}
|
||||
}
|
||||
assert(count == map_size(me));
|
||||
map_put(me, &key, &num);
|
||||
map_destroy(me);
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
key = 4;
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 1);
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 1);
|
||||
assert(!map_is_empty(me));
|
||||
assert(map_contains(me, &key));
|
||||
key = 7;
|
||||
assert(!map_contains(me, &key));
|
||||
map_put(me, &key, &num);
|
||||
assert(map_size(me) == 2);
|
||||
assert(map_contains(me, &key));
|
||||
for (i = 0; i < 10; i++) {
|
||||
map_put(me, &c[i], &num);
|
||||
assert(map_contains(me, &c[i]));
|
||||
}
|
||||
assert(map_size(me) == 9);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(map_contains(me, &c[i]));
|
||||
}
|
||||
for (i = -100; i < 100; i++) {
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(map_contains(me, &i) == contains);
|
||||
}
|
||||
num = -3;
|
||||
assert(!map_remove(me, &num));
|
||||
assert(map_size(me) == 9);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 6;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 8);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 4;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 7);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 7;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 6);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 9;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 5);
|
||||
assert(!map_contains(me, &num));
|
||||
num = -5;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 4);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 0;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 3);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 1;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 2);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 5;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 1);
|
||||
assert(!map_contains(me, &num));
|
||||
num = 2;
|
||||
assert(map_remove(me, &num));
|
||||
assert(map_size(me) == 0);
|
||||
assert(!map_contains(me, &num));
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &num);
|
||||
assert(map_contains(me, &i));
|
||||
@@ -340,20 +349,20 @@ void test_map(void)
|
||||
map_clear(me);
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
map_put(me, &i, &num);
|
||||
assert(map_contains(me, &i));
|
||||
}
|
||||
assert(map_size(me) == 1000);
|
||||
map_clear(me);
|
||||
int p = 0xdeadbeef;
|
||||
p = 0xdeadbeef;
|
||||
assert(!map_remove(me, &p));
|
||||
assert(map_size(me) == 0);
|
||||
assert(map_is_empty(me));
|
||||
me = map_destroy(me);
|
||||
assert(!me);
|
||||
// Create odd shape graph.
|
||||
/* Create odd shape graph. */
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
@@ -378,7 +387,7 @@ void test_map(void)
|
||||
key = 8;
|
||||
map_remove(me, &key);
|
||||
map_clear(me);
|
||||
// Allocate many nodes.
|
||||
/* Allocate many nodes. */
|
||||
for (i = 8123; i < 12314; i += 3) {
|
||||
map_put(me, &i, &num);
|
||||
assert(map_contains(me, &i));
|
||||
@@ -388,7 +397,7 @@ void test_map(void)
|
||||
assert(!map_contains(me, &i));
|
||||
}
|
||||
map_clear(me);
|
||||
// Create another odd shape graph.
|
||||
/* Create another odd shape graph. */
|
||||
key = 20;
|
||||
map_put(me, &key, &num);
|
||||
key = 10;
|
||||
@@ -420,7 +429,7 @@ void test_map(void)
|
||||
key = 32;
|
||||
assert(map_contains(me, &key));
|
||||
map_clear(me);
|
||||
// One sided tree.
|
||||
/* One sided tree. */
|
||||
key = 10;
|
||||
map_put(me, &key, &num);
|
||||
key = 9;
|
||||
@@ -434,7 +443,7 @@ void test_map(void)
|
||||
key = 7;
|
||||
assert(map_contains(me, &key));
|
||||
map_destroy(me);
|
||||
// Replace two sided two children.
|
||||
/* Replace two sided two children. */
|
||||
me = map_init(sizeof(int), sizeof(int), compare_int);
|
||||
key = 5;
|
||||
map_put(me, &key, &num);
|
||||
@@ -500,7 +509,7 @@ void test_map(void)
|
||||
key = 5;
|
||||
map_remove(me, &key);
|
||||
map_clear(me);
|
||||
// Two children edge case other side.
|
||||
/* Two children edge case other side. */
|
||||
key = 8;
|
||||
map_put(me, &key, &num);
|
||||
key = 4;
|
||||
|
||||
@@ -10,17 +10,28 @@ static int compare_int(const void *const one, const void *const two)
|
||||
|
||||
void test_multimap(void)
|
||||
{
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
multimap me;
|
||||
int key;
|
||||
int value;
|
||||
int num;
|
||||
int count;
|
||||
int val;
|
||||
int flip;
|
||||
int p;
|
||||
int i;
|
||||
int j;
|
||||
assert(!multimap_init(0, sizeof(int), compare_int, compare_int));
|
||||
assert(!multimap_init(sizeof(int), 0, compare_int, compare_int));
|
||||
assert(!multimap_init(sizeof(int), sizeof(int), NULL, compare_int));
|
||||
assert(!multimap_init(sizeof(int), sizeof(int), compare_int, NULL));
|
||||
multimap me = multimap_init(sizeof(int), sizeof(int),
|
||||
compare_int, compare_int);
|
||||
me = multimap_init(sizeof(int), sizeof(int), compare_int, compare_int);
|
||||
assert(me);
|
||||
assert(multimap_size(me) == 0);
|
||||
assert(multimap_is_empty(me));
|
||||
int key = 4;
|
||||
int value = 123;
|
||||
key = 4;
|
||||
value = 123;
|
||||
multimap_put(me, &key, &value);
|
||||
assert(multimap_size(me) == 1);
|
||||
multimap_put(me, &key, &value);
|
||||
@@ -40,8 +51,7 @@ void test_multimap(void)
|
||||
assert(multimap_size(me) == 1);
|
||||
multimap_remove(me, &key, &value);
|
||||
assert(multimap_size(me) == 0);
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
multimap_put(me, &val_arr[i], &value);
|
||||
assert(multimap_contains(me, &val_arr[i]));
|
||||
@@ -50,17 +60,16 @@ void test_multimap(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(multimap_contains(me, &val_arr[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (val_arr[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(multimap_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!multimap_remove(me, &num, &value));
|
||||
assert(multimap_size(me) == 10);
|
||||
assert(!multimap_contains(me, &num));
|
||||
@@ -95,8 +104,8 @@ void test_multimap(void)
|
||||
num = 5;
|
||||
assert(multimap_count(me, &num) == 2);
|
||||
multimap_get_start(me, &num);
|
||||
int count = 0;
|
||||
int val = 0xdeadbeef;
|
||||
count = 0;
|
||||
val = 0xdeadbeef;
|
||||
while (multimap_get_next(&val, me)) {
|
||||
count++;
|
||||
assert(val == 123);
|
||||
@@ -114,7 +123,7 @@ void test_multimap(void)
|
||||
assert(multimap_remove(me, &num, &value));
|
||||
assert(multimap_size(me) == 0);
|
||||
assert(!multimap_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multimap_put(me, &i, &value);
|
||||
assert(multimap_contains(me, &i));
|
||||
@@ -129,7 +138,7 @@ void test_multimap(void)
|
||||
multimap_clear(me);
|
||||
assert(multimap_size(me) == 0);
|
||||
assert(multimap_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multimap_put(me, &i, &value);
|
||||
assert(multimap_contains(me, &i));
|
||||
@@ -154,7 +163,7 @@ void test_multimap(void)
|
||||
assert(!me);
|
||||
me = multimap_init(sizeof(int), sizeof(int), compare_int, compare_int);
|
||||
assert(me);
|
||||
// left-left
|
||||
/* left-left */
|
||||
key = 5;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 3;
|
||||
@@ -164,7 +173,7 @@ void test_multimap(void)
|
||||
key = 0xdeadbeef;
|
||||
multimap_contains(me, &key);
|
||||
multimap_clear(me);
|
||||
// right-right
|
||||
/* right-right */
|
||||
key = 1;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 3;
|
||||
@@ -174,7 +183,7 @@ void test_multimap(void)
|
||||
key = 0xdeadbeef;
|
||||
multimap_contains(me, &key);
|
||||
multimap_clear(me);
|
||||
// left-right
|
||||
/* left-right */
|
||||
key = 5;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 1;
|
||||
@@ -184,7 +193,7 @@ void test_multimap(void)
|
||||
key = 0xdeadbeef;
|
||||
multimap_contains(me, &key);
|
||||
multimap_clear(me);
|
||||
// right-left
|
||||
/* right-left */
|
||||
key = 1;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 5;
|
||||
@@ -194,7 +203,7 @@ void test_multimap(void)
|
||||
key = 0xdeadbeef;
|
||||
multimap_contains(me, &key);
|
||||
multimap_clear(me);
|
||||
// Two children edge case.
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 5;
|
||||
@@ -228,7 +237,7 @@ void test_multimap(void)
|
||||
key = 14;
|
||||
multimap_put(me, &key, &num);
|
||||
multimap_clear(me);
|
||||
// Two children edge case.
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 4;
|
||||
@@ -262,9 +271,9 @@ void test_multimap(void)
|
||||
key = 14;
|
||||
multimap_put(me, &key, &num);
|
||||
multimap_clear(me);
|
||||
// Add a lot of items.
|
||||
/* Add a lot of items. */
|
||||
count = 0;
|
||||
bool flip = false;
|
||||
flip = 0;
|
||||
for (i = 1234; i < 82400; i++) {
|
||||
key = i % 765;
|
||||
multimap_put(me, &key, &num);
|
||||
@@ -272,7 +281,7 @@ void test_multimap(void)
|
||||
count++;
|
||||
if (i == 1857 && !flip) {
|
||||
i *= -1;
|
||||
flip = true;
|
||||
flip = 1;
|
||||
}
|
||||
}
|
||||
assert(count == multimap_size(me));
|
||||
@@ -293,7 +302,6 @@ void test_multimap(void)
|
||||
multimap_put(me, &key, &num);
|
||||
assert(multimap_size(me) == 3);
|
||||
assert(multimap_contains(me, &key));
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
for (i = 0; i < 10; i++) {
|
||||
multimap_put(me, &c[i], &value);
|
||||
assert(multimap_contains(me, &c[i]));
|
||||
@@ -303,10 +311,10 @@ void test_multimap(void)
|
||||
assert(multimap_contains(me, &c[i]));
|
||||
}
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(multimap_contains(me, &i) == contains);
|
||||
@@ -352,7 +360,7 @@ void test_multimap(void)
|
||||
assert(multimap_size(me) == 4);
|
||||
assert(!multimap_contains(me, &num));
|
||||
multimap_clear(me);
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
value = 37;
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multimap_put(me, &i, &value);
|
||||
@@ -368,20 +376,20 @@ void test_multimap(void)
|
||||
multimap_clear(me);
|
||||
assert(multimap_size(me) == 0);
|
||||
assert(multimap_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multimap_put(me, &i, &num);
|
||||
assert(multimap_contains(me, &i));
|
||||
}
|
||||
assert(multimap_size(me) == 1000);
|
||||
multimap_clear(me);
|
||||
int p = 0xdeadbeef;
|
||||
p = 0xdeadbeef;
|
||||
assert(!multimap_remove(me, &p, &value));
|
||||
assert(multimap_size(me) == 0);
|
||||
assert(multimap_is_empty(me));
|
||||
me = multimap_destroy(me);
|
||||
assert(!me);
|
||||
// Create odd shape graph.
|
||||
/* Create odd shape graph. */
|
||||
me = multimap_init(sizeof(int), sizeof(int), compare_int, compare_int);
|
||||
key = 10;
|
||||
multimap_put(me, &key, &num);
|
||||
@@ -406,7 +414,7 @@ void test_multimap(void)
|
||||
key = 8;
|
||||
multimap_remove(me, &key, &value);
|
||||
multimap_clear(me);
|
||||
// Allocate many nodes.
|
||||
/* Allocate many nodes. */
|
||||
value = 54;
|
||||
for (i = 8123; i < 12314; i += 3) {
|
||||
multimap_put(me, &i, &value);
|
||||
@@ -417,7 +425,7 @@ void test_multimap(void)
|
||||
assert(!multimap_contains(me, &i));
|
||||
}
|
||||
multimap_clear(me);
|
||||
// Create another odd shape graph.
|
||||
/* Create another odd shape graph. */
|
||||
key = 20;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 10;
|
||||
@@ -449,7 +457,7 @@ void test_multimap(void)
|
||||
key = 32;
|
||||
assert(multimap_contains(me, &key));
|
||||
multimap_clear(me);
|
||||
// One sided tree.
|
||||
/* One sided tree. */
|
||||
key = 10;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 9;
|
||||
@@ -463,7 +471,7 @@ void test_multimap(void)
|
||||
key = 7;
|
||||
assert(multimap_contains(me, &key));
|
||||
multimap_destroy(me);
|
||||
// Replace two sided two children.
|
||||
/* Replace two sided two children. */
|
||||
me = multimap_init(sizeof(int), sizeof(int), compare_int, compare_int);
|
||||
key = 5;
|
||||
multimap_put(me, &key, &num);
|
||||
@@ -530,7 +538,7 @@ void test_multimap(void)
|
||||
key = 5;
|
||||
multimap_remove(me, &key, &value);
|
||||
multimap_clear(me);
|
||||
// Two children edge case other side.
|
||||
/* Two children edge case other side. */
|
||||
key = 8;
|
||||
multimap_put(me, &key, &num);
|
||||
key = 4;
|
||||
@@ -566,7 +574,7 @@ void test_multimap(void)
|
||||
multimap_clear(me);
|
||||
assert(multimap_count(me, &key) == 0);
|
||||
assert(!multimap_remove_all(me, &key));
|
||||
// Edge case.
|
||||
/* Edge case. */
|
||||
me = multimap_init(sizeof(int), sizeof(int), compare_int, compare_int);
|
||||
value = 17;
|
||||
key = 5;
|
||||
|
||||
@@ -10,13 +10,23 @@ static int compare_int(const void *const one, const void *const two)
|
||||
|
||||
void test_multiset(void)
|
||||
{
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
multiset me;
|
||||
int key;
|
||||
int num;
|
||||
int count;
|
||||
int flip;
|
||||
int p;
|
||||
int i;
|
||||
int j;
|
||||
assert(!multiset_init(0, compare_int));
|
||||
assert(!multiset_init(sizeof(int), NULL));
|
||||
multiset me = multiset_init(sizeof(int), compare_int);
|
||||
me = multiset_init(sizeof(int), compare_int);
|
||||
assert(me);
|
||||
assert(multiset_size(me) == 0);
|
||||
assert(multiset_is_empty(me));
|
||||
int key = 4;
|
||||
key = 4;
|
||||
multiset_put(me, &key);
|
||||
assert(multiset_size(me) == 1);
|
||||
multiset_put(me, &key);
|
||||
@@ -37,8 +47,6 @@ void test_multiset(void)
|
||||
assert(multiset_size(me) == 1);
|
||||
multiset_remove(me, &key);
|
||||
assert(multiset_size(me) == 0);
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
multiset_put(me, &val_arr[i]);
|
||||
assert(multiset_contains(me, &val_arr[i]));
|
||||
@@ -47,17 +55,16 @@ void test_multiset(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(multiset_contains(me, &val_arr[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (val_arr[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(multiset_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!multiset_remove(me, &num));
|
||||
assert(multiset_size(me) == 10);
|
||||
assert(!multiset_contains(me, &num));
|
||||
@@ -101,7 +108,7 @@ void test_multiset(void)
|
||||
assert(multiset_remove(me, &num));
|
||||
assert(multiset_size(me) == 0);
|
||||
assert(!multiset_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multiset_put(me, &i);
|
||||
assert(multiset_contains(me, &i));
|
||||
@@ -116,7 +123,7 @@ void test_multiset(void)
|
||||
multiset_clear(me);
|
||||
assert(multiset_size(me) == 0);
|
||||
assert(multiset_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multiset_put(me, &i);
|
||||
assert(multiset_contains(me, &i));
|
||||
@@ -141,7 +148,7 @@ void test_multiset(void)
|
||||
assert(!me);
|
||||
me = multiset_init(sizeof(int), compare_int);
|
||||
assert(me);
|
||||
// left-left
|
||||
/* left-left */
|
||||
key = 5;
|
||||
multiset_put(me, &key);
|
||||
key = 3;
|
||||
@@ -151,7 +158,7 @@ void test_multiset(void)
|
||||
key = 0xdeadbeef;
|
||||
multiset_contains(me, &key);
|
||||
multiset_clear(me);
|
||||
// right-right
|
||||
/* right-right */
|
||||
key = 1;
|
||||
multiset_put(me, &key);
|
||||
key = 3;
|
||||
@@ -161,7 +168,7 @@ void test_multiset(void)
|
||||
key = 0xdeadbeef;
|
||||
multiset_contains(me, &key);
|
||||
multiset_clear(me);
|
||||
// left-right
|
||||
/* left-right */
|
||||
key = 5;
|
||||
multiset_put(me, &key);
|
||||
key = 1;
|
||||
@@ -171,7 +178,7 @@ void test_multiset(void)
|
||||
key = 0xdeadbeef;
|
||||
multiset_contains(me, &key);
|
||||
multiset_clear(me);
|
||||
// right-left
|
||||
/* right-left */
|
||||
key = 1;
|
||||
multiset_put(me, &key);
|
||||
key = 5;
|
||||
@@ -181,7 +188,7 @@ void test_multiset(void)
|
||||
key = 0xdeadbeef;
|
||||
multiset_contains(me, &key);
|
||||
multiset_clear(me);
|
||||
// Two children edge case.
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
multiset_put(me, &key);
|
||||
key = 5;
|
||||
@@ -215,7 +222,7 @@ void test_multiset(void)
|
||||
key = 14;
|
||||
multiset_put(me, &key);
|
||||
multiset_clear(me);
|
||||
// Two children edge case.
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
multiset_put(me, &key);
|
||||
key = 4;
|
||||
@@ -249,9 +256,9 @@ void test_multiset(void)
|
||||
key = 14;
|
||||
multiset_put(me, &key);
|
||||
multiset_clear(me);
|
||||
// Add a lot of items.
|
||||
int count = 0;
|
||||
bool flip = false;
|
||||
/* Add a lot of items. */
|
||||
count = 0;
|
||||
flip = 0;
|
||||
for (i = 1234; i < 82400; i++) {
|
||||
key = i % 765;
|
||||
multiset_put(me, &key);
|
||||
@@ -259,7 +266,7 @@ void test_multiset(void)
|
||||
count++;
|
||||
if (i == 1857 && !flip) {
|
||||
i *= -1;
|
||||
flip = true;
|
||||
flip = 1;
|
||||
}
|
||||
}
|
||||
assert(count == multiset_size(me));
|
||||
@@ -280,7 +287,6 @@ void test_multiset(void)
|
||||
multiset_put(me, &key);
|
||||
assert(multiset_size(me) == 3);
|
||||
assert(multiset_contains(me, &key));
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
for (i = 0; i < 10; i++) {
|
||||
multiset_put(me, &c[i]);
|
||||
assert(multiset_contains(me, &c[i]));
|
||||
@@ -290,10 +296,10 @@ void test_multiset(void)
|
||||
assert(multiset_contains(me, &c[i]));
|
||||
}
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(multiset_contains(me, &i) == contains);
|
||||
@@ -339,7 +345,7 @@ void test_multiset(void)
|
||||
assert(multiset_size(me) == 4);
|
||||
assert(!multiset_contains(me, &num));
|
||||
multiset_clear(me);
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multiset_put(me, &i);
|
||||
assert(multiset_contains(me, &i));
|
||||
@@ -354,20 +360,20 @@ void test_multiset(void)
|
||||
multiset_clear(me);
|
||||
assert(multiset_size(me) == 0);
|
||||
assert(multiset_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
multiset_put(me, &i);
|
||||
assert(multiset_contains(me, &i));
|
||||
}
|
||||
assert(multiset_size(me) == 1000);
|
||||
multiset_clear(me);
|
||||
int p = 0xdeadbeef;
|
||||
p = 0xdeadbeef;
|
||||
assert(!multiset_remove(me, &p));
|
||||
assert(multiset_size(me) == 0);
|
||||
assert(multiset_is_empty(me));
|
||||
me = multiset_destroy(me);
|
||||
assert(!me);
|
||||
// Create odd shape graph.
|
||||
/* Create odd shape graph. */
|
||||
me = multiset_init(sizeof(int), compare_int);
|
||||
key = 10;
|
||||
multiset_put(me, &key);
|
||||
@@ -392,7 +398,7 @@ void test_multiset(void)
|
||||
key = 8;
|
||||
multiset_remove(me, &key);
|
||||
multiset_clear(me);
|
||||
// Allocate many nodes.
|
||||
/* Allocate many nodes. */
|
||||
for (i = 8123; i < 12314; i += 3) {
|
||||
multiset_put(me, &i);
|
||||
assert(multiset_contains(me, &i));
|
||||
@@ -402,7 +408,7 @@ void test_multiset(void)
|
||||
assert(!multiset_contains(me, &i));
|
||||
}
|
||||
multiset_clear(me);
|
||||
// Create another odd shape graph.
|
||||
/* Create another odd shape graph. */
|
||||
key = 20;
|
||||
multiset_put(me, &key);
|
||||
key = 10;
|
||||
@@ -434,7 +440,7 @@ void test_multiset(void)
|
||||
key = 32;
|
||||
assert(multiset_contains(me, &key));
|
||||
multiset_clear(me);
|
||||
// One sided tree.
|
||||
/* One sided tree. */
|
||||
key = 10;
|
||||
multiset_put(me, &key);
|
||||
key = 9;
|
||||
@@ -448,7 +454,7 @@ void test_multiset(void)
|
||||
key = 7;
|
||||
assert(multiset_contains(me, &key));
|
||||
multiset_destroy(me);
|
||||
// Replace two sided two children.
|
||||
/* Replace two sided two children. */
|
||||
me = multiset_init(sizeof(int), compare_int);
|
||||
key = 5;
|
||||
multiset_put(me, &key);
|
||||
@@ -514,7 +520,7 @@ void test_multiset(void)
|
||||
key = 5;
|
||||
multiset_remove(me, &key);
|
||||
multiset_clear(me);
|
||||
// Two children edge case other side.
|
||||
/* Two children edge case other side. */
|
||||
key = 8;
|
||||
multiset_put(me, &key);
|
||||
key = 4;
|
||||
|
||||
@@ -13,20 +13,22 @@ struct internal_priority_queue {
|
||||
|
||||
static void priority_queue_verify(priority_queue me)
|
||||
{
|
||||
int i;
|
||||
void *const vector_storage = vector_get_data(me->data);
|
||||
const int size = vector_size(me->data);
|
||||
int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
const int val = *(int *) (vector_storage + i * me->data_size);
|
||||
const int val = *(int *) ((char *) vector_storage + i * me->data_size);
|
||||
const int left_child = 2 * i + 1;
|
||||
const int right_child = 2 * i + 2;
|
||||
if (left_child < size) {
|
||||
void *left_data = vector_storage + left_child * me->data_size;
|
||||
void *left_data =
|
||||
(char *) vector_storage + left_child * me->data_size;
|
||||
const int left_val = *(int *) left_data;
|
||||
assert(val >= left_val);
|
||||
}
|
||||
if (right_child < size) {
|
||||
void *right_data = vector_storage + right_child * me->data_size;
|
||||
void *right_data =
|
||||
(char *) vector_storage + right_child * me->data_size;
|
||||
const int right_val = *(int *) right_data;
|
||||
assert(val >= right_val);
|
||||
}
|
||||
@@ -47,22 +49,26 @@ int stub_priority_queue_push(priority_queue me, void *const data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool stub_priority_queue_pop(void *const data, priority_queue me)
|
||||
int stub_priority_queue_pop(void *const data, priority_queue me)
|
||||
{
|
||||
const bool ret = priority_queue_pop(data, me);
|
||||
const int ret = priority_queue_pop(data, me);
|
||||
priority_queue_verify(me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void test_priority_queue(void)
|
||||
{
|
||||
priority_queue me;
|
||||
int item;
|
||||
int latest;
|
||||
int i;
|
||||
assert(!priority_queue_init(0, compare_int));
|
||||
assert(!priority_queue_init(sizeof(int), NULL));
|
||||
priority_queue me = priority_queue_init(sizeof(int), compare_int);
|
||||
me = priority_queue_init(sizeof(int), compare_int);
|
||||
assert(me);
|
||||
assert(priority_queue_size(me) == 0);
|
||||
assert(priority_queue_is_empty(me));
|
||||
int item = 0xdeadbeef;
|
||||
item = 0xdeadbeef;
|
||||
assert(!priority_queue_pop(&item, me));
|
||||
assert(item == 0xdeadbeef);
|
||||
item = 5;
|
||||
@@ -109,8 +115,7 @@ void test_priority_queue(void)
|
||||
item = 0xdeadbeef;
|
||||
priority_queue_front(&item, me);
|
||||
assert(item == 9);
|
||||
int latest = item;
|
||||
int i;
|
||||
latest = item;
|
||||
for (i = 0; i < 15; i++) {
|
||||
stub_priority_queue_pop(&item, me);
|
||||
assert(item <= latest);
|
||||
|
||||
27
tst/queue.c
27
tst/queue.c
@@ -3,31 +3,36 @@
|
||||
|
||||
void test_queue(void)
|
||||
{
|
||||
assert(!queue_init(0));
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
queue me = queue_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
queue me;
|
||||
int get;
|
||||
int stuff;
|
||||
int old_size;
|
||||
int pop_count;
|
||||
int i;
|
||||
assert(!queue_init(0));
|
||||
me = queue_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(queue_size(me) == 0);
|
||||
assert(queue_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
queue_push(me, &val[i]);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(queue_back(&get, me));
|
||||
assert(get == val[i]);
|
||||
int stuff = 0;
|
||||
stuff = 0;
|
||||
assert(queue_front(&stuff, me));
|
||||
assert(stuff == 1);
|
||||
}
|
||||
assert(queue_size(me) == 10);
|
||||
assert(!queue_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
queue_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(get_arr[i] == i + 1);
|
||||
}
|
||||
for (i = 0; i < 9; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(queue_pop(&get, me));
|
||||
assert(get == i + 1);
|
||||
}
|
||||
@@ -35,7 +40,7 @@ void test_queue(void)
|
||||
assert(queue_size(me) == 1);
|
||||
queue_clear(me);
|
||||
assert(queue_size(me) == 0);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(!queue_pop(&get, me));
|
||||
assert(!queue_front(&get, me));
|
||||
assert(!queue_back(&get, me));
|
||||
@@ -46,15 +51,15 @@ void test_queue(void)
|
||||
for (i = 123; i < 123456; i++) {
|
||||
queue_push(me, &i);
|
||||
}
|
||||
const int old_size = queue_size(me);
|
||||
int pop_count = 0;
|
||||
old_size = queue_size(me);
|
||||
pop_count = 0;
|
||||
while (!queue_is_empty(me)) {
|
||||
queue_pop(&get, me);
|
||||
pop_count++;
|
||||
}
|
||||
assert(pop_count == old_size);
|
||||
queue_destroy(me);
|
||||
// Testing automatic trim
|
||||
/* Testing automatic trim. */
|
||||
me = queue_init(sizeof(int));
|
||||
for (i = 0; i < 100; i++) {
|
||||
queue_push(me, &i);
|
||||
|
||||
537
tst/set.c
537
tst/set.c
@@ -1,9 +1,6 @@
|
||||
#include "test.h"
|
||||
#include "../src/set.h"
|
||||
|
||||
// Used for thorough testing, but takes longer to run.
|
||||
//#define LONG_TEST
|
||||
|
||||
/*
|
||||
* Include this struct for the stubs.
|
||||
*/
|
||||
@@ -14,97 +11,6 @@ struct internal_set {
|
||||
struct node *root;
|
||||
};
|
||||
|
||||
/*
|
||||
* Include this struct for the stubs.
|
||||
*/
|
||||
struct node {
|
||||
struct node *parent;
|
||||
int balance;
|
||||
void *key;
|
||||
struct node *left;
|
||||
struct node *right;
|
||||
};
|
||||
|
||||
/*
|
||||
* Verifies that the AVL tree rules are followed. The balance factor of an item
|
||||
* must be the right height minus the left height. Also, the left key must be
|
||||
* less than the right key.
|
||||
*/
|
||||
static int set_verify_recursive(struct node *const item)
|
||||
{
|
||||
if (!item) {
|
||||
return 0;
|
||||
}
|
||||
const int left = set_verify_recursive(item->left);
|
||||
const int right = set_verify_recursive(item->right);
|
||||
const int max = left > right ? left : right;
|
||||
assert(right - left == item->balance);
|
||||
if (item->left && item->right) {
|
||||
const int left_val = *(int *) item->left->key;
|
||||
const int right_val = *(int *) item->right->key;
|
||||
assert(left_val < right_val);
|
||||
}
|
||||
if (item->left) {
|
||||
assert(item->left->parent == item);
|
||||
assert(item->left->parent->key == item->key);
|
||||
}
|
||||
if (item->right) {
|
||||
assert(item->right->parent == item);
|
||||
assert(item->right->parent->key == item->key);
|
||||
}
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
static int set_compute_size(struct node *const item)
|
||||
{
|
||||
if (!item) {
|
||||
return 0;
|
||||
}
|
||||
return 1 + set_compute_size(item->left) + set_compute_size(item->right);
|
||||
}
|
||||
|
||||
static void set_verify(set me)
|
||||
{
|
||||
#ifdef LONG_TEST
|
||||
set_verify_recursive(me->root);
|
||||
assert(set_compute_size(me->root) == set_size(me));
|
||||
#endif
|
||||
}
|
||||
|
||||
static int stub_set_put(set me, void *const key)
|
||||
{
|
||||
const int ret = set_put(me, key);
|
||||
set_verify(me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stub_set_contains(set me, void *const key)
|
||||
{
|
||||
const bool ret = set_contains(me, key);
|
||||
set_verify(me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool stub_set_remove(set me, void *const key)
|
||||
{
|
||||
const bool ret = set_remove(me, key);
|
||||
set_verify(me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void stub_set_clear(set me)
|
||||
{
|
||||
set_clear(me);
|
||||
set_verify(me);
|
||||
}
|
||||
|
||||
static set stub_set_destroy(set me)
|
||||
{
|
||||
set ret = set_destroy(me);
|
||||
set_verify(me);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compare_int(const void *const one, const void *const two)
|
||||
{
|
||||
const int a = *(int *) one;
|
||||
@@ -114,421 +20,428 @@ static int compare_int(const void *const one, const void *const two)
|
||||
|
||||
void test_set(void)
|
||||
{
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
set me;
|
||||
int key;
|
||||
int count;
|
||||
int flip;
|
||||
int i;
|
||||
int j;
|
||||
int num;
|
||||
int p;
|
||||
assert(!set_init(0, compare_int));
|
||||
assert(!set_init(sizeof(int), NULL));
|
||||
set me = set_init(sizeof(int), compare_int);
|
||||
me = set_init(sizeof(int), compare_int);
|
||||
assert(me);
|
||||
int key;
|
||||
// left-left
|
||||
/* left-left */
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0xdeadbeef;
|
||||
stub_set_contains(me, &key);
|
||||
stub_set_clear(me);
|
||||
// right-right
|
||||
set_contains(me, &key);
|
||||
set_clear(me);
|
||||
/* right-right */
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0xdeadbeef;
|
||||
stub_set_contains(me, &key);
|
||||
stub_set_clear(me);
|
||||
// left-right
|
||||
set_contains(me, &key);
|
||||
set_clear(me);
|
||||
/* left-right */
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0xdeadbeef;
|
||||
stub_set_contains(me, &key);
|
||||
stub_set_clear(me);
|
||||
// right-left
|
||||
set_contains(me, &key);
|
||||
set_clear(me);
|
||||
/* right-left */
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0xdeadbeef;
|
||||
stub_set_contains(me, &key);
|
||||
stub_set_clear(me);
|
||||
// Two children edge case.
|
||||
set_contains(me, &key);
|
||||
set_clear(me);
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 11;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 6;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 15;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 9;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 12;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 13;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 16;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 14;
|
||||
stub_set_put(me, &key);
|
||||
stub_set_clear(me);
|
||||
// Two children edge case.
|
||||
set_put(me, &key);
|
||||
set_clear(me);
|
||||
/* Two children edge case. */
|
||||
key = 8;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 12;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 6;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 15;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 9;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 11;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 13;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 16;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 14;
|
||||
stub_set_put(me, &key);
|
||||
stub_set_clear(me);
|
||||
// Add a lot of items.
|
||||
int count = 0;
|
||||
bool flip = false;
|
||||
int i;
|
||||
set_put(me, &key);
|
||||
set_clear(me);
|
||||
/* Add a lot of items. */
|
||||
count = 0;
|
||||
flip = 0;
|
||||
for (i = 1234; i < 82400; i++) {
|
||||
int num = i % 765;
|
||||
const bool is_already_present = stub_set_contains(me, &num);
|
||||
stub_set_put(me, &num);
|
||||
const bool is_now_present = stub_set_contains(me, &num);
|
||||
int is_already_present;
|
||||
int is_now_present;
|
||||
num = i % 765;
|
||||
is_already_present = set_contains(me, &num);
|
||||
set_put(me, &num);
|
||||
is_now_present = set_contains(me, &num);
|
||||
assert(is_now_present);
|
||||
if (!is_already_present && is_now_present) {
|
||||
count++;
|
||||
}
|
||||
if (i == 1857 && !flip) {
|
||||
i *= -1;
|
||||
flip = true;
|
||||
flip = 1;
|
||||
}
|
||||
}
|
||||
assert(count == set_size(me));
|
||||
stub_set_contains(me, &key);
|
||||
stub_set_destroy(me);
|
||||
set_contains(me, &key);
|
||||
set_destroy(me);
|
||||
me = set_init(sizeof(int), compare_int);
|
||||
assert(set_size(me) == 0);
|
||||
assert(set_is_empty(me));
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
assert(set_size(me) == 1);
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
assert(set_size(me) == 1);
|
||||
assert(!set_is_empty(me));
|
||||
assert(stub_set_contains(me, &key));
|
||||
assert(set_contains(me, &key));
|
||||
key = 7;
|
||||
assert(!stub_set_contains(me, &key));
|
||||
stub_set_put(me, &key);
|
||||
assert(!set_contains(me, &key));
|
||||
set_put(me, &key);
|
||||
assert(set_size(me) == 2);
|
||||
assert(stub_set_contains(me, &key));
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
assert(set_contains(me, &key));
|
||||
for (i = 0; i < 10; i++) {
|
||||
stub_set_put(me, &c[i]);
|
||||
assert(stub_set_contains(me, &c[i]));
|
||||
set_put(me, &c[i]);
|
||||
assert(set_contains(me, &c[i]));
|
||||
}
|
||||
assert(set_size(me) == 9);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(stub_set_contains(me, &c[i]));
|
||||
assert(set_contains(me, &c[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(stub_set_contains(me, &i) == contains);
|
||||
assert(set_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
assert(!stub_set_remove(me, &num));
|
||||
num = -3;
|
||||
assert(!set_remove(me, &num));
|
||||
assert(set_size(me) == 9);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 6;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 8);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 4;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 7);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 7;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 6);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 9;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 5);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = -5;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 4);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 0;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 3);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 1;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 2);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 5;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 1);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
assert(!set_contains(me, &num));
|
||||
num = 2;
|
||||
assert(stub_set_remove(me, &num));
|
||||
assert(set_remove(me, &num));
|
||||
assert(set_size(me) == 0);
|
||||
assert(!stub_set_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
assert(!set_contains(me, &num));
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
stub_set_put(me, &i);
|
||||
assert(stub_set_contains(me, &i));
|
||||
set_put(me, &i);
|
||||
assert(set_contains(me, &i));
|
||||
}
|
||||
assert(set_size(me) == 1000);
|
||||
for (i = 5000; i < 5500; i++) {
|
||||
stub_set_remove(me, &i);
|
||||
assert(!stub_set_contains(me, &i));
|
||||
set_remove(me, &i);
|
||||
assert(!set_contains(me, &i));
|
||||
}
|
||||
assert(set_size(me) == 500);
|
||||
assert(!set_is_empty(me));
|
||||
stub_set_clear(me);
|
||||
set_clear(me);
|
||||
assert(set_size(me) == 0);
|
||||
assert(set_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
stub_set_put(me, &i);
|
||||
assert(stub_set_contains(me, &i));
|
||||
set_put(me, &i);
|
||||
assert(set_contains(me, &i));
|
||||
}
|
||||
assert(set_size(me) == 1000);
|
||||
stub_set_clear(me);
|
||||
int p = 0xdeadbeef;
|
||||
assert(!stub_set_remove(me, &p));
|
||||
set_clear(me);
|
||||
p = 0xdeadbeef;
|
||||
assert(!set_remove(me, &p));
|
||||
assert(set_size(me) == 0);
|
||||
assert(set_is_empty(me));
|
||||
me = stub_set_destroy(me);
|
||||
me = set_destroy(me);
|
||||
assert(!me);
|
||||
// Create odd shape graph.
|
||||
/* Create odd shape graph. */
|
||||
me = set_init(sizeof(int), compare_int);
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 15;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 8;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 12;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 18;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 12;
|
||||
stub_set_remove(me, &key);
|
||||
set_remove(me, &key);
|
||||
key = 5;
|
||||
stub_set_remove(me, &key);
|
||||
set_remove(me, &key);
|
||||
key = 3;
|
||||
stub_set_remove(me, &key);
|
||||
set_remove(me, &key);
|
||||
key = 8;
|
||||
stub_set_remove(me, &key);
|
||||
stub_set_clear(me);
|
||||
// Allocate many nodes.
|
||||
set_remove(me, &key);
|
||||
set_clear(me);
|
||||
/* Allocate many nodes. */
|
||||
for (i = 8123; i < 12314; i += 3) {
|
||||
stub_set_put(me, &i);
|
||||
assert(stub_set_contains(me, &i));
|
||||
set_put(me, &i);
|
||||
assert(set_contains(me, &i));
|
||||
}
|
||||
for (i = 13000; i > 8000; i--) {
|
||||
stub_set_remove(me, &i);
|
||||
assert(!stub_set_contains(me, &i));
|
||||
set_remove(me, &i);
|
||||
assert(!set_contains(me, &i));
|
||||
}
|
||||
stub_set_clear(me);
|
||||
// Create another odd shape graph.
|
||||
set_clear(me);
|
||||
/* Create another odd shape graph. */
|
||||
key = 20;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 40;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 15;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 30;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 50;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 25;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 35;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 36;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 34;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 33;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 32;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 30;
|
||||
stub_set_remove(me, &key);
|
||||
set_remove(me, &key);
|
||||
key = 32;
|
||||
assert(stub_set_contains(me, &key));
|
||||
stub_set_clear(me);
|
||||
// One sided tree.
|
||||
assert(set_contains(me, &key));
|
||||
set_clear(me);
|
||||
/* One sided tree. */
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 9;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 8;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 8;
|
||||
stub_set_remove(me, &key);
|
||||
set_remove(me, &key);
|
||||
key = 7;
|
||||
assert(stub_set_contains(me, &key));
|
||||
stub_set_destroy(me);
|
||||
// Replace two sided two children.
|
||||
assert(set_contains(me, &key));
|
||||
set_destroy(me);
|
||||
/* Replace two sided two children. */
|
||||
me = set_init(sizeof(int), compare_int);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 6;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = -1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = -2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_remove(me, &key);
|
||||
assert(!stub_set_contains(me, &key));
|
||||
stub_set_clear(me);
|
||||
set_remove(me, &key);
|
||||
assert(!set_contains(me, &key));
|
||||
set_clear(me);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 6;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = -1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = -2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 0;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_remove(me, &key);
|
||||
assert(!stub_set_contains(me, &key));
|
||||
me = stub_set_destroy(me);
|
||||
set_remove(me, &key);
|
||||
assert(!set_contains(me, &key));
|
||||
me = set_destroy(me);
|
||||
assert(!me);
|
||||
me = set_init(sizeof(int), compare_int);
|
||||
for (i = 4817; i > -2983; i -= 11) {
|
||||
stub_set_put(me, &i);
|
||||
assert(stub_set_contains(me, &i));
|
||||
set_put(me, &i);
|
||||
assert(set_contains(me, &i));
|
||||
}
|
||||
for (i = -432; i < 3849; i += 7) {
|
||||
stub_set_remove(me, &i);
|
||||
assert(!stub_set_contains(me, &i));
|
||||
set_remove(me, &i);
|
||||
assert(!set_contains(me, &i));
|
||||
}
|
||||
stub_set_clear(me);
|
||||
set_clear(me);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_remove(me, &key);
|
||||
stub_set_clear(me);
|
||||
// Two children edge case on the other side.
|
||||
set_remove(me, &key);
|
||||
set_clear(me);
|
||||
/* Two children edge case on the other side. */
|
||||
key = 8;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 4;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 12;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 2;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 6;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 10;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 16;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 1;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 3;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 5;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 7;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 9;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 11;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 15;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 17;
|
||||
stub_set_put(me, &key);
|
||||
set_put(me, &key);
|
||||
key = 13;
|
||||
stub_set_put(me, &key);
|
||||
stub_set_clear(me);
|
||||
set_put(me, &key);
|
||||
set_clear(me);
|
||||
}
|
||||
|
||||
18
tst/stack.c
18
tst/stack.c
@@ -3,28 +3,30 @@
|
||||
|
||||
void test_stack(void)
|
||||
{
|
||||
assert(!stack_init(0));
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
stack me = stack_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
stack me;
|
||||
int get;
|
||||
int i;
|
||||
assert(!stack_init(0));
|
||||
me = stack_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(stack_size(me) == 0);
|
||||
assert(stack_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
stack_push(me, &val[i]);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(stack_top(&get, me));
|
||||
assert(get == val[i]);
|
||||
}
|
||||
assert(stack_size(me) == 10);
|
||||
assert(!stack_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
stack_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(get_arr[i] == i + 1);
|
||||
}
|
||||
for (i = 0; i < 9; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(stack_pop(&get, me));
|
||||
assert(get == 10 - i);
|
||||
}
|
||||
@@ -32,12 +34,12 @@ void test_stack(void)
|
||||
assert(stack_size(me) == 1);
|
||||
stack_clear(me);
|
||||
assert(stack_size(me) == 0);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
assert(!stack_pop(&get, me));
|
||||
assert(!stack_top(&get, me));
|
||||
me = stack_destroy(me);
|
||||
assert(!me);
|
||||
// Testing automatic trim
|
||||
/* Testing automatic trim. */
|
||||
me = stack_init(sizeof(int));
|
||||
for (i = 0; i < 100; i++) {
|
||||
stack_push(me, &i);
|
||||
|
||||
@@ -12,8 +12,8 @@ static int hash_count;
|
||||
|
||||
static unsigned long hash_int(const void *const key)
|
||||
{
|
||||
hash_count++;
|
||||
unsigned long hash = 17;
|
||||
hash_count++;
|
||||
hash = 31 * hash + *(int *) key;
|
||||
return hash;
|
||||
}
|
||||
@@ -25,16 +25,22 @@ static unsigned long bad_hash_int(const void *const key)
|
||||
|
||||
void test_unordered_map(void)
|
||||
{
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
unordered_map me;
|
||||
int key;
|
||||
int num;
|
||||
int value;
|
||||
int i;
|
||||
int j;
|
||||
assert(!unordered_map_init(0, sizeof(int), hash_int, compare_int));
|
||||
assert(!unordered_map_init(sizeof(int), 0, hash_int, compare_int));
|
||||
assert(!unordered_map_init(sizeof(int), sizeof(int), NULL, compare_int));
|
||||
assert(!unordered_map_init(sizeof(int), sizeof(int), hash_int, NULL));
|
||||
unordered_map me = unordered_map_init(sizeof(int), sizeof(int),
|
||||
hash_int, compare_int);
|
||||
me = unordered_map_init(sizeof(int), sizeof(int), hash_int, compare_int);
|
||||
assert(unordered_map_size(me) == 0);
|
||||
assert(unordered_map_is_empty(me));
|
||||
int key = 4;
|
||||
int value = 9;
|
||||
key = 4;
|
||||
value = 9;
|
||||
unordered_map_put(me, &key, &value);
|
||||
assert(unordered_map_size(me) == 1);
|
||||
value = 5;
|
||||
@@ -50,8 +56,6 @@ void test_unordered_map(void)
|
||||
unordered_map_put(me, &key, &value);
|
||||
assert(unordered_map_size(me) == 2);
|
||||
assert(unordered_map_contains(me, &key));
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
unordered_map_put(me, &val_arr[i], &value);
|
||||
assert(unordered_map_contains(me, &val_arr[i]));
|
||||
@@ -60,17 +64,16 @@ void test_unordered_map(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(unordered_map_contains(me, &val_arr[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (val_arr[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(unordered_map_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!unordered_map_remove(me, &num));
|
||||
assert(unordered_map_size(me) == 9);
|
||||
assert(!unordered_map_contains(me, &num));
|
||||
@@ -110,7 +113,7 @@ void test_unordered_map(void)
|
||||
assert(unordered_map_remove(me, &num));
|
||||
assert(unordered_map_size(me) == 0);
|
||||
assert(!unordered_map_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_map_put(me, &i, &value);
|
||||
assert(unordered_map_contains(me, &i));
|
||||
@@ -125,7 +128,7 @@ void test_unordered_map(void)
|
||||
unordered_map_clear(me);
|
||||
assert(unordered_map_size(me) == 0);
|
||||
assert(unordered_map_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_map_put(me, &i, &value);
|
||||
assert(unordered_map_contains(me, &i));
|
||||
|
||||
@@ -12,8 +12,8 @@ static int hash_count;
|
||||
|
||||
static unsigned long hash_int(const void *const key)
|
||||
{
|
||||
hash_count++;
|
||||
unsigned long hash = 17;
|
||||
hash_count++;
|
||||
hash = 31 * hash + *(int *) key;
|
||||
return hash;
|
||||
}
|
||||
@@ -25,6 +25,15 @@ static unsigned long bad_hash_int(const void *const key)
|
||||
|
||||
void test_unordered_multimap(void)
|
||||
{
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
unordered_multimap me;
|
||||
int key;
|
||||
int value;
|
||||
int num;
|
||||
int count;
|
||||
int val;
|
||||
int i;
|
||||
int j;
|
||||
assert(!unordered_multimap_init(0, sizeof(int), hash_int, compare_int,
|
||||
compare_int));
|
||||
assert(!unordered_multimap_init(sizeof(int), 0, hash_int, compare_int,
|
||||
@@ -35,14 +44,13 @@ void test_unordered_multimap(void)
|
||||
compare_int));
|
||||
assert(!unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
|
||||
compare_int, NULL));
|
||||
unordered_multimap me =
|
||||
unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
|
||||
compare_int, compare_int);
|
||||
me = unordered_multimap_init(sizeof(int), sizeof(int), hash_int,
|
||||
compare_int, compare_int);
|
||||
assert(me);
|
||||
assert(unordered_multimap_size(me) == 0);
|
||||
assert(unordered_multimap_is_empty(me));
|
||||
int key = 4;
|
||||
int value = 123;
|
||||
key = 4;
|
||||
value = 123;
|
||||
unordered_multimap_put(me, &key, &value);
|
||||
assert(unordered_multimap_size(me) == 1);
|
||||
unordered_multimap_put(me, &key, &value);
|
||||
@@ -62,8 +70,6 @@ void test_unordered_multimap(void)
|
||||
assert(unordered_multimap_size(me) == 1);
|
||||
unordered_multimap_remove(me, &key, &value);
|
||||
assert(unordered_multimap_size(me) == 0);
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
unordered_multimap_put(me, &c[i], &value);
|
||||
assert(unordered_multimap_contains(me, &c[i]));
|
||||
@@ -72,17 +78,16 @@ void test_unordered_multimap(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(unordered_multimap_contains(me, &c[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(unordered_multimap_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!unordered_multimap_remove(me, &num, &value));
|
||||
assert(unordered_multimap_size(me) == 10);
|
||||
assert(!unordered_multimap_contains(me, &num));
|
||||
@@ -117,8 +122,8 @@ void test_unordered_multimap(void)
|
||||
num = 5;
|
||||
assert(unordered_multimap_count(me, &num) == 2);
|
||||
unordered_multimap_get_start(me, &num);
|
||||
int count = 0;
|
||||
int val = 0xdeadbeef;
|
||||
count = 0;
|
||||
val = 0xdeadbeef;
|
||||
while (unordered_multimap_get_next(&val, me)) {
|
||||
count++;
|
||||
assert(val == 123);
|
||||
@@ -136,7 +141,7 @@ void test_unordered_multimap(void)
|
||||
assert(unordered_multimap_remove(me, &num, &value));
|
||||
assert(unordered_multimap_size(me) == 0);
|
||||
assert(!unordered_multimap_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_multimap_put(me, &i, &value);
|
||||
assert(unordered_multimap_contains(me, &i));
|
||||
@@ -151,7 +156,7 @@ void test_unordered_multimap(void)
|
||||
unordered_multimap_clear(me);
|
||||
assert(unordered_multimap_size(me) == 0);
|
||||
assert(unordered_multimap_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_multimap_put(me, &i, &value);
|
||||
assert(unordered_multimap_contains(me, &i));
|
||||
|
||||
@@ -12,8 +12,8 @@ static int hash_count;
|
||||
|
||||
static unsigned long hash_int(const void *const key)
|
||||
{
|
||||
hash_count++;
|
||||
unsigned long hash = 17;
|
||||
hash_count++;
|
||||
hash = 31 * hash + *(int *) key;
|
||||
return hash;
|
||||
}
|
||||
@@ -25,15 +25,20 @@ static unsigned long bad_hash_int(const void *const key)
|
||||
|
||||
void test_unordered_multiset(void)
|
||||
{
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
unordered_multiset me;
|
||||
int key;
|
||||
int num;
|
||||
int i;
|
||||
int j;
|
||||
assert(!unordered_multiset_init(0, hash_int, compare_int));
|
||||
assert(!unordered_multiset_init(sizeof(int), NULL, compare_int));
|
||||
assert(!unordered_multiset_init(sizeof(int), hash_int, NULL));
|
||||
unordered_multiset me =
|
||||
unordered_multiset_init(sizeof(int), hash_int, compare_int);
|
||||
me = unordered_multiset_init(sizeof(int), hash_int, compare_int);
|
||||
assert(me);
|
||||
assert(unordered_multiset_size(me) == 0);
|
||||
assert(unordered_multiset_is_empty(me));
|
||||
int key = 4;
|
||||
key = 4;
|
||||
unordered_multiset_put(me, &key);
|
||||
assert(unordered_multiset_size(me) == 1);
|
||||
unordered_multiset_put(me, &key);
|
||||
@@ -53,8 +58,6 @@ void test_unordered_multiset(void)
|
||||
assert(unordered_multiset_size(me) == 1);
|
||||
unordered_multiset_remove(me, &key);
|
||||
assert(unordered_multiset_size(me) == 0);
|
||||
int c[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
unordered_multiset_put(me, &c[i]);
|
||||
assert(unordered_multiset_contains(me, &c[i]));
|
||||
@@ -63,17 +66,16 @@ void test_unordered_multiset(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(unordered_multiset_contains(me, &c[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (c[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(unordered_multiset_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!unordered_multiset_remove(me, &num));
|
||||
assert(unordered_multiset_size(me) == 10);
|
||||
assert(!unordered_multiset_contains(me, &num));
|
||||
@@ -117,7 +119,7 @@ void test_unordered_multiset(void)
|
||||
assert(unordered_multiset_remove(me, &num));
|
||||
assert(unordered_multiset_size(me) == 0);
|
||||
assert(!unordered_multiset_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_multiset_put(me, &i);
|
||||
assert(unordered_multiset_contains(me, &i));
|
||||
@@ -132,7 +134,7 @@ void test_unordered_multiset(void)
|
||||
unordered_multiset_clear(me);
|
||||
assert(unordered_multiset_size(me) == 0);
|
||||
assert(unordered_multiset_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_multiset_put(me, &i);
|
||||
assert(unordered_multiset_contains(me, &i));
|
||||
|
||||
@@ -12,8 +12,8 @@ static int hash_count;
|
||||
|
||||
static unsigned long hash_int(const void *const key)
|
||||
{
|
||||
hash_count++;
|
||||
unsigned long hash = 17;
|
||||
hash_count++;
|
||||
hash = 31 * hash + *(int *) key;
|
||||
return hash;
|
||||
}
|
||||
@@ -25,14 +25,21 @@ static unsigned long bad_hash_int(const void *const key)
|
||||
|
||||
void test_unordered_set(void)
|
||||
{
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
unordered_set me;
|
||||
int key;
|
||||
int num;
|
||||
int p;
|
||||
int i;
|
||||
int j;
|
||||
assert(!unordered_set_init(0, hash_int, compare_int));
|
||||
assert(!unordered_set_init(sizeof(int), NULL, compare_int));
|
||||
assert(!unordered_set_init(sizeof(int), hash_int, NULL));
|
||||
unordered_set me = unordered_set_init(sizeof(int), hash_int, compare_int);
|
||||
me = unordered_set_init(sizeof(int), hash_int, compare_int);
|
||||
assert(me);
|
||||
assert(unordered_set_size(me) == 0);
|
||||
assert(unordered_set_is_empty(me));
|
||||
int key = 4;
|
||||
key = 4;
|
||||
unordered_set_put(me, &key);
|
||||
assert(unordered_set_size(me) == 1);
|
||||
unordered_set_put(me, &key);
|
||||
@@ -44,8 +51,6 @@ void test_unordered_set(void)
|
||||
unordered_set_put(me, &key);
|
||||
assert(unordered_set_size(me) == 2);
|
||||
assert(unordered_set_contains(me, &key));
|
||||
int val_arr[10] = {5, 9, 4, -5, 0, 6, 1, 5, 7, 2};
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
unordered_set_put(me, &val_arr[i]);
|
||||
assert(unordered_set_contains(me, &val_arr[i]));
|
||||
@@ -54,17 +59,16 @@ void test_unordered_set(void)
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(unordered_set_contains(me, &val_arr[i]));
|
||||
}
|
||||
int j;
|
||||
for (i = -100; i < 100; i++) {
|
||||
bool contains = false;
|
||||
int contains = 0;
|
||||
for (j = 0; j < 10; j++) {
|
||||
if (val_arr[j] == i) {
|
||||
contains = true;
|
||||
contains = 1;
|
||||
}
|
||||
}
|
||||
assert(unordered_set_contains(me, &i) == contains);
|
||||
}
|
||||
int num = -3;
|
||||
num = -3;
|
||||
assert(!unordered_set_remove(me, &num));
|
||||
assert(unordered_set_size(me) == 9);
|
||||
assert(!unordered_set_contains(me, &num));
|
||||
@@ -104,7 +108,7 @@ void test_unordered_set(void)
|
||||
assert(unordered_set_remove(me, &num));
|
||||
assert(unordered_set_size(me) == 0);
|
||||
assert(!unordered_set_contains(me, &num));
|
||||
// Add a lot of items and remove individually.
|
||||
/* Add a lot of items and remove individually. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_set_put(me, &i);
|
||||
assert(unordered_set_contains(me, &i));
|
||||
@@ -119,7 +123,7 @@ void test_unordered_set(void)
|
||||
unordered_set_clear(me);
|
||||
assert(unordered_set_size(me) == 0);
|
||||
assert(unordered_set_is_empty(me));
|
||||
// Add a lot of items and clear.
|
||||
/* Add a lot of items and clear. */
|
||||
for (i = 5000; i < 6000; i++) {
|
||||
unordered_set_put(me, &i);
|
||||
assert(unordered_set_contains(me, &i));
|
||||
@@ -129,7 +133,7 @@ void test_unordered_set(void)
|
||||
unordered_set_rehash(me);
|
||||
assert(hash_count == 1000);
|
||||
unordered_set_clear(me);
|
||||
int p = 0xdeadbeef;
|
||||
p = 0xdeadbeef;
|
||||
assert(!unordered_set_remove(me, &p));
|
||||
assert(unordered_set_size(me) == 0);
|
||||
assert(unordered_set_is_empty(me));
|
||||
|
||||
39
tst/vector.c
39
tst/vector.c
@@ -4,9 +4,9 @@
|
||||
|
||||
static void test_vector_of_vectors(void)
|
||||
{
|
||||
// Test using a vector of vectors of ints
|
||||
/* Test using a vector of vectors of ints */
|
||||
vector outer = vector_init(sizeof(vector));
|
||||
// Add vectors to the outer vector
|
||||
/* Add vectors to the outer vector */
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0; i < 5; i++) {
|
||||
@@ -18,7 +18,7 @@ static void test_vector_of_vectors(void)
|
||||
vector_add_last(outer, &inner);
|
||||
}
|
||||
assert(vector_size(outer) == 5);
|
||||
// Delete the vectors in the outer vector
|
||||
/* Delete the vectors in the outer vector */
|
||||
for (i = 0; i < 5; i++) {
|
||||
vector inner = NULL;
|
||||
vector_get_first(&inner, outer);
|
||||
@@ -39,6 +39,7 @@ static void test_vector_dynamic(void)
|
||||
char **str = malloc(5 * sizeof(char **));
|
||||
int i;
|
||||
int j;
|
||||
vector str_vector;
|
||||
for (i = 0; i < 5; i++) {
|
||||
str[i] = malloc(10 * sizeof(char *));
|
||||
for (j = 0; j < 9; j++) {
|
||||
@@ -46,7 +47,7 @@ static void test_vector_dynamic(void)
|
||||
}
|
||||
str[i][9] = '\0';
|
||||
}
|
||||
vector str_vector = vector_init(sizeof(char *));
|
||||
str_vector = vector_init(sizeof(char *));
|
||||
assert(str_vector);
|
||||
for (i = 0; i < 5; i++) {
|
||||
vector_add_last(str_vector, &str[i]);
|
||||
@@ -67,35 +68,42 @@ static void test_vector_dynamic(void)
|
||||
|
||||
void test_vector(void)
|
||||
{
|
||||
assert(!vector_init(0));
|
||||
|
||||
int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
vector me = vector_init(sizeof(int));
|
||||
int get_arr[10] = {0};
|
||||
int trimmed[5] = {0};
|
||||
int arr[3] = {0};
|
||||
int get;
|
||||
vector me;
|
||||
int i;
|
||||
int *data;
|
||||
int add;
|
||||
int set;
|
||||
assert(!vector_init(0));
|
||||
me = vector_init(sizeof(int));
|
||||
assert(me);
|
||||
assert(vector_size(me) == 0);
|
||||
assert(vector_is_empty(me));
|
||||
int i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
vector_add_first(me, &val[i]);
|
||||
int get = 0;
|
||||
get = 0;
|
||||
vector_get_first(&get, me);
|
||||
assert(get == val[i]);
|
||||
}
|
||||
assert(vector_size(me) == 10);
|
||||
assert(!vector_is_empty(me));
|
||||
int get_arr[10] = {0};
|
||||
vector_copy_to_array(get_arr, me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
int get = 0;
|
||||
get = 0;
|
||||
vector_get_at(&get, me, i);
|
||||
assert(get == val[9 - i]);
|
||||
assert(get_arr[i] == val[9 - i]);
|
||||
}
|
||||
int *const data = vector_get_data(me);
|
||||
data = vector_get_data(me);
|
||||
for (i = 0; i < 10; i++) {
|
||||
assert(data[i] == val[9 - i]);
|
||||
}
|
||||
assert(vector_capacity(me) >= vector_size(me));
|
||||
int trimmed[5] = {0};
|
||||
vector_trim(me);
|
||||
vector_reserve(me, 3);
|
||||
for (i = 0; i < 7; i++) {
|
||||
@@ -106,14 +114,14 @@ void test_vector(void)
|
||||
for (i = 0; i < 3; i++) {
|
||||
assert(10 - i == trimmed[i]);
|
||||
}
|
||||
int add = 3;
|
||||
add = 3;
|
||||
vector_add_last(me, &add);
|
||||
add = -1;
|
||||
vector_add_at(me, 1, &add);
|
||||
add = -2;
|
||||
vector_add_last(me, &add);
|
||||
assert(vector_size(me) == 6);
|
||||
int get = 0xdeadbeef;
|
||||
get = 0xdeadbeef;
|
||||
vector_get_first(&get, me);
|
||||
assert(get == 10);
|
||||
get = 0xdeadbeef;
|
||||
@@ -143,13 +151,12 @@ void test_vector(void)
|
||||
assert(get == 9);
|
||||
vector_get_last(&get, me);
|
||||
assert(get == 3);
|
||||
int set = 12;
|
||||
set = 12;
|
||||
vector_set_first(me, &set);
|
||||
set = 13;
|
||||
vector_set_at(me, 1, &set);
|
||||
set = 14;
|
||||
vector_set_last(me, &set);
|
||||
int arr[3] = {0};
|
||||
vector_copy_to_array(arr, me);
|
||||
assert(arr[0] == 12);
|
||||
assert(arr[1] == 13);
|
||||
|
||||
Reference in New Issue
Block a user