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