Const-correctness for vector and implemented some more functions.
This commit is contained in:
parent
0064de87d6
commit
778e7494ef
|
@ -14,8 +14,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO: CONST STATEMENTS IN FUNCTION DEFINITIONS AND DECLARATIONS. */
|
||||
|
||||
/* This file contains the function implementations for a vector. */
|
||||
/* Include guard + includes. */
|
||||
#ifndef VECTOR_C
|
||||
|
@ -26,7 +24,7 @@
|
|||
/* Function implementations. */
|
||||
|
||||
/* This function initializes a new empty vector, returns NULL on failure. */
|
||||
vector_t* initialize_vector() {
|
||||
static inline vector_t* initialize_vector() {
|
||||
/* Local variables. */
|
||||
vector_t *vector;
|
||||
|
||||
|
@ -61,7 +59,7 @@ vector_t* initialize_vector() {
|
|||
/* Note that if a failure code is returned, then the original vector wasn't changed whatsoever. */
|
||||
/* Returns SUCCESS_CODE_VECTOR_C on success and FAILURE_CODE_VECTOR_C on failure. */
|
||||
/* Undefined behavior for NULL vectors. */
|
||||
int append_to_vector(const vector_t* const vector, const void* const data) {
|
||||
static inline int append_to_vector(const vector_t* const vector, const void* const data) {
|
||||
/* Check if the vector has enough space. */
|
||||
if (check_size_change_vector(vector, THRESHOLD_GROW_VECTOR)) {
|
||||
/* Grow the vector. */
|
||||
|
@ -82,7 +80,7 @@ int append_to_vector(const vector_t* const vector, const void* const data) {
|
|||
/* Note that if a failure code is returned, then the original vector wasn't changed whatsoever. */
|
||||
/* Returns SUCCESS_CODE_VECTOR_C on success and FAILURE_CODE_VECTOR_C on failure. */
|
||||
/* Undefined behavior for NULL vectors. */
|
||||
int prepend_to_vector(const vector_t* const vector, const void* const data) {
|
||||
static inline int prepend_to_vector(const vector_t* const vector, const void* const data) {
|
||||
/* Check if the vector has enough space. */
|
||||
if (check_size_change_vector(vector, THRESHOLD_GROW_VECTOR)) {
|
||||
/* Grow the vector. */
|
||||
|
@ -106,10 +104,10 @@ int prepend_to_vector(const vector_t* const vector, const void* const data) {
|
|||
/* Returns NULL on error and sets error to the error code. */
|
||||
/* NULL can also be a perfectly fine value to store and retrieve. */
|
||||
/* Undefined behavior for NULL vectors. */
|
||||
static inline void* read_from_vector(vector_t *vector, const size_t index, int *error) {
|
||||
/* Check if read is within bounds. */
|
||||
static inline void* read_from_vector(const vector_t* const vector, const size_t index, const int *error) {
|
||||
/* Check if read index is within bounds. */
|
||||
if (vector->last_element < index) {
|
||||
/* Read out of bounds. */
|
||||
/* Index out of bounds. */
|
||||
*error = INDEX_NOT_FOUND_CODE_VECTOR_C;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -118,11 +116,35 @@ static inline void* read_from_vector(vector_t *vector, const size_t index, int *
|
|||
return (vector->array + (index * vector->element_size));
|
||||
}
|
||||
|
||||
static inline int write_to_vector(vector_t *vector, const size_t index, void *data) {}
|
||||
/* This function reads from the vector at the given index. */
|
||||
/* Returns NULL on error and sets error to the error code. */
|
||||
/* NULL can also be a perfectly fine value to store and retrieve. */
|
||||
/* Undefined behavior for NULL vectors. */
|
||||
/* Disallows writes beyond last_index + 1. */
|
||||
static inline int write_to_vector(const vector_t* const vector, const size_t index, const void* const data) {
|
||||
/* Check if write index is within bounds. */
|
||||
if ((vector->length <= index) || ((vector->last_element + 1L) < index))
|
||||
return INDEX_NOT_FOUND_CODE_VECTOR_C;
|
||||
|
||||
/* Check if the write is over-writing or not. */
|
||||
/* Check for an append call. */
|
||||
if (index == (vector->last_element + 1L))
|
||||
return append_to_vector(vector, data);
|
||||
/* Overwriting call! */
|
||||
*(vector->array + (index * vector->element_size)) = data;
|
||||
vector->last_element = vector->last_element + 1L;
|
||||
|
||||
/* Check if the vector needs to be grown. */
|
||||
if (check_size_change_vector(vector, THRESHOLD_GROW_VECTOR_C))
|
||||
return (grow_vector(vector)) ? SUCCESS_CODE_VECTOR_C : WRITE_SUCCESS_VECTOR_GROW_FAIL_VECTOR_C;
|
||||
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_VECTOR_C;
|
||||
}
|
||||
|
||||
/* Internal functions. */
|
||||
/* This function checks if the vector needs to be grown, shrunk or kept as is. */
|
||||
inline int check_size_change_vector(vector_t *vector, const double threshold) {
|
||||
inline int check_size_change_vector(const vector_t* const vector, const double threshold) {
|
||||
/* Calculate the threshold and length. */
|
||||
size_t current_size = vector->last_element;
|
||||
size_t current_threshold = (size_t)((vector->length) * threshold);
|
||||
|
@ -138,7 +160,7 @@ inline int check_size_change_vector(vector_t *vector, const double threshold) {
|
|||
|
||||
/* This function grows a vector, doesn't change it on failure. */
|
||||
/* Returns SUCCESS_CODE_VECTOR_C on success and FAILURE_CODE_VECTOR_C on failure. */
|
||||
inline int grow_vector(vector_t *vector) {
|
||||
inline int grow_vector(const vector_t* const vector) {
|
||||
/* Local variables. */
|
||||
size_t size;
|
||||
void* array;
|
||||
|
@ -166,7 +188,7 @@ inline int grow_vector(vector_t *vector) {
|
|||
/* This function shrinks a vector, doesn't change it on failure. */
|
||||
/* Note that if the vector cannot be shrunk according to the growth factor, data loss may occure. */
|
||||
/* Returns SUCCESS_CODE_VECTOR_C on success and FAILURE_CODE_VECTOR_C on failure. */
|
||||
inline int shrink_vector(vector_t *vector) {
|
||||
inline int shrink_vector(const vector_t* const vector) {
|
||||
/* Local variables. */
|
||||
size_t size;
|
||||
void* array;
|
||||
|
@ -193,7 +215,7 @@ inline int shrink_vector(vector_t *vector) {
|
|||
|
||||
/* This function compacts a vector by pushing all the NULLs to the end. */
|
||||
/* Try to avoid calling it unless needed as it has an O(n^2) runtime complexity. */
|
||||
inline void compact_vector(vector_t *vector) {
|
||||
inline void compact_vector(const vector_t* const vector) {
|
||||
/* Loop and push. */
|
||||
void *pointer = vector->array;
|
||||
size_t i, j;
|
||||
|
@ -209,7 +231,7 @@ inline void compact_vector(vector_t *vector) {
|
|||
}
|
||||
|
||||
/* This function creates a "gap" (of NULL) at the start of the vector, doesn't do any sanity checking! */
|
||||
inline void push_vector(vector_t *vector, size_t gap_length) {
|
||||
inline void push_vector(const vector_t* const vector, const size_t gap_length) {
|
||||
/* Local variables. */
|
||||
size_t i;
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO: CONST STATEMENTS IN FUNCTION DEFINITIONS AND DECLARATIONS. */
|
||||
|
||||
/* This header defines a double-linked-list and related functions. */
|
||||
/* Use the double nodes. */
|
||||
#include <stdlib.h> /* Used in allocations and deallocations. */
|
||||
|
@ -45,6 +43,8 @@
|
|||
#define CODE_KEEP_VECTOR_C 0
|
||||
/* Check code for shrinking the vector. */
|
||||
#define CODE_SHRINK_VECTOR_C -1
|
||||
/* Error code for when write succeeds and vector grow fails. */
|
||||
#define WRITE_SUCCESS_VECTOR_GROW_FAIL_VECTOR_C 3
|
||||
/* Used to calculate the whole when checking size-changes. */
|
||||
#define THRESHOLD_WHOLE_VECTOR_C 1.0
|
||||
/* The threshold used to grow the vector. */
|
||||
|
@ -54,6 +54,7 @@
|
|||
/* Define the initial index for the last element. */
|
||||
#define LAST_ELEMENT_EMPTY_INDEX_VECTOR_C -1
|
||||
|
||||
|
||||
/* The vector's struct. */
|
||||
typedef struct vector {
|
||||
/* Stores the current power used to compute the length. */
|
||||
|
@ -70,15 +71,15 @@ typedef struct vector {
|
|||
|
||||
/* Function declarations. */
|
||||
/* This function initializes a new empty vector. */
|
||||
vector_t* initialize_vector();
|
||||
static inline vector_t* initialize_vector();
|
||||
/* This function appends to the vector. */
|
||||
int append_to_vector(const vector_t* const vector, const void* const data);
|
||||
static inline int append_to_vector(const vector_t* const vector, const void* const data);
|
||||
/* This function prepends to the vector. */
|
||||
int prepend_to_vector(const vector_t* const vector, const void* const data);
|
||||
static inline int prepend_to_vector(const vector_t* const vector, const void* const data);
|
||||
/* This function reads from the vector at the given index. */
|
||||
static inline void* read_from_vector(const vector_t const *vector, const size_t index, int *error);
|
||||
static inline void* read_from_vector(const vector_t const *vector, const size_t index, const int *error);
|
||||
/* This function overwrites the value at the given index. */
|
||||
static inline int write_to_vector(vector_t *vector, const size_t index, void *data);
|
||||
static inline int write_to_vector(const vector_t* const vector, const size_t index, const void* const data);
|
||||
/* This function frees the data at the given index (using the given free function, if NULL doesn't change it!) and marks the cell there as NULL. */
|
||||
static inline int delete_from_vector(vector_t *vector, const size_t index, void (*free_function)(const void*));
|
||||
/* This function serializes the vector into an array! */
|
||||
|
@ -87,14 +88,14 @@ static inline void* serialize_vector(size_t *length);
|
|||
static inline int copy_vector(vector_t *source, vector_t *destination, void (*copy_function)(const void*, const void*))
|
||||
/* Internal functions. */
|
||||
/* This function checks if the vector needs to be grown or shrunk. */
|
||||
inline int check_size_change_vector(vector_t *vector, const double threshold);
|
||||
inline int check_size_change_vector(const vector_t* const vector, const double threshold);
|
||||
/* This function grows the vector, doesn't change the vector on failure. */
|
||||
inline int grow_vector(vector_t *vector);
|
||||
inline int grow_vector(const vector_t* const vector);
|
||||
/* This function shrinks the vector, doesn't change the vector on failure. */
|
||||
inline int shrink_vector(vector_t *vector);
|
||||
inline int shrink_vector(const vector_t* const vector);
|
||||
/* This function compacts a vector by pushing all the NULLs to the end. */
|
||||
inline void compact_vector(vector_t *vector);
|
||||
inline void compact_vector(const vector_t* const vector);
|
||||
/* This function creates a "gap" at the start of the vector. */
|
||||
inline void push_vector(vector_t *vector, size_t gap_length);
|
||||
inline void push_vector(const vector_t* const vector, const size_t gap_length);
|
||||
|
||||
#endif /* VECTOR_H */
|
||||
|
|
Loading…
Reference in New Issue