Make sure containers are valid upon initialization

When initializing a container, the arguments are now checked for validity. This is done by verifying that data sizes are not 0 and that function pointers are not NULL.
This commit is contained in:
Bailey Thompson
2018-01-11 21:54:49 -05:00
committed by GitHub
parent c51bdfefef
commit 2f39963b3e
16 changed files with 214 additions and 139 deletions

View File

@@ -26,27 +26,30 @@
#include "array.h"
struct internal_array {
size_t data_size;
int element_count;
size_t bytes_per_item;
int item_count;
void *data;
};
/**
* Initializes an array, which is a static contiguous array.
*
* @param element_count The amount of elements in the array.
* @param data_size The size of each element in the array.
* @param element_count The amount of elements in the array. Must be positive.
* @param data_size The size of each element in the array. Must be positive.
*
* @return The newly-initialized array, or NULL if memory allocation error.
*/
array array_init(const int element_count, const size_t data_size)
{
if (element_count <= 0 || data_size == 0) {
return NULL;
}
struct internal_array *const init = malloc(sizeof(struct internal_array));
if (!init) {
return NULL;
}
init->data_size = data_size;
init->element_count = element_count;
init->bytes_per_item = data_size;
init->item_count = element_count;
init->data = calloc((size_t) element_count, data_size);
if (!init->data) {
free(init);
@@ -64,7 +67,7 @@ array array_init(const int element_count, const size_t data_size)
*/
int array_size(array me)
{
return me->element_count;
return me->item_count;
}
/**
@@ -75,7 +78,7 @@ int array_size(array me)
*/
void array_copy_to_array(void *const arr, array me)
{
memcpy(arr, me->data, me->element_count * me->data_size);
memcpy(arr, me->data, me->item_count * me->bytes_per_item);
}
/**
@@ -98,7 +101,7 @@ void *array_get_data(array me)
*/
static bool array_is_illegal_input(array me, const int index)
{
return index < 0 || index >= me->element_count;
return index < 0 || index >= me->item_count;
}
/**
@@ -116,7 +119,7 @@ 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->data_size, data, me->data_size);
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
return 0;
}
@@ -135,7 +138,7 @@ 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->data_size, me->data_size);
memcpy(data, me->data + index * me->bytes_per_item, me->bytes_per_item);
return 0;
}

View File

@@ -44,12 +44,15 @@ struct node {
/**
* Initializes a deque, which is a doubly-ended queue.
*
* @param data_size The size of each element in the deque.
* @param data_size The size of each element in the deque. Must be positive.
*
* @return The newly-allocated deque, or NULL if could not allocate memory.
* @return The newly-initialized deque, or NULL if memory allocation error.
*/
deque deque_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_deque *const init = malloc(sizeof(struct internal_deque));
if (!init) {
return NULL;

View File

@@ -26,8 +26,8 @@
#include "forward_list.h"
struct internal_forward_list {
size_t data_size;
int space;
size_t bytes_per_item;
int item_count;
struct node *head;
};
@@ -39,19 +39,23 @@ struct node {
/**
* Initializes a singly-linked list.
*
* @param data_size The size of data to store.
* @param data_size The size of data to store. Must be positive.
*
* @return The singly-linked list, or NULL if memory could not be allocated.
* @return The newly-initialized singly-linked list, or NULL if memory
* allocation error.
*/
forward_list forward_list_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_forward_list *const init =
malloc(sizeof(struct internal_forward_list));
if (!init) {
return NULL;
}
init->data_size = data_size;
init->space = 0;
init->bytes_per_item = data_size;
init->item_count = 0;
init->head = NULL;
return init;
}
@@ -65,7 +69,7 @@ forward_list forward_list_init(const size_t data_size)
*/
int forward_list_size(forward_list me)
{
return me->space;
return me->item_count;
}
/**
@@ -91,8 +95,8 @@ 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->data_size);
offset += me->data_size;
memcpy(arr + offset, traverse->data, me->bytes_per_item);
offset += me->bytes_per_item;
traverse = traverse->next;
}
}
@@ -136,19 +140,19 @@ 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)
{
if (index < 0 || index > me->space) {
if (index < 0 || index > me->item_count) {
return -EINVAL;
}
struct node *const add = malloc(sizeof(struct node));
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->data_size);
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
memcpy(add->data, data, me->data_size);
memcpy(add->data, data, me->bytes_per_item);
if (index == 0) {
add->next = me->head;
me->head = add;
@@ -157,7 +161,7 @@ int forward_list_add_at(forward_list me, const int index, void *const data)
add->next = traverse->next;
traverse->next = add;
}
me->space++;
me->item_count++;
return 0;
}
@@ -172,7 +176,7 @@ int forward_list_add_at(forward_list me, const int index, void *const data)
*/
int forward_list_add_last(forward_list me, void *const data)
{
return forward_list_add_at(me, me->space, data);
return forward_list_add_at(me, me->item_count, data);
}
/*
@@ -180,7 +184,7 @@ int forward_list_add_last(forward_list me, void *const data)
*/
static bool forward_list_is_illegal_input(forward_list me, const int index)
{
return index < 0 || index >= me->space || me->space == 0;
return index < 0 || index >= me->item_count || me->item_count == 0;
}
/**
@@ -215,7 +219,7 @@ int forward_list_remove_at(forward_list me, const int index)
me->head = temp->next;
free(temp->data);
free(temp);
} else if (index == me->space - 1) {
} else if (index == me->item_count - 1) {
struct node *const traverse = forward_list_get_node_at(me, index - 1);
free(traverse->next->data);
free(traverse->next);
@@ -227,7 +231,7 @@ int forward_list_remove_at(forward_list me, const int index)
free(backup->data);
free(backup);
}
me->space--;
me->item_count--;
return 0;
}
@@ -241,7 +245,7 @@ int forward_list_remove_at(forward_list me, const int index)
*/
int forward_list_remove_last(forward_list me)
{
return forward_list_remove_at(me, me->space - 1);
return forward_list_remove_at(me, me->item_count - 1);
}
/**
@@ -274,7 +278,7 @@ int forward_list_set_at(forward_list me, const int index, void *const data)
return -EINVAL;
}
struct node *const traverse = forward_list_get_node_at(me, index);
memcpy(traverse->data, data, me->data_size);
memcpy(traverse->data, data, me->bytes_per_item);
return 0;
}
@@ -289,7 +293,7 @@ int forward_list_set_at(forward_list me, const int index, void *const data)
*/
int forward_list_set_last(forward_list me, void *const data)
{
return forward_list_set_at(me, me->space - 1, data);
return forward_list_set_at(me, me->item_count - 1, data);
}
/**
@@ -322,7 +326,7 @@ int forward_list_get_at(void *const data, forward_list me, const int index)
return -EINVAL;
}
struct node *const traverse = forward_list_get_node_at(me, index);
memcpy(data, traverse->data, me->data_size);
memcpy(data, traverse->data, me->bytes_per_item);
return 0;
}
@@ -337,7 +341,7 @@ int forward_list_get_at(void *const data, forward_list me, const int index)
*/
int forward_list_get_last(void *const data, forward_list me)
{
return forward_list_get_at(data, me, me->space - 1);
return forward_list_get_at(data, me, me->item_count - 1);
}
/**
@@ -355,7 +359,7 @@ void forward_list_clear(forward_list me)
free(temp);
}
me->head = NULL;
me->space = 0;
me->item_count = 0;
}
/**

View File

@@ -26,8 +26,8 @@
#include "list.h"
struct internal_list {
size_t data_size;
int space;
size_t bytes_per_item;
int item_count;
struct node *head;
struct node *tail;
};
@@ -41,18 +41,22 @@ struct node {
/**
* Initializes a doubly-linked list.
*
* @param data_size The size of data to store.
* @param data_size The size of data to store. Must be positive.
*
* @return The doubly-linked list, or NULL if memory could not be allocated.
* @return The newly-initialized doubly-linked list, or NULL if memory
* allocation error.
*/
list list_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_list *const init = malloc(sizeof(struct internal_list));
if (!init) {
return NULL;
}
init->data_size = data_size;
init->space = 0;
init->bytes_per_item = data_size;
init->item_count = 0;
init->head = NULL;
init->tail = NULL;
return init;
@@ -67,7 +71,7 @@ list list_init(const size_t data_size)
*/
int list_size(list me)
{
return me->space;
return me->item_count;
}
/**
@@ -93,8 +97,8 @@ 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->data_size);
offset += me->data_size;
memcpy(arr + offset, traverse->data, me->bytes_per_item);
offset += me->bytes_per_item;
traverse = traverse->next;
}
}
@@ -117,7 +121,7 @@ static struct node *list_get_node_from_head(list me, const int index)
static struct node *list_get_node_from_tail(list me, const int index)
{
struct node *traverse = me->tail;
for (int i = me->space - 1; i > index; i--) {
for (int i = me->item_count - 1; i > index; i--) {
traverse = traverse->prev;
}
return traverse;
@@ -128,7 +132,7 @@ static struct node *list_get_node_from_tail(list me, const int index)
*/
static struct node *list_get_node_at(list me, const int index)
{
if (index <= me->space / 2) {
if (index <= me->item_count / 2) {
return list_get_node_from_head(me, index);
} else {
return list_get_node_from_tail(me, index);
@@ -151,13 +155,13 @@ int list_add_first(list me, void *const data)
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->data_size);
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
add->prev = NULL;
memcpy(add->data, data, me->data_size);
memcpy(add->data, data, me->bytes_per_item);
add->next = traverse;
if (traverse) {
traverse->prev = add;
@@ -166,7 +170,7 @@ int list_add_first(list me, void *const data)
if (!me->tail) {
me->tail = traverse;
}
me->space++;
me->item_count++;
return 0;
}
@@ -183,13 +187,13 @@ int list_add_first(list me, void *const data)
*/
int list_add_at(list me, const int index, void *const data)
{
if (index < 0 || index > me->space) {
if (index < 0 || index > me->item_count) {
return -EINVAL;
}
if (index == 0) {
return list_add_first(me, data);
}
if (index == me->space) {
if (index == me->item_count) {
return list_add_last(me, data);
}
// The new node will go right before this node.
@@ -198,17 +202,17 @@ int list_add_at(list me, const int index, void *const data)
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->data_size);
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
add->prev = traverse->prev;
memcpy(add->data, data, me->data_size);
memcpy(add->data, data, me->bytes_per_item);
add->next = traverse;
traverse->prev->next = add;
traverse->prev = add;
me->space++;
me->item_count++;
return 0;
}
@@ -228,19 +232,19 @@ int list_add_last(list me, void *const data)
if (!add) {
return -ENOMEM;
}
add->data = malloc(me->data_size);
add->data = malloc(me->bytes_per_item);
if (!add->data) {
free(add);
return -ENOMEM;
}
add->prev = traverse;
memcpy(add->data, data, me->data_size);
memcpy(add->data, data, me->bytes_per_item);
add->next = NULL;
if (traverse) {
traverse->next = add;
}
me->tail = add;
me->space++;
me->item_count++;
return 0;
}
@@ -249,7 +253,7 @@ int list_add_last(list me, void *const data)
*/
static bool list_is_illegal_input(list me, const int index)
{
return index < 0 || index >= me->space || me->space == 0;
return index < 0 || index >= me->item_count || me->item_count == 0;
}
/**
@@ -283,7 +287,7 @@ int list_remove_at(list me, const int index)
if (index == 0) {
traverse->next->prev = NULL;
me->head = traverse->next;
} else if (index == me->space - 1) {
} else if (index == me->item_count - 1) {
traverse->prev->next = NULL;
me->tail = traverse->prev;
} else {
@@ -292,7 +296,7 @@ int list_remove_at(list me, const int index)
}
free(traverse->data);
free(traverse);
me->space--;
me->item_count--;
return 0;
}
@@ -306,7 +310,7 @@ int list_remove_at(list me, const int index)
*/
int list_remove_last(list me)
{
return list_remove_at(me, me->space - 1);
return list_remove_at(me, me->item_count - 1);
}
/**
@@ -339,7 +343,7 @@ int list_set_at(list me, const int index, void *const data)
return -EINVAL;
}
struct node *const traverse = list_get_node_at(me, index);
memcpy(traverse->data, data, me->data_size);
memcpy(traverse->data, data, me->bytes_per_item);
return 0;
}
@@ -354,7 +358,7 @@ int list_set_at(list me, const int index, void *const data)
*/
int list_set_last(list me, void *const data)
{
return list_set_at(me, me->space - 1, data);
return list_set_at(me, me->item_count - 1, data);
}
/**
@@ -387,7 +391,7 @@ int list_get_at(void *const data, list me, const int index)
return -EINVAL;
}
struct node *const traverse = list_get_node_at(me, index);
memcpy(data, traverse->data, me->data_size);
memcpy(data, traverse->data, me->bytes_per_item);
return 0;
}
@@ -402,7 +406,7 @@ int list_get_at(void *const data, list me, const int index)
*/
int list_get_last(void *const data, list me)
{
return list_get_at(data, me, me->space - 1);
return list_get_at(data, me, me->item_count - 1);
}
/**
@@ -420,7 +424,7 @@ void list_clear(list me)
free(temp);
}
me->head = NULL;
me->space = 0;
me->item_count = 0;
me->tail = NULL;
}

View File

@@ -46,9 +46,10 @@ struct node {
* Initializes a map, which is a collection of key-value pairs, sorted by keys,
* keys are unique
*
* @param key_size The size of each key in the map.
* @param value_size The size of each value in the map.
* @param comparator The comparator function used for key ordering.
* @param key_size The size of each key in the map. Must be positive.
* @param value_size The size of each value in the map. Must be positive.
* @param comparator The comparator function used for key ordering. Must not be
* NULL.
*
* @return The newly-initialized map, or NULL if memory allocation error.
*/
@@ -56,6 +57,9 @@ map map_init(const size_t key_size,
const size_t value_size,
int (*const comparator)(const void *const, const void *const))
{
if (key_size == 0 || value_size == 0 || !comparator) {
return NULL;
}
struct internal_map *const init = malloc(sizeof(struct internal_map));
if (!init) {
return NULL;

View File

@@ -54,10 +54,12 @@ struct value_node {
* Initializes a multi-map, which is a collection of key-value pairs, sorted by
* keys.
*
* @param key_size The size of each key in the multi-map.
* @param value_size The size of each value in the multi-map.
* @param key_comparator The key comparator function.
* @param value_comparator The value comparator function.
* @param key_size The size of each key in the multi-map. Must be
* positive.
* @param value_size The size of each value in the multi-map. Must be
* positive.
* @param key_comparator The key comparator function. Must not be NULL.
* @param value_comparator The value comparator function. Must not be NULL.
*
* @return The newly-initialized multi-map, or NULL if memory allocation error.
*/
@@ -68,6 +70,10 @@ multimap multimap_init(const size_t key_size,
int (*const value_comparator)(const void *const,
const void *const))
{
if (key_size == 0 || value_size == 0
|| !key_comparator || !value_comparator) {
return NULL;
}
struct internal_multimap *const init =
malloc(sizeof(struct internal_multimap));
if (!init) {

View File

@@ -45,8 +45,10 @@ struct node {
* Initializes a multi-set, which is a collection of key-value pairs, sorted by
* keys, keys are unique
*
* @param key_size The size of each element in the multi-set.
* @param comparator The comparator function used for key ordering.
* @param key_size The size of each element in the multi-set. Must be
* positive.
* @param comparator The comparator function used for key ordering. Must not be
* NULL.
*
* @return The newly-initialized multi-set, or NULL if memory allocation error.
*/
@@ -54,6 +56,9 @@ multiset multiset_init(const size_t key_size,
int (*const comparator)(const void *const,
const void *const))
{
if (key_size == 0 || !comparator) {
return NULL;
}
struct internal_multiset *const init =
malloc(sizeof(struct internal_multiset));
if (!init) {

View File

@@ -36,8 +36,9 @@ struct internal_priority_queue {
* Initializes a priority queue, which adapts a container to provide priority
* queue. Adapts the vector container.
*
* @param data_size The size of the data in the priority queue.
* @param comparator The priority comparator function.
* @param data_size The size of the data in the priority queue. Must be
* positive.
* @param comparator The priority comparator function. Must not be NULL.
*
* @return The newly-initialized priority queue, or NULL if memory allocation
* error.
@@ -46,6 +47,9 @@ priority_queue priority_queue_init(const size_t data_size,
int (*comparator)(const void *const,
const void *const))
{
if (data_size == 0 || !comparator) {
return NULL;
}
struct internal_priority_queue *const init =
malloc(sizeof(struct internal_priority_queue));
if (!init) {

View File

@@ -35,12 +35,15 @@ struct internal_queue {
* Initializes a queue, which adapts a container to provide queue
* (first-in first-out). Adapts the deque container.
*
* @param data_size The size of each element.
* @param data_size The size of each element. Must be positive.
*
* @return The newly-initialized queue, or NULL if out of memory.
* @return The newly-initialized queue, or NULL if memory allocation error.
*/
queue queue_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_queue *const init = malloc(sizeof(struct internal_queue));
if (!init) {
return NULL;

View File

@@ -43,14 +43,18 @@ struct node {
/**
* Initializes a set, which is a collection of unique keys, sorted by keys.
*
* @param key_size The size of each element in the set.
* @param comparator The comparator function used for key ordering.
* @param key_size The size of each element in the set. Must be positive.
* @param comparator The comparator function used for key ordering. Must not be
* NULL.
*
* @return The newly-initialized set, or NULL if memory allocation error.
*/
set set_init(const size_t key_size,
int (*const comparator)(const void *const, const void *const))
{
if (key_size == 0 || !comparator) {
return NULL;
}
struct internal_set *const init = malloc(sizeof(struct internal_set));
if (!init) {
return NULL;

View File

@@ -32,12 +32,16 @@ struct internal_stack {
* Initializes a stack, which adapts a container to provide stack
* (last-in first-out). Adapts the deque container.
*
* @param data_size The size of each data element in the stack.
* @param data_size The size of each data element in the stack. Must be
* positive.
*
* @return The newly-initialized stack, or NULL if could not allocate memory.
* @return The newly-initialized stack, or NULL if memory allocation error.
*/
stack stack_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_stack *const init = malloc(sizeof(struct internal_stack));
if (!init) {
return NULL;

View File

@@ -50,10 +50,14 @@ struct node {
* Initializes an unordered map, which is a collection of key-value pairs,
* hashed by keys, keys are unique
*
* @param key_size The size of each key in the unordered map.
* @param value_size The size of each value in the unordered map.
* @param key_size The size of each key in the unordered map. Must be
* positive.
* @param value_size The size of each value in the unordered map. Must be
* positive.
* @param hash The hash function which computes the hash from the key.
* @param comparator The comparator function which compares two keys.
* Must not be NULL.
* @param comparator The comparator function which compares two keys. Must not
* be NULL.
*
* @return The newly-initialized unordered map, or NULL if memory allocation
* error.
@@ -64,6 +68,9 @@ unordered_map unordered_map_init(const size_t key_size,
int (*comparator)(const void *const,
const void *const))
{
if (key_size == 0 || value_size == 0 || !hash || !comparator) {
return NULL;
}
struct internal_unordered_map *const init =
malloc(sizeof(struct internal_unordered_map));
if (!init) {

View File

@@ -54,11 +54,16 @@ struct node {
* Initializes an unordered multi-map, which is a collection of key-value pairs,
* hashed by keys
*
* @param key_size The size of each key in the unordered multi-map.
* @param key_size The size of each key in the unordered multi-map. Must
* be positive.
* @param value_size The size of each value in the unordered multi-map.
* Must be positive.
* @param hash The hash function which computes the hash from key.
* Must not be NULL.
* @param key_comparator The comparator function which compares two keys.
* Must not be NULL.
* @param value_comparator The comparator function which compares two values.
* Must not be NULL.
*
* @return The newly-initialized unordered multi-map, or NULL if memory
* allocation error.
@@ -72,6 +77,10 @@ unordered_multimap_init(const size_t key_size,
int (*value_comparator)(const void *const,
const void *const))
{
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));
if (!init) {

View File

@@ -50,9 +50,12 @@ struct node {
* Initializes an unordered multi-set, which is a collection of keys, hashed by
* keys.
*
* @param key_size The size of each key in the unordered multi-set.
* @param key_size The size of each key in the unordered multi-set. Must be
* positive.
* @param hash The hash function which computes the hash from the key.
* @param comparator The comparator function which compares two keys.
* Must not be NULL.
* @param comparator The comparator function which compares two keys. Must not
* be NULL.
*
* @return The newly-initialized unordered multi-set, or NULL if memory
* allocation error.
@@ -62,6 +65,9 @@ unordered_multiset_init(const size_t key_size,
unsigned long (*hash)(const void *const),
int (*comparator)(const void *const, const void *const))
{
if (key_size == 0 || !hash || !comparator) {
return NULL;
}
struct internal_unordered_multiset *const init =
malloc(sizeof(struct internal_unordered_multiset));
if (!init) {

View File

@@ -48,9 +48,12 @@ struct node {
* Initializes an unordered set, which is a collection of unique keys, hashed by
* keys.
*
* @param key_size The size of each key in the unordered set.
* @param key_size The size of each key in the unordered set. Must be
* positive.
* @param hash The hash function which computes the hash from the key.
* @param comparator The comparator function which compares two keys.
* Must not be NULL.
* @param comparator The comparator function which compares two keys. Must not
* be NULL.
*
* @return The newly-initialized unordered set, or NULL if memory allocation
* error.
@@ -60,6 +63,9 @@ unordered_set unordered_set_init(const size_t key_size,
int (*comparator)(const void *const,
const void *const))
{
if (key_size == 0 || !hash || !comparator) {
return NULL;
}
struct internal_unordered_set *const init =
malloc(sizeof(struct internal_unordered_set));
if (!init) {

View File

@@ -29,30 +29,33 @@ static const int START_SPACE = 8;
static const double RESIZE_RATIO = 1.5;
struct internal_vector {
size_t data_size;
int offset;
int space;
void *storage;
size_t bytes_per_item;
int item_count;
int item_capacity;
void *data;
};
/**
* Initializes a vector, which is a dynamic contiguous array.
*
* @param data_size The size of each element in the vector.
* @param data_size The size of each element in the vector. Must be positive.
*
* @return The newly-initialized vector, or NULL if memory allocation error.
*/
vector vector_init(const size_t data_size)
{
if (data_size == 0) {
return NULL;
}
struct internal_vector *const init = malloc(sizeof(struct internal_vector));
if (!init) {
return NULL;
}
init->data_size = data_size;
init->offset = 0;
init->space = START_SPACE;
init->storage = malloc(init->space * init->data_size);
if (!init->storage) {
init->bytes_per_item = data_size;
init->item_count = 0;
init->item_capacity = START_SPACE;
init->data = malloc(init->item_capacity * init->bytes_per_item);
if (!init->data) {
free(init);
return NULL;
}
@@ -68,7 +71,7 @@ vector vector_init(const size_t data_size)
*/
int vector_size(vector me)
{
return me->offset;
return me->item_count;
}
/**
@@ -88,14 +91,14 @@ bool vector_is_empty(vector me)
*/
static int vector_set_space(vector me, const int size)
{
void *const temp = realloc(me->storage, size * me->data_size);
void *const temp = realloc(me->data, size * me->bytes_per_item);
if (!temp) {
return -ENOMEM;
}
me->storage = temp;
me->space = size;
if (me->space < me->offset) {
me->offset = me->space;
me->data = temp;
me->item_capacity = size;
if (me->item_capacity < me->item_count) {
me->item_count = me->item_capacity;
}
return 0;
}
@@ -112,7 +115,7 @@ static int vector_set_space(vector me, const int size)
*/
int vector_reserve(vector me, int size)
{
if (me->space >= size) {
if (me->item_capacity >= size) {
return 0;
}
return vector_set_space(me, size);
@@ -128,7 +131,7 @@ int vector_reserve(vector me, int size)
*/
int vector_trim(vector me)
{
return vector_set_space(me, me->offset);
return vector_set_space(me, me->item_count);
}
/**
@@ -139,7 +142,7 @@ int vector_trim(vector me)
*/
void vector_copy_to_array(void *const arr, vector me)
{
memcpy(arr, me->storage, me->offset * me->data_size);
memcpy(arr, me->data, me->item_count * me->bytes_per_item);
}
/**
@@ -154,7 +157,7 @@ void vector_copy_to_array(void *const arr, vector me)
*/
void *vector_get_data(vector me)
{
return me->storage;
return me->data;
}
/**
@@ -184,25 +187,25 @@ int vector_add_first(vector me, void *const data)
*/
int vector_add_at(vector me, const int index, void *const data)
{
if (index < 0 || index > me->offset) {
if (index < 0 || index > me->item_count) {
return -EINVAL;
}
if (me->offset + 1 >= me->space) {
const int new_space = (int) (me->space * RESIZE_RATIO);
void *const temp = realloc(me->storage, new_space * me->data_size);
if (me->item_count + 1 >= me->item_capacity) {
const int new_space = (int) (me->item_capacity * RESIZE_RATIO);
void *const temp = realloc(me->data, new_space * me->bytes_per_item);
if (!temp) {
return -ENOMEM;
}
me->storage = temp;
me->space = new_space;
me->data = temp;
me->item_capacity = new_space;
}
if (index != me->offset) {
memmove(me->storage + (index + 1) * me->data_size,
me->storage + index * me->data_size,
(me->offset - index) * me->data_size);
if (index != me->item_count) {
memmove(me->data + (index + 1) * me->bytes_per_item,
me->data + index * me->bytes_per_item,
(me->item_count - index) * me->bytes_per_item);
}
memcpy(me->storage + index * me->data_size, data, me->data_size);
me->offset++;
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
me->item_count++;
return 0;
}
@@ -217,7 +220,7 @@ int vector_add_at(vector me, const int index, void *const data)
*/
int vector_add_last(vector me, void *const data)
{
return vector_add_at(me, me->offset, data);
return vector_add_at(me, me->item_count, data);
}
/*
@@ -225,7 +228,7 @@ int vector_add_last(vector me, void *const data)
*/
static bool vector_is_illegal_input(vector me, const int index)
{
return index < 0 || index >= me->offset || me->offset == 0;
return index < 0 || index >= me->item_count || me->item_count == 0;
}
/**
@@ -255,10 +258,10 @@ int vector_remove_at(vector me, const int index)
if (vector_is_illegal_input(me, index)) {
return -EINVAL;
}
me->offset--;
memmove(me->storage + index * me->data_size,
me->storage + (index + 1) * me->data_size,
(me->offset - index) * me->data_size);
me->item_count--;
memmove(me->data + index * me->bytes_per_item,
me->data + (index + 1) * me->bytes_per_item,
(me->item_count - index) * me->bytes_per_item);
return 0;
}
@@ -272,10 +275,10 @@ int vector_remove_at(vector me, const int index)
*/
int vector_remove_last(vector me)
{
if (me->offset == 0) {
if (me->item_count == 0) {
return -EINVAL;
}
me->offset--;
me->item_count--;
return 0;
}
@@ -307,7 +310,7 @@ int vector_set_at(vector me, const int index, void *const data)
if (vector_is_illegal_input(me, index)) {
return -EINVAL;
}
memcpy(me->storage + index * me->data_size, data, me->data_size);
memcpy(me->data + index * me->bytes_per_item, data, me->bytes_per_item);
return 0;
}
@@ -321,7 +324,7 @@ int vector_set_at(vector me, const int index, void *const data)
*/
int vector_set_last(vector me, void *const data)
{
return vector_set_at(me, me->offset - 1, data);
return vector_set_at(me, me->item_count - 1, data);
}
/**
@@ -353,7 +356,7 @@ int vector_get_at(void *const data, vector me, const int index)
if (vector_is_illegal_input(me, index)) {
return -EINVAL;
}
memcpy(data, me->storage + index * me->data_size, me->data_size);
memcpy(data, me->data + index * me->bytes_per_item, me->bytes_per_item);
return 0;
}
@@ -368,7 +371,7 @@ int vector_get_at(void *const data, vector me, const int index)
*/
int vector_get_last(void *const data, vector me)
{
return vector_get_at(data, me, me->offset - 1);
return vector_get_at(data, me, me->item_count - 1);
}
/**
@@ -382,7 +385,7 @@ int vector_get_last(void *const data, vector me)
int vector_clear(vector me)
{
const int ret = vector_set_space(me, START_SPACE);
me->offset = 0;
me->item_count = 0;
return ret;
}
@@ -395,8 +398,8 @@ int vector_clear(vector me)
*/
vector vector_destroy(vector me)
{
free(me->storage);
me->storage = NULL;
free(me->data);
me->data = NULL;
free(me);
return NULL;
}