mirror of
https://github.com/bkthomps/Containers.git
synced 2025-11-16 04:24:47 +00:00
10
containers.h
10
containers.h
@@ -303,19 +303,19 @@ unordered_multimap unordered_multimap_destroy(unordered_multimap me);
|
||||
/**
|
||||
* The array data structure, which is a static contiguous array.
|
||||
*/
|
||||
typedef struct internal_array *array;
|
||||
typedef char *array;
|
||||
|
||||
/* Starting */
|
||||
array array_init(int element_count, size_t data_size);
|
||||
array array_init(size_t element_count, size_t data_size);
|
||||
|
||||
/* Utility */
|
||||
int array_size(array me);
|
||||
size_t array_size(array me);
|
||||
void array_copy_to_array(void *arr, array me);
|
||||
void *array_get_data(array me);
|
||||
|
||||
/* Accessing */
|
||||
int array_set(array me, int index, void *data);
|
||||
int array_get(void *data, array me, int index);
|
||||
int array_set(array me, size_t index, void *data);
|
||||
int array_get(void *data, array me, size_t index);
|
||||
|
||||
/* Ending */
|
||||
array array_destroy(array me);
|
||||
|
||||
89
src/array.c
89
src/array.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019 Bailey Thompson
|
||||
* Copyright (c) 2017-2020 Bailey Thompson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,14 +24,14 @@
|
||||
#include <errno.h>
|
||||
#include "include/array.h"
|
||||
|
||||
struct internal_array {
|
||||
size_t bytes_per_item;
|
||||
int item_count;
|
||||
void *data;
|
||||
};
|
||||
const size_t book_keeping_size = sizeof(size_t);
|
||||
const size_t arr_size_offset = 0;
|
||||
const size_t data_size_offset = sizeof(size_t);
|
||||
const size_t data_ptr_offset = 2 * sizeof(size_t);
|
||||
|
||||
/**
|
||||
* Initializes an array.
|
||||
* Initializes an array. If the multiplication of the element count and the
|
||||
* data size overflows, it is undefined behavior.
|
||||
*
|
||||
* @param element_count the number of elements in the array; must not be
|
||||
* negative
|
||||
@@ -41,27 +41,19 @@ struct internal_array {
|
||||
* initialized due to either invalid input arguments or memory
|
||||
* allocation error
|
||||
*/
|
||||
array array_init(const int element_count, const size_t data_size)
|
||||
array array_init(const size_t element_count, const size_t data_size)
|
||||
{
|
||||
struct internal_array *init;
|
||||
if (element_count < 0 || data_size == 0) {
|
||||
char *init;
|
||||
if (data_size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
init = malloc(sizeof(struct internal_array));
|
||||
init = malloc(data_ptr_offset + element_count * data_size);
|
||||
if (!init) {
|
||||
return NULL;
|
||||
}
|
||||
init->bytes_per_item = data_size;
|
||||
init->item_count = element_count;
|
||||
if (init->item_count == 0) {
|
||||
init->data = NULL;
|
||||
return init;
|
||||
}
|
||||
init->data = calloc((size_t) element_count, data_size);
|
||||
if (!init->data) {
|
||||
free(init);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(init + arr_size_offset, &element_count, book_keeping_size);
|
||||
memcpy(init + data_size_offset, &data_size, book_keeping_size);
|
||||
memset(init + data_ptr_offset, 0, element_count * data_size);
|
||||
return init;
|
||||
}
|
||||
|
||||
@@ -72,9 +64,11 @@ array array_init(const int element_count, const size_t data_size)
|
||||
*
|
||||
* @return the size of the array
|
||||
*/
|
||||
int array_size(array me)
|
||||
size_t array_size(array me)
|
||||
{
|
||||
return me->item_count;
|
||||
size_t size;
|
||||
memcpy(&size, me + arr_size_offset, book_keeping_size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,10 +84,11 @@ int array_size(array me)
|
||||
*/
|
||||
void array_copy_to_array(void *const arr, array me)
|
||||
{
|
||||
if (me->item_count == 0) {
|
||||
return;
|
||||
}
|
||||
memcpy(arr, me->data, me->item_count * me->bytes_per_item);
|
||||
size_t element_count;
|
||||
size_t data_size;
|
||||
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
|
||||
memcpy(&data_size, me + data_size_offset, book_keeping_size);
|
||||
memcpy(arr, me + data_ptr_offset, element_count * data_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,15 +108,12 @@ void array_copy_to_array(void *const arr, array me)
|
||||
*/
|
||||
void *array_get_data(array me)
|
||||
{
|
||||
return me->data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines if the input is illegal.
|
||||
*/
|
||||
static int array_is_illegal_input(array me, const int index)
|
||||
{
|
||||
return index < 0 || index >= me->item_count;
|
||||
size_t element_count;
|
||||
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
|
||||
if (element_count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return me + data_ptr_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,13 +130,16 @@ static int array_is_illegal_input(array me, const int index)
|
||||
* @return 0 if no error
|
||||
* @return -EINVAL if invalid argument
|
||||
*/
|
||||
int array_set(array me, const int index, void *const data)
|
||||
int array_set(array me, const size_t index, void *const data)
|
||||
{
|
||||
if (array_is_illegal_input(me, index)) {
|
||||
size_t element_count;
|
||||
size_t data_size;
|
||||
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
|
||||
if (index >= element_count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy((char *) me->data + index * me->bytes_per_item, data,
|
||||
me->bytes_per_item);
|
||||
memcpy(&data_size, me + data_size_offset, book_keeping_size);
|
||||
memcpy(me + data_ptr_offset + index * data_size, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,13 +158,16 @@ int array_set(array me, const int index, void *const data)
|
||||
* @return 0 if no error
|
||||
* @return -EINVAL if invalid argument
|
||||
*/
|
||||
int array_get(void *const data, array me, const int index)
|
||||
int array_get(void *const data, array me, const size_t index)
|
||||
{
|
||||
if (array_is_illegal_input(me, index)) {
|
||||
size_t element_count;
|
||||
size_t data_size;
|
||||
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
|
||||
if (index >= element_count) {
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(data, (char *) me->data + index * me->bytes_per_item,
|
||||
me->bytes_per_item);
|
||||
memcpy(&data_size, me + data_size_offset, book_keeping_size);
|
||||
memcpy(data, me + data_ptr_offset + index * data_size, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,7 +181,6 @@ int array_get(void *const data, array me, const int index)
|
||||
*/
|
||||
array array_destroy(array me)
|
||||
{
|
||||
free(me->data);
|
||||
free(me);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019 Bailey Thompson
|
||||
* Copyright (c) 2017-2020 Bailey Thompson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -28,19 +28,19 @@
|
||||
/**
|
||||
* The array data structure, which is a static contiguous array.
|
||||
*/
|
||||
typedef struct internal_array *array;
|
||||
typedef char *array;
|
||||
|
||||
/* Starting */
|
||||
array array_init(int element_count, size_t data_size);
|
||||
array array_init(size_t element_count, size_t data_size);
|
||||
|
||||
/* Utility */
|
||||
int array_size(array me);
|
||||
size_t array_size(array me);
|
||||
void array_copy_to_array(void *arr, array me);
|
||||
void *array_get_data(array me);
|
||||
|
||||
/* Accessing */
|
||||
int array_set(array me, int index, void *data);
|
||||
int array_get(void *data, array me, int index);
|
||||
int array_set(array me, size_t index, void *data);
|
||||
int array_get(void *data, array me, size_t index);
|
||||
|
||||
/* Ending */
|
||||
array array_destroy(array me);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
static void test_invalid_init(void)
|
||||
{
|
||||
assert(!array_init(-1, sizeof(int)));
|
||||
assert(!array_init(1, 0));
|
||||
}
|
||||
|
||||
@@ -83,8 +82,6 @@ static void test_init_out_of_memory(void)
|
||||
{
|
||||
fail_malloc = 1;
|
||||
assert(!array_init(10, sizeof(int)));
|
||||
fail_calloc = 1;
|
||||
assert(!array_init(10, sizeof(int)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user