API: Cutting my losses and having singular types and files for the 4
types { char, int, float, string } and can come back later to make it
one type to call.
GITIGNORE: Added tests and Makefile to cleanup fuzzyfinder but dont need
them pushed either as I have enough testing done.
This commit is contained in:
@@ -3,3 +3,6 @@ build/
|
||||
tests/cache/
|
||||
tests/bin/
|
||||
coverage.html
|
||||
|
||||
tests
|
||||
Makefile
|
||||
|
||||
+6
-7
@@ -5,13 +5,12 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_library(libvec STATIC
|
||||
src/libvec.c
|
||||
src/lib/char/char.c
|
||||
src/lib/utils/utils.c
|
||||
src/char.c
|
||||
src/int.c
|
||||
src/utils.c
|
||||
src/float.c
|
||||
# src/string.c
|
||||
# Add your other types here as you implement them:
|
||||
# src/lib/float/float.c
|
||||
# src/lib/int/int.c
|
||||
# src/lib/string/string.c
|
||||
)
|
||||
|
||||
target_include_directories(libvec
|
||||
@@ -22,7 +21,7 @@ target_include_directories(libvec
|
||||
# PUBLIC: Consumers (and test_runner) are granted access ONLY to include/
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lib # Turn back to private when ready
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/src/lib # Turn back to private when ready
|
||||
)
|
||||
|
||||
add_executable(libvec_bin src/main.c)
|
||||
|
||||
@@ -14,7 +14,7 @@ CFLAGS := -std=c23 -Wall -Wextra -Wpedantic -Wshadow \
|
||||
-Wconversion -Wsign-conversion \
|
||||
-g -O1 -fno-omit-frame-pointer
|
||||
SAN_FLAGS := -fsanitize=address,undefined
|
||||
INCLUDES := -Iinclude -Isrc/lib -Isrc/lib/char -Isrc/lib/utils
|
||||
INCLUDES := -Iinclude -Isrc/lib -Isrc/lib/int -Isrc/lib/utils
|
||||
|
||||
ASAN_ENV := ASAN_OPTIONS="allocator_may_return_null=1:detect_stack_use_after_return=1" \
|
||||
UBSAN_OPTIONS="halt_on_error=1:print_stacktrace=1"
|
||||
@@ -31,7 +31,7 @@ CPPCHECK_FLAGS := --enable=all \
|
||||
$(INCLUDES)
|
||||
|
||||
# Sources & Build Directories
|
||||
SRCS := src/lib/char/char.c src/lib/utils/utils.c
|
||||
SRCS := src/lib/int/int.c src/lib/utils/utils.c
|
||||
TEST_SRC := tests/test_learn.c
|
||||
FUZZ_SRC := tests/fuzz_char.c
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef LIBVEC_H
|
||||
#define LIBVEC_H
|
||||
|
||||
// Add code here
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CHAR_H
|
||||
#define CHAR_H
|
||||
|
||||
#include <utils/utils.h>
|
||||
#include <libvec/utils.h>
|
||||
|
||||
// Will add DOCS later
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
#ifndef CHAR_H
|
||||
#define CHAR_H
|
||||
|
||||
#include <libvec/utils.h>
|
||||
|
||||
// Will add DOCS later
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* _internal_arr;
|
||||
size_t _internal_size;
|
||||
size_t _internal_capacity;
|
||||
size_t _internal_max_size;
|
||||
} _VecCharInternal;
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const _VecCharInternal* ptr, err_t* status);
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const char* ptr, err_t* status);
|
||||
|
||||
size_t
|
||||
__origin_override(err_t* status, char* str);
|
||||
|
||||
void
|
||||
_vec_char_print_vec(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
_VecCharInternal
|
||||
_vec_char_cpy(const char* src, const size_t src_size, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_push_back(_VecCharInternal* ptr, const char val, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_pop_back(_VecCharInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_reserve(_VecCharInternal* ptr, const size_t capacity, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_shrink_to_fit(_VecCharInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_swap(_VecCharInternal* ptr_a, _VecCharInternal* ptr_b, err_t* err);
|
||||
|
||||
const char*
|
||||
_vec_char_data(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_size(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_capacity(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_max_size(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_delete(_VecCharInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_char_clear(_VecCharInternal* ptr, err_t* err);
|
||||
|
||||
char*
|
||||
_vec_char_at(const _VecCharInternal* ptr, const size_t idx, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_begin(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_end(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
char
|
||||
_vec_char_front(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
char
|
||||
_vec_char_back(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_char_empty(const _VecCharInternal* ptr, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_erase(_VecCharInternal* ptr, const size_t iter, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_erase(_VecCharInternal* ptr, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_resize(_VecCharInternal* ptr, const size_t size, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_resize(_VecCharInternal* ptr, const size_t size, const char val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_assign(_VecCharInternal* ptr, const _VecCharInternal* iterator,
|
||||
const size_t iter_start, const size_t iter_end, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_assign(_VecCharInternal* ptr, const size_t amount, const char val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const char val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const size_t amount,
|
||||
const char val, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const _VecCharInternal* iterator,
|
||||
const size_t iter, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,117 @@
|
||||
#ifndef INT_H
|
||||
#define INT_H
|
||||
|
||||
#include <libvec/utils.h>
|
||||
|
||||
// Will add DOCS later
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int* _internal_arr;
|
||||
size_t _internal_size;
|
||||
size_t _internal_capacity;
|
||||
size_t _internal_max_size;
|
||||
} _VecIntInternal;
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const _VecIntInternal* ptr, err_t* status);
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const int* ptr, err_t* status);
|
||||
|
||||
size_t
|
||||
__origin_override(err_t* status, char* str);
|
||||
|
||||
void
|
||||
_vec_int_print_vec(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
_VecIntInternal
|
||||
_vec_int_cpy(const int* src, const size_t src_size, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_push_back(_VecIntInternal* ptr, const int val, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_pop_back(_VecIntInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_reserve(_VecIntInternal* ptr, const size_t capacity, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_shrink_to_fit(_VecIntInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_swap(_VecIntInternal* ptr_a, _VecIntInternal* ptr_b, err_t* err);
|
||||
|
||||
const int*
|
||||
_vec_int_data(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_size(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_capacity(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_max_size(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_delete(_VecIntInternal* ptr, err_t* err);
|
||||
|
||||
void
|
||||
_vec_int_clear(_VecIntInternal* ptr, err_t* err);
|
||||
|
||||
int*
|
||||
_vec_int_at(const _VecIntInternal* ptr, const size_t idx, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_begin(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_end(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
int
|
||||
_vec_int_front(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
int
|
||||
_vec_int_back(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
size_t
|
||||
_vec_int_empty(const _VecIntInternal* ptr, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_erase(_VecIntInternal* ptr, const size_t iter, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_erase(_VecIntInternal* ptr, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_resize(_VecIntInternal* ptr, const size_t size, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_resize(_VecIntInternal* ptr, const size_t size, const int val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_assign(_VecIntInternal* ptr, const _VecIntInternal* iterator,
|
||||
const size_t iter_start, const size_t iter_end, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_assign(_VecIntInternal* ptr, const size_t amount, const int val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const size_t iter, const int val,
|
||||
err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const size_t iter, const size_t amount,
|
||||
const int val, err_t* err);
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const _VecIntInternal* iterator,
|
||||
const size_t iter, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err);
|
||||
|
||||
#endif
|
||||
Vendored
BIN
Binary file not shown.
@@ -1,12 +1,11 @@
|
||||
#include "char.h"
|
||||
#include "libvec/char.h"
|
||||
|
||||
#include <libvec/utils.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/utils.h"
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const _VecCharInternal* ptr, err_t* status)
|
||||
{
|
||||
+938
@@ -0,0 +1,938 @@
|
||||
#include <libvec/float.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const _VecCharInternal* ptr, err_t* status)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_VEC_NULL;
|
||||
return ERR_VEC_NULL;
|
||||
}
|
||||
if (ptr->_internal_arr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_BUF_NULL;
|
||||
}
|
||||
|
||||
return status->flags;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const char* ptr, err_t* status)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_BUF_NULL;
|
||||
}
|
||||
return status->flags;
|
||||
}
|
||||
|
||||
size_t
|
||||
__origin_override(err_t* status, char* str)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (status->origin != nullptr)
|
||||
{
|
||||
status->flags |= ERR_ORIGIN_UNALTERABLE;
|
||||
return status->flags;
|
||||
}
|
||||
else if (str == nullptr)
|
||||
{
|
||||
status->flags |= ERR_STR_NULL;
|
||||
return status->flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
status->origin = str;
|
||||
return status->flags;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_print_vec(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
if (__null_check(ptr, err) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < ptr->_internal_size; i++)
|
||||
{
|
||||
printf("%c ", ptr->_internal_arr[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
_VecCharInternal
|
||||
_vec_char_cpy(const char* src, const size_t src_size, err_t* err)
|
||||
{
|
||||
_VecCharInternal self = VEC_INIT;
|
||||
err_t status = ERR_T_INIT;
|
||||
|
||||
size_t null = __null_check(src, err);
|
||||
if (null != 0)
|
||||
{
|
||||
if (null & ERR_ERR_T_NULL)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= status.flags;
|
||||
return self;
|
||||
}
|
||||
if (src_size == 0)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
err->flags |= status.flags;
|
||||
return self;
|
||||
}
|
||||
if (src_size > self._internal_max_size)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return self;
|
||||
}
|
||||
self._internal_arr = malloc(src_size * sizeof(char));
|
||||
if (self._internal_arr == nullptr)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return self;
|
||||
}
|
||||
memcpy(self._internal_arr, src, src_size * sizeof(char));
|
||||
self._internal_size = src_size;
|
||||
self._internal_capacity = src_size;
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_push_back(_VecCharInternal* ptr, const char val, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
char* res;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size + 1 > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((status.flags & ERR_BUF_NULL) != 0)
|
||||
{
|
||||
res = malloc(1 * sizeof(char));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = 1;
|
||||
ptr->_internal_size = 0;
|
||||
}
|
||||
|
||||
else if (ptr->_internal_size + 1 > ptr->_internal_capacity)
|
||||
{
|
||||
size_t dst_cap =
|
||||
(ptr->_internal_capacity / 2) + ptr->_internal_capacity;
|
||||
if (dst_cap == ptr->_internal_capacity)
|
||||
{
|
||||
dst_cap++;
|
||||
}
|
||||
if (dst_cap > ptr->_internal_max_size)
|
||||
{
|
||||
dst_cap = ptr->_internal_max_size;
|
||||
DEBUG(
|
||||
"Capacity cannot be grown any further due "
|
||||
"to hitting max size");
|
||||
}
|
||||
res = realloc(ptr->_internal_arr, dst_cap * sizeof(char));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = dst_cap;
|
||||
}
|
||||
ptr->_internal_arr[ptr->_internal_size] = val;
|
||||
ptr->_internal_size++;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_pop_back(_VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
if (__null_check(ptr, err) != 0)
|
||||
{
|
||||
__origin_override(err, "POP_BACK");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "POP_BACK");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
ptr->_internal_arr[ptr->_internal_size - 1] = 0;
|
||||
ptr->_internal_size--;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_reserve(_VecCharInternal* ptr, const size_t capacity, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ptr->_internal_max_size < capacity)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
if (capacity == 0)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
char* res = realloc(ptr->_internal_arr, capacity * sizeof(char));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = capacity;
|
||||
if (ptr->_internal_size > capacity)
|
||||
{
|
||||
ptr->_internal_size = capacity;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_shrink_to_fit(_VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "SHRINK_TO_FIT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "SHRINK_TO_FIT");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
_vec_char_reserve(ptr, ptr->_internal_size, err);
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_swap(_VecCharInternal* ptr_a, _VecCharInternal* ptr_b, err_t* err)
|
||||
{
|
||||
err_t status_1 = ERR_T_INIT, status_2 = ERR_T_INIT;
|
||||
if ((__null_check(ptr_a, &status_1) & ERR_VEC_NULL) != 0 ||
|
||||
(__null_check(ptr_b, &status_2) & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "SWAP");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
_VecCharInternal self = *ptr_a;
|
||||
*ptr_a = *ptr_b;
|
||||
*ptr_b = self;
|
||||
return;
|
||||
}
|
||||
|
||||
const char*
|
||||
_vec_char_data(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "DATA");
|
||||
err->flags |= status.flags;
|
||||
return nullptr;
|
||||
}
|
||||
return &ptr->_internal_arr[0];
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_size(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "SIZE");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_capacity(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "CAPACITY");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_capacity;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_max_size(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "MAX_SIZE");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_max_size;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_delete(_VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "DELETE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr != nullptr)
|
||||
{
|
||||
free(ptr->_internal_arr);
|
||||
ptr->_internal_arr = nullptr;
|
||||
}
|
||||
ptr->_internal_size = 0;
|
||||
ptr->_internal_capacity = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_char_clear(_VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "CLEAR");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size > 0)
|
||||
{
|
||||
memset(ptr->_internal_arr, 0, ptr->_internal_size);
|
||||
ptr->_internal_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
_vec_char_at(const _VecCharInternal* ptr, const size_t idx, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "AT");
|
||||
err->flags |= status.flags;
|
||||
return nullptr;
|
||||
}
|
||||
if (idx >= ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "AT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return nullptr;
|
||||
}
|
||||
return &ptr->_internal_arr[idx];
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_begin(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "BEGIN");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_end(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "END");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "END");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return status.flags;
|
||||
}
|
||||
return (size_t)(ptr->_internal_size - 1);
|
||||
}
|
||||
|
||||
char
|
||||
_vec_char_front(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "FRONT");
|
||||
err->flags |= status.flags;
|
||||
return -1;
|
||||
}
|
||||
if (_vec_char_at(ptr, 0, err) == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return 0;
|
||||
}
|
||||
return *_vec_char_at(ptr, 0, err);
|
||||
}
|
||||
|
||||
char
|
||||
_vec_char_back(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "BACK");
|
||||
err->flags |= status.flags;
|
||||
return -1;
|
||||
}
|
||||
if (_vec_char_at(ptr, 0, err) == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return 0;
|
||||
}
|
||||
return *_vec_char_at(ptr, ptr->_internal_size - 1, err);
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_char_empty(const _VecCharInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "EMPTY");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
return ptr->_internal_size;
|
||||
}
|
||||
return status.flags;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_erase(_VecCharInternal* ptr, const size_t iter, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter >= ptr->_internal_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
memmove(&ptr->_internal_arr[iter], &ptr->_internal_arr[iter + 1],
|
||||
(ptr->_internal_size - iter - 1) * sizeof(char));
|
||||
ptr->_internal_arr[ptr->_internal_size - 1] = 0;
|
||||
ptr->_internal_size--;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_erase(_VecCharInternal* ptr, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size < iter_end || iter_end <= iter_start)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
size_t diff = iter_end - iter_start;
|
||||
memmove(&ptr->_internal_arr[iter_start], &ptr->_internal_arr[iter_end],
|
||||
(ptr->_internal_size - iter_end) * sizeof(char));
|
||||
memset(&ptr->_internal_arr[ptr->_internal_size - diff], 0,
|
||||
sizeof(char) * diff);
|
||||
ptr->_internal_size -= diff;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_resize(_VecCharInternal* ptr, const size_t size, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size == size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
else if (size > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->_internal_size == 0)
|
||||
{
|
||||
size_t max = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
_vec_char_reserve(ptr, size, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
ptr->_internal_arr[i] = 0;
|
||||
}
|
||||
ptr->_internal_max_size = max;
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
else if (size > ptr->_internal_capacity)
|
||||
{
|
||||
size_t tmpcp = ptr->_internal_capacity;
|
||||
size_t tmpmx = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
while (size > tmpcp)
|
||||
{
|
||||
tmpcp *= 2;
|
||||
}
|
||||
if (tmpcp > ptr->_internal_max_size)
|
||||
{
|
||||
tmpcp = size;
|
||||
}
|
||||
_vec_char_reserve(ptr, tmpcp, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != tmpcp)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_max_size = tmpmx;
|
||||
}
|
||||
if (size < ptr->_internal_size)
|
||||
{
|
||||
memset(&ptr->_internal_arr[size], 0,
|
||||
ptr->_internal_size - size);
|
||||
}
|
||||
if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
|
||||
{
|
||||
memset(&ptr->_internal_arr[ptr->_internal_size], 0,
|
||||
size - ptr->_internal_size);
|
||||
}
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_resize(_VecCharInternal* ptr, const size_t size, const char val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size == size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
else if (size > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->_internal_size == 0)
|
||||
{
|
||||
size_t max = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
_vec_char_reserve(ptr, size, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
ptr->_internal_arr[i] = val;
|
||||
}
|
||||
ptr->_internal_max_size = max;
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
else if (size > ptr->_internal_capacity)
|
||||
{
|
||||
size_t tmpcp = ptr->_internal_capacity;
|
||||
size_t tmpmx = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
while (size > tmpcp)
|
||||
{
|
||||
tmpcp *= 2;
|
||||
}
|
||||
if (tmpcp > ptr->_internal_max_size)
|
||||
{
|
||||
tmpcp = size;
|
||||
}
|
||||
_vec_char_reserve(ptr, tmpcp, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_max_size = tmpmx;
|
||||
}
|
||||
if (size < ptr->_internal_size)
|
||||
{
|
||||
memset(&ptr->_internal_arr[size], val,
|
||||
ptr->_internal_size - size);
|
||||
}
|
||||
if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
|
||||
{
|
||||
memset(&ptr->_internal_arr[ptr->_internal_size], val,
|
||||
size - ptr->_internal_size);
|
||||
}
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_assign(_VecCharInternal* ptr, const _VecCharInternal* iterator,
|
||||
const size_t iter_start, const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0 ||
|
||||
__null_check(iterator, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr == iterator->_internal_arr)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_DOUBLE_BUF;
|
||||
return;
|
||||
}
|
||||
if (iterator->_internal_size < iter_end || iter_end <= iter_start)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_char_erase(ptr, _vec_char_begin(ptr, &status),
|
||||
_vec_char_end(ptr, &status) + 1, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
_vec_char_reserve(ptr, (iter_end - iter_start), &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter_start; i < iter_end; i++)
|
||||
{
|
||||
char* res = _vec_char_at(iterator, i, &status);
|
||||
if (res == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_char_push_back(ptr, *res, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_assign(_VecCharInternal* ptr, const size_t amount, const char val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (amount == 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
_vec_char_erase(ptr, _vec_char_begin(ptr, &status),
|
||||
_vec_char_end(ptr, &status) + 1, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
_vec_char_reserve(ptr, amount, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < amount; i++)
|
||||
{
|
||||
_vec_char_push_back(ptr, val, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const char val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if ((status.flags & ERR_BUF_NULL) != 0)
|
||||
{
|
||||
char* res = malloc(1 * sizeof(char));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_BUF_NULL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = 1;
|
||||
ptr->_internal_arr[0] = val;
|
||||
ptr->_internal_size = 1;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_max_size < ptr->_internal_size + 1)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
if (iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_char_push_back(ptr, 0, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = ptr->_internal_size - 1; i > iter; i--)
|
||||
{
|
||||
ptr->_internal_arr[i] = ptr->_internal_arr[i - 1];
|
||||
}
|
||||
ptr->_internal_arr[iter] = val;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const size_t amount,
|
||||
const char val, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & (ERR_VEC_NULL | ERR_BUF_NULL)) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
if (amount == 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter; i < iter + amount; i++)
|
||||
{
|
||||
_vec_char_insert(ptr, i, val, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_char_insert(_VecCharInternal* ptr, const _VecCharInternal* iterator,
|
||||
const size_t iter, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
__null_check(iterator, &status);
|
||||
if ((status.flags & (ERR_VEC_NULL | ERR_BUF_NULL)) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter_end <= iter_start || iter_end > iterator->_internal_size ||
|
||||
iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr == iterator->_internal_arr)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_DOUBLE_BUF;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter_start; i < iter_end; i++)
|
||||
{
|
||||
_vec_char_insert(ptr, iter + (i - iter_start),
|
||||
iterator->_internal_arr[i], &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,940 @@
|
||||
#include <libvec/int.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const _VecIntInternal* ptr, err_t* status)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_VEC_NULL;
|
||||
return ERR_VEC_NULL;
|
||||
}
|
||||
if (ptr->_internal_arr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_BUF_NULL;
|
||||
}
|
||||
|
||||
return status->flags;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) size_t
|
||||
__null_check(const int* ptr, err_t* status)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
status->flags |= ERR_BUF_NULL;
|
||||
}
|
||||
return status->flags;
|
||||
}
|
||||
|
||||
size_t
|
||||
__origin_override(err_t* status, char* str)
|
||||
{
|
||||
if (status == nullptr)
|
||||
{
|
||||
return ERR_ERR_T_NULL;
|
||||
}
|
||||
if (status->origin != nullptr)
|
||||
{
|
||||
status->flags |= ERR_ORIGIN_UNALTERABLE;
|
||||
return status->flags;
|
||||
}
|
||||
else if (str == nullptr)
|
||||
{
|
||||
status->flags |= ERR_STR_NULL;
|
||||
return status->flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
status->origin = str;
|
||||
return status->flags;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_print_vec(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
if (__null_check(ptr, err) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < ptr->_internal_size; i++)
|
||||
{
|
||||
printf("%d ", ptr->_internal_arr[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
_VecIntInternal
|
||||
_vec_int_cpy(const int* src, const size_t src_size, err_t* err)
|
||||
{
|
||||
_VecIntInternal self = VEC_INIT;
|
||||
err_t status = ERR_T_INIT;
|
||||
|
||||
size_t null = __null_check(src, err);
|
||||
if (null != 0)
|
||||
{
|
||||
if (null & ERR_ERR_T_NULL)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= status.flags;
|
||||
return self;
|
||||
}
|
||||
if (src_size == 0)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
err->flags |= status.flags;
|
||||
return self;
|
||||
}
|
||||
if (src_size > self._internal_max_size)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return self;
|
||||
}
|
||||
self._internal_arr = malloc(src_size * sizeof(int));
|
||||
if (self._internal_arr == nullptr)
|
||||
{
|
||||
__origin_override(err, "CPY");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return self;
|
||||
}
|
||||
memcpy(self._internal_arr, src, src_size * sizeof(int));
|
||||
self._internal_size = src_size;
|
||||
self._internal_capacity = src_size;
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_push_back(_VecIntInternal* ptr, const int val, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
int* res;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size + 1 > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((status.flags & ERR_BUF_NULL) != 0)
|
||||
{
|
||||
res = malloc(1 * sizeof(int));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = 1;
|
||||
ptr->_internal_size = 0;
|
||||
}
|
||||
|
||||
else if (ptr->_internal_size + 1 > ptr->_internal_capacity)
|
||||
{
|
||||
size_t dst_cap =
|
||||
(ptr->_internal_capacity / 2) + ptr->_internal_capacity;
|
||||
if (dst_cap == ptr->_internal_capacity)
|
||||
{
|
||||
dst_cap++;
|
||||
}
|
||||
if (dst_cap > ptr->_internal_max_size)
|
||||
{
|
||||
dst_cap = ptr->_internal_max_size;
|
||||
DEBUG(
|
||||
"Capacity cannot be grown any further due "
|
||||
"to hitting max size");
|
||||
}
|
||||
res = realloc(ptr->_internal_arr, dst_cap * sizeof(int));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "PUSH_BACK");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = dst_cap;
|
||||
}
|
||||
ptr->_internal_arr[ptr->_internal_size] = val;
|
||||
ptr->_internal_size++;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_pop_back(_VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
if (__null_check(ptr, err) != 0)
|
||||
{
|
||||
__origin_override(err, "POP_BACK");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "POP_BACK");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
ptr->_internal_arr[ptr->_internal_size - 1] = 0;
|
||||
ptr->_internal_size--;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_reserve(_VecIntInternal* ptr, const size_t capacity, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ptr->_internal_max_size < capacity)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
if (capacity == 0)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
int* res = realloc(ptr->_internal_arr, capacity * sizeof(int));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "RESERVE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = capacity;
|
||||
if (ptr->_internal_size > capacity)
|
||||
{
|
||||
ptr->_internal_size = capacity;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_shrink_to_fit(_VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "SHRINK_TO_FIT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "SHRINK_TO_FIT");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
_vec_int_reserve(ptr, ptr->_internal_size, err);
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_swap(_VecIntInternal* ptr_a, _VecIntInternal* ptr_b, err_t* err)
|
||||
{
|
||||
err_t status_1 = ERR_T_INIT, status_2 = ERR_T_INIT;
|
||||
if ((__null_check(ptr_a, &status_1) & ERR_VEC_NULL) != 0 ||
|
||||
(__null_check(ptr_b, &status_2) & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "SWAP");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
_VecIntInternal self = *ptr_a;
|
||||
*ptr_a = *ptr_b;
|
||||
*ptr_b = self;
|
||||
return;
|
||||
}
|
||||
|
||||
const int*
|
||||
_vec_int_data(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "DATA");
|
||||
err->flags |= status.flags;
|
||||
return nullptr;
|
||||
}
|
||||
return &ptr->_internal_arr[0];
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_size(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "SIZE");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_capacity(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "CAPACITY");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_capacity;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_max_size(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "MAX_SIZE");
|
||||
err->flags |= status.flags;
|
||||
return 0;
|
||||
}
|
||||
return ptr->_internal_max_size;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_delete(_VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "DELETE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr != nullptr)
|
||||
{
|
||||
free(ptr->_internal_arr);
|
||||
ptr->_internal_arr = nullptr;
|
||||
}
|
||||
ptr->_internal_size = 0;
|
||||
ptr->_internal_capacity = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_vec_int_clear(_VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "CLEAR");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size > 0)
|
||||
{
|
||||
memset(ptr->_internal_arr, 0,
|
||||
ptr->_internal_size * sizeof(int));
|
||||
ptr->_internal_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int*
|
||||
_vec_int_at(const _VecIntInternal* ptr, const size_t idx, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "AT");
|
||||
err->flags |= status.flags;
|
||||
return nullptr;
|
||||
}
|
||||
if (idx >= ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "AT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return nullptr;
|
||||
}
|
||||
return &ptr->_internal_arr[idx];
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_begin(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "BEGIN");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_end(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "END");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
__origin_override(err, "END");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return status.flags;
|
||||
}
|
||||
return (size_t)(ptr->_internal_size - 1);
|
||||
}
|
||||
|
||||
int
|
||||
_vec_int_front(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "FRONT");
|
||||
err->flags |= status.flags;
|
||||
return -1;
|
||||
}
|
||||
if (_vec_int_at(ptr, 0, err) == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return 0;
|
||||
}
|
||||
return *_vec_int_at(ptr, 0, err);
|
||||
}
|
||||
|
||||
int
|
||||
_vec_int_back(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "BACK");
|
||||
err->flags |= status.flags;
|
||||
return -1;
|
||||
}
|
||||
if (_vec_int_at(ptr, 0, err) == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return 0;
|
||||
}
|
||||
return *_vec_int_at(ptr, ptr->_internal_size - 1, err);
|
||||
}
|
||||
|
||||
size_t
|
||||
_vec_int_empty(const _VecIntInternal* ptr, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "EMPTY");
|
||||
err->flags |= status.flags;
|
||||
return status.flags;
|
||||
}
|
||||
if (ptr->_internal_size == 0)
|
||||
{
|
||||
return ptr->_internal_size;
|
||||
}
|
||||
return status.flags;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_erase(_VecIntInternal* ptr, const size_t iter, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter >= ptr->_internal_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
memmove(&ptr->_internal_arr[iter], &ptr->_internal_arr[iter + 1],
|
||||
(ptr->_internal_size - iter - 1) * sizeof(int));
|
||||
ptr->_internal_arr[ptr->_internal_size - 1] = 0;
|
||||
ptr->_internal_size--;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_erase(_VecIntInternal* ptr, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size < iter_end || iter_end <= iter_start)
|
||||
{
|
||||
__origin_override(err, "ERASE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
size_t diff = iter_end - iter_start;
|
||||
memmove(&ptr->_internal_arr[iter_start], &ptr->_internal_arr[iter_end],
|
||||
(ptr->_internal_size - iter_end) * sizeof(int));
|
||||
memset(&ptr->_internal_arr[ptr->_internal_size - diff], 0,
|
||||
sizeof(int) * diff);
|
||||
ptr->_internal_size -= diff;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_resize(_VecIntInternal* ptr, const size_t size, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr->_internal_size == size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
else if (size > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->_internal_size == 0)
|
||||
{
|
||||
size_t max = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
_vec_int_reserve(ptr, size, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
memset(ptr->_internal_arr, 0, size * sizeof(int));
|
||||
ptr->_internal_max_size = max;
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
else if (size > ptr->_internal_capacity)
|
||||
{
|
||||
size_t tmpcp = ptr->_internal_capacity;
|
||||
size_t tmpmx = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
while (size > tmpcp)
|
||||
{
|
||||
tmpcp *= 2;
|
||||
}
|
||||
if (tmpcp > ptr->_internal_max_size)
|
||||
{
|
||||
tmpcp = size;
|
||||
}
|
||||
_vec_int_reserve(ptr, tmpcp, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != tmpcp)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_max_size = tmpmx;
|
||||
}
|
||||
if (size < ptr->_internal_size)
|
||||
{
|
||||
memset(&ptr->_internal_arr[size], 0,
|
||||
(ptr->_internal_size - size) * sizeof(int));
|
||||
}
|
||||
if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
|
||||
{
|
||||
memset(&ptr->_internal_arr[ptr->_internal_size], 0,
|
||||
(size - ptr->_internal_size) * sizeof(int));
|
||||
}
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_resize(_VecIntInternal* ptr, const size_t size, const int val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_VEC_NULL;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_size == size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
else if (size > ptr->_internal_max_size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->_internal_size == 0)
|
||||
{
|
||||
size_t max = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
_vec_int_reserve(ptr, size, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_capacity != size)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= ERR_ALLOC_FAIL;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
ptr->_internal_arr[i] = val;
|
||||
}
|
||||
ptr->_internal_max_size = max;
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
else if (size > ptr->_internal_capacity)
|
||||
{
|
||||
size_t tmpcp = ptr->_internal_capacity;
|
||||
size_t tmpmx = ptr->_internal_max_size;
|
||||
err_t verr = ERR_T_INIT;
|
||||
while (size > tmpcp)
|
||||
{
|
||||
tmpcp *= 2;
|
||||
}
|
||||
if (tmpcp > ptr->_internal_max_size)
|
||||
{
|
||||
tmpcp = size;
|
||||
}
|
||||
_vec_int_reserve(ptr, tmpcp, &verr);
|
||||
if (verr.flags != 0)
|
||||
{
|
||||
__origin_override(err, "RESIZE");
|
||||
err->flags |= verr.flags;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_max_size = tmpmx;
|
||||
}
|
||||
if (size < ptr->_internal_size)
|
||||
{
|
||||
for (size_t i = size; i < ptr->_internal_size; i++)
|
||||
{
|
||||
ptr->_internal_arr[i] = 0;
|
||||
}
|
||||
}
|
||||
if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
|
||||
{
|
||||
for (size_t i = ptr->_internal_size; i < size; i++)
|
||||
{
|
||||
ptr->_internal_arr[i] = val;
|
||||
}
|
||||
}
|
||||
ptr->_internal_size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_assign(_VecIntInternal* ptr, const _VecIntInternal* iterator,
|
||||
const size_t iter_start, const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0 ||
|
||||
__null_check(iterator, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr == iterator->_internal_arr)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_DOUBLE_BUF;
|
||||
return;
|
||||
}
|
||||
if (iterator->_internal_size < iter_end || iter_end <= iter_start)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_int_erase(ptr, _vec_int_begin(ptr, &status),
|
||||
_vec_int_end(ptr, &status) + 1, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
_vec_int_reserve(ptr, (iter_end - iter_start), &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter_start; i < iter_end; i++)
|
||||
{
|
||||
int* res = _vec_int_at(iterator, i, &status);
|
||||
if (res == nullptr)
|
||||
{
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_int_push_back(ptr, *res, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_assign(_VecIntInternal* ptr, const size_t amount, const int val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
if (__null_check(ptr, &status) != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (amount == 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
_vec_int_erase(ptr, _vec_int_begin(ptr, &status),
|
||||
_vec_int_end(ptr, &status) + 1, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
_vec_int_reserve(ptr, amount, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < amount; i++)
|
||||
{
|
||||
_vec_int_push_back(ptr, val, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "ASSIGN");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const size_t iter, const int val,
|
||||
err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & ERR_VEC_NULL) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if ((status.flags & ERR_BUF_NULL) != 0)
|
||||
{
|
||||
int* res = malloc(1 * sizeof(int));
|
||||
if (res == nullptr)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_BUF_NULL;
|
||||
return;
|
||||
}
|
||||
ptr->_internal_arr = res;
|
||||
ptr->_internal_capacity = 1;
|
||||
ptr->_internal_arr[0] = val;
|
||||
ptr->_internal_size = 1;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_max_size < ptr->_internal_size + 1)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_SIZE_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
if (iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
_vec_int_push_back(ptr, 0, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
for (size_t i = ptr->_internal_size - 1; i > iter; i--)
|
||||
{
|
||||
ptr->_internal_arr[i] = ptr->_internal_arr[i - 1];
|
||||
}
|
||||
ptr->_internal_arr[iter] = val;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const size_t iter, const size_t amount,
|
||||
const int val, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
if ((status.flags & (ERR_VEC_NULL | ERR_BUF_NULL)) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
if (amount == 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_SIZE_ZERO;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter; i < iter + amount; i++)
|
||||
{
|
||||
_vec_int_insert(ptr, i, val, &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__attribute__((overloadable)) void
|
||||
_vec_int_insert(_VecIntInternal* ptr, const _VecIntInternal* iterator,
|
||||
const size_t iter, const size_t iter_start,
|
||||
const size_t iter_end, err_t* err)
|
||||
{
|
||||
err_t status = ERR_T_INIT;
|
||||
__null_check(ptr, &status);
|
||||
__null_check(iterator, &status);
|
||||
if ((status.flags & (ERR_VEC_NULL | ERR_BUF_NULL)) != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
if (iter_end <= iter_start || iter_end > iterator->_internal_size ||
|
||||
iter > ptr->_internal_size)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
if (ptr->_internal_arr == iterator->_internal_arr)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= ERR_DOUBLE_BUF;
|
||||
return;
|
||||
}
|
||||
for (size_t i = iter_start; i < iter_end; i++)
|
||||
{
|
||||
_vec_int_insert(ptr, iter + (i - iter_start),
|
||||
iterator->_internal_arr[i], &status);
|
||||
if (status.flags != 0)
|
||||
{
|
||||
__origin_override(err, "INSERT");
|
||||
err->flags |= status.flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
@@ -1 +0,0 @@
|
||||
#include <libvec.h>
|
||||
+2
-2
@@ -12,13 +12,12 @@
|
||||
* String 32 Bits with suffix of 's'
|
||||
*/
|
||||
|
||||
#include <libvec/utils.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/utils/utils.h"
|
||||
|
||||
void
|
||||
print_bits(unsigned int num);
|
||||
|
||||
@@ -26,6 +25,7 @@ int
|
||||
main()
|
||||
{
|
||||
// TODO:
|
||||
//
|
||||
// Fix the error checking because you make a status to hold all local
|
||||
// errors but then in some cases you or them to the main err handler and
|
||||
// if the error doesnt need to be there like a good error but one that
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <libvec/utils.h>
|
||||
#include <stdio.h>
|
||||
#include <utils/utils.h>
|
||||
|
||||
const char*
|
||||
vec_get_error_desc(ERROR_CODES err)
|
||||
+193
-190
@@ -1,5 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <char/char.h>
|
||||
#include <int/int.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -23,15 +23,15 @@ __asan_default_options(void)
|
||||
static void
|
||||
test_push_back_single(void)
|
||||
{
|
||||
printf("[1] Testing push_back with a single character...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
printf("[1] Testing push_back with a single integer...\n");
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'A', &err);
|
||||
_vec_int_push_back(&vec, 65, &err);
|
||||
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'A');
|
||||
_vec_char_delete(&vec, &err);
|
||||
assert(vec._internal_arr[0] == 65);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
@@ -39,13 +39,13 @@ static void
|
||||
test_null_guards(void)
|
||||
{
|
||||
printf("[2] Testing null pointer checks in __null_check...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
size_t res1 = __null_check(&vec, nullptr);
|
||||
assert(res1 == ERR_ERR_T_NULL);
|
||||
|
||||
size_t res2 = __null_check((const _VecCharInternal*)nullptr, &err);
|
||||
size_t res2 = __null_check((const _VecIntInternal*)nullptr, &err);
|
||||
assert(res2 == ERR_VEC_NULL);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
@@ -60,7 +60,7 @@ test_null_guards(void)
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t res5 = __null_check((const char*)nullptr, nullptr);
|
||||
size_t res5 = __null_check((const int*)nullptr, nullptr);
|
||||
assert(res5 == ERR_ERR_T_NULL);
|
||||
|
||||
printf("Passed\n");
|
||||
@@ -98,42 +98,42 @@ test_origin_override(void)
|
||||
static void
|
||||
test_print_vec(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[4] Testing print_vec with null vector\n");
|
||||
_vec_char_print_vec(nullptr, &err);
|
||||
_vec_int_print_vec(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[5] Testing print_vec with null array\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_print_vec(&vec, &err);
|
||||
_vec_int_print_vec(&vec, &err);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[6] Testing print_vec with null err\n");
|
||||
_vec_char_print_vec(&vec, nullptr);
|
||||
_vec_int_print_vec(&vec, nullptr);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[7] Testing print_vec with valid parameters\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_push_back(&vec, 'b', &err);
|
||||
_vec_char_print_vec(&vec, &err);
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_push_back(&vec, 1, &err);
|
||||
_vec_int_push_back(&vec, 2, &err);
|
||||
_vec_int_print_vec(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_cpy(void)
|
||||
{
|
||||
char arr[3] = { 'a', 'b', 'c' };
|
||||
_VecCharInternal blank = VEC_INIT;
|
||||
int arr[3] = { 1, 2, 3 };
|
||||
_VecIntInternal blank = VEC_INIT;
|
||||
|
||||
printf("[8] Testing _vec_char_cpy with null source arr\n");
|
||||
printf("[8] Testing _vec_int_cpy with null source arr\n");
|
||||
err_t err1 = ERR_T_INIT;
|
||||
_VecCharInternal tmp = _vec_char_cpy(nullptr, 3, &err1);
|
||||
_VecIntInternal tmp = _vec_int_cpy(nullptr, 3, &err1);
|
||||
assert(blank._internal_arr == tmp._internal_arr &&
|
||||
blank._internal_capacity == tmp._internal_capacity &&
|
||||
blank._internal_size == tmp._internal_size &&
|
||||
@@ -141,17 +141,17 @@ test_cpy(void)
|
||||
assert((err1.flags & ERR_BUF_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[9] Testing _vec_char_cpy with null err\n");
|
||||
_VecCharInternal res2 = _vec_char_cpy(arr, 3, nullptr);
|
||||
printf("[9] Testing _vec_int_cpy with null err\n");
|
||||
_VecIntInternal res2 = _vec_int_cpy(arr, 3, nullptr);
|
||||
assert(blank._internal_arr == res2._internal_arr &&
|
||||
blank._internal_capacity == res2._internal_capacity &&
|
||||
blank._internal_size == res2._internal_size &&
|
||||
blank._internal_max_size == res2._internal_max_size);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[10] Testing _vec_char_cpy with size 0\n");
|
||||
printf("[10] Testing _vec_int_cpy with size 0\n");
|
||||
err_t err3 = ERR_T_INIT;
|
||||
_VecCharInternal res3 = _vec_char_cpy(arr, 0, &err3);
|
||||
_VecIntInternal res3 = _vec_int_cpy(arr, 0, &err3);
|
||||
assert(blank._internal_arr == res3._internal_arr &&
|
||||
blank._internal_capacity == res3._internal_capacity &&
|
||||
blank._internal_size == res3._internal_size &&
|
||||
@@ -159,10 +159,10 @@ test_cpy(void)
|
||||
assert((err3.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[11] Testing _vec_char_cpy with size exceeding max_size\n");
|
||||
printf("[11] Testing _vec_int_cpy with size exceeding max_size\n");
|
||||
err_t err4 = ERR_T_INIT;
|
||||
_VecCharInternal res4 =
|
||||
_vec_char_cpy(arr, res3._internal_max_size + 1, &err4);
|
||||
_VecIntInternal res4 =
|
||||
_vec_int_cpy(arr, res3._internal_max_size + 1, &err4);
|
||||
assert(blank._internal_arr == res4._internal_arr &&
|
||||
blank._internal_capacity == res4._internal_capacity &&
|
||||
blank._internal_size == res4._internal_size &&
|
||||
@@ -170,22 +170,23 @@ test_cpy(void)
|
||||
assert((err4.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[12] Testing _vec_char_cpy allocation failure\n");
|
||||
printf("[12] Testing _vec_int_cpy allocation failure\n");
|
||||
err_t err5 = ERR_T_INIT;
|
||||
size_t huge_size = ((size_t)1 << 40);
|
||||
_VecCharInternal res5 = _vec_char_cpy(arr, huge_size, &err5);
|
||||
_VecIntInternal res5 = _vec_int_cpy(arr, huge_size, &err5);
|
||||
assert(res5._internal_arr == blank._internal_arr);
|
||||
assert((err5.flags & ERR_ALLOC_FAIL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[13] Testing _vec_char_cpy with valid inputs\n");
|
||||
printf("[13] Testing _vec_int_cpy with valid inputs\n");
|
||||
err_t err = ERR_T_INIT;
|
||||
char res[4] = { 'a', 'b', 'c', 'd' };
|
||||
_VecCharInternal vec = _vec_char_cpy(res, 4, &err);
|
||||
int res[4] = { 10, 20, 30, 40 };
|
||||
_VecIntInternal vec = _vec_int_cpy(res, 4, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 4);
|
||||
assert(vec._internal_capacity == 4);
|
||||
assert(memcmp(vec._internal_arr, res, 4) == 0);
|
||||
_vec_char_delete(&vec, &err);
|
||||
assert(memcmp(vec._internal_arr, res, sizeof(int) * 4) == 0);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
@@ -196,151 +197,151 @@ test_cpy(void)
|
||||
static void
|
||||
test_push_back(void)
|
||||
{
|
||||
printf("[14] Testing _vec_char_push_back null vec\n");
|
||||
printf("[14] Testing _vec_int_push_back null vec\n");
|
||||
err_t err = ERR_T_INIT;
|
||||
_vec_char_push_back(nullptr, 'a', &err);
|
||||
_vec_int_push_back(nullptr, 1, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[15] Testing _vec_char_push_back null err\n");
|
||||
_VecCharInternal vec1 = VEC_INIT;
|
||||
_vec_char_push_back(&vec1, 'a', nullptr);
|
||||
printf("[15] Testing _vec_int_push_back null err\n");
|
||||
_VecIntInternal vec1 = VEC_INIT;
|
||||
_vec_int_push_back(&vec1, 1, nullptr);
|
||||
assert(vec1._internal_size == 1);
|
||||
_vec_char_delete(&vec1, &err);
|
||||
_vec_int_delete(&vec1, &err);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[16] Testing _vec_char_push_back size overflow\n");
|
||||
_VecCharInternal vec2 = VEC_INIT;
|
||||
printf("[16] Testing _vec_int_push_back size overflow\n");
|
||||
_VecIntInternal vec2 = VEC_INIT;
|
||||
err_t err2 = ERR_T_INIT;
|
||||
vec2._internal_size = vec2._internal_max_size;
|
||||
_vec_char_push_back(&vec2, 'a', &err2);
|
||||
_vec_int_push_back(&vec2, 1, &err2);
|
||||
assert((err2.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[17] Testing push_back capacity growth realloc\n");
|
||||
err_t err3 = ERR_T_INIT;
|
||||
_VecCharInternal vec3 = VEC_INIT;
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
_VecIntInternal vec3 = VEC_INIT;
|
||||
for (int val = 0; val < 10; val++)
|
||||
{
|
||||
_vec_char_push_back(&vec3, c, &err3);
|
||||
_vec_int_push_back(&vec3, val, &err3);
|
||||
assert(err3.flags == 0);
|
||||
}
|
||||
assert(vec3._internal_size == 10);
|
||||
assert(vec3._internal_capacity >= 10);
|
||||
_vec_char_delete(&vec3, &err3);
|
||||
_vec_int_delete(&vec3, &err3);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_pop_back(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[18] Testing _vec_char_pop_back null vector\n");
|
||||
_vec_char_pop_back(nullptr, &err);
|
||||
printf("[18] Testing _vec_int_pop_back null vector\n");
|
||||
_vec_int_pop_back(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[19] Testing _vec_char_pop_back size 0\n");
|
||||
printf("[19] Testing _vec_int_pop_back size 0\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_pop_back(&vec,
|
||||
&err); // size is now 0, but buffer is allocated
|
||||
_vec_int_push_back(&vec, 42, &err);
|
||||
_vec_int_pop_back(&vec,
|
||||
&err); // size is now 0, but buffer is allocated
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
_vec_int_pop_back(&vec, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[20] Testing _vec_char_pop_back valid pop\n");
|
||||
printf("[20] Testing _vec_int_pop_back valid pop\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_push_back(&vec, 'b', &err);
|
||||
_vec_int_push_back(&vec, 1, &err);
|
||||
_vec_int_push_back(&vec, 2, &err);
|
||||
assert(vec._internal_size == 2);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
_vec_int_pop_back(&vec, &err);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'a');
|
||||
assert(vec._internal_arr[0] == 1);
|
||||
assert(vec._internal_arr[1] == 0);
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_reserve(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[21] Testing _vec_char_reserve null vector\n");
|
||||
_vec_char_reserve(nullptr, 1, &err);
|
||||
printf("[21] Testing _vec_int_reserve null vector\n");
|
||||
_vec_int_reserve(nullptr, 1, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[22] Testing _vec_char_reserve capacity 0\n");
|
||||
printf("[22] Testing _vec_int_reserve capacity 0\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_reserve(&vec, 0, &err);
|
||||
_vec_int_reserve(&vec, 0, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[23] Testing _vec_char_reserve calloc on unallocated buffer\n");
|
||||
printf("[23] Testing _vec_int_reserve calloc on unallocated buffer\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_reserve(&vec, 32, &err);
|
||||
_vec_int_reserve(&vec, 32, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 32);
|
||||
assert(vec._internal_arr != nullptr);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[24] Testing _vec_char_reserve realloc to larger capacity\n");
|
||||
_vec_char_reserve(&vec, 64, &err);
|
||||
printf("[24] Testing _vec_int_reserve realloc to larger capacity\n");
|
||||
_vec_int_reserve(&vec, 64, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 64);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[25] Testing _vec_char_reserve truncating size\n");
|
||||
printf("[25] Testing _vec_int_reserve truncating size\n");
|
||||
vec._internal_size = 50;
|
||||
_vec_char_reserve(&vec, 20, &err);
|
||||
_vec_int_reserve(&vec, 20, &err);
|
||||
assert(vec._internal_size == 20);
|
||||
assert(vec._internal_capacity == 20);
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_shrink_to_fit(void)
|
||||
{
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
printf("[26] Testing _vec_char_shrink_to_fit null vector\n");
|
||||
_vec_char_shrink_to_fit(nullptr, &err);
|
||||
printf("[26] Testing _vec_int_shrink_to_fit null vector\n");
|
||||
_vec_int_shrink_to_fit(nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf(
|
||||
"[27] Testing _vec_char_shrink_to_fit size 0 with allocated "
|
||||
"[27] Testing _vec_int_shrink_to_fit size 0 with allocated "
|
||||
"buffer\n");
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'a', &err);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
_vec_int_push_back(&vec, 1, &err);
|
||||
_vec_int_pop_back(&vec, &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_shrink_to_fit(&vec, &err);
|
||||
_vec_int_shrink_to_fit(&vec, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
printf("Passed\n");
|
||||
|
||||
printf("[28] Testing _vec_char_shrink_to_fit normal shrinkage\n");
|
||||
_vec_char_reserve(&vec, 128, &err);
|
||||
for (char c = '0'; c < '5'; c++)
|
||||
printf("[28] Testing _vec_int_shrink_to_fit normal shrinkage\n");
|
||||
_vec_int_reserve(&vec, 128, &err);
|
||||
for (int val = 0; val < 5; val++)
|
||||
{
|
||||
_vec_char_push_back(&vec, c, &err);
|
||||
_vec_int_push_back(&vec, val, &err);
|
||||
}
|
||||
assert(vec._internal_capacity == 128);
|
||||
assert(vec._internal_size == 5);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_shrink_to_fit(&vec, &err);
|
||||
_vec_int_shrink_to_fit(&vec, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_capacity == 5);
|
||||
assert(vec._internal_size == 5);
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
@@ -352,75 +353,75 @@ static void
|
||||
test_getters_and_access(void)
|
||||
{
|
||||
printf("[29] Testing getters, clear, and boundary element access...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// 1. Null pointer check
|
||||
assert(_vec_char_data(nullptr, &err) == nullptr);
|
||||
assert(_vec_int_data(nullptr, &err) == nullptr);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_size(nullptr, &err) == 0);
|
||||
assert(_vec_int_size(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_capacity(nullptr, &err) == 0);
|
||||
assert(_vec_int_capacity(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_max_size(nullptr, &err) == 0);
|
||||
assert(_vec_int_max_size(nullptr, &err) == 0);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// 2. Unallocated buffer check for empty()
|
||||
err = (err_t)ERR_T_INIT;
|
||||
size_t unalloc_empty = _vec_char_empty(&vec, &err);
|
||||
size_t unalloc_empty = _vec_int_empty(&vec, &err);
|
||||
assert((err.flags & ERR_BUF_NULL) != 0);
|
||||
assert(unalloc_empty != 0);
|
||||
|
||||
// 3. Allocate the buffer and pop so size is 0 with valid arr
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_pop_back(&vec, &err);
|
||||
_vec_int_push_back(&vec, 100, &err);
|
||||
_vec_int_pop_back(&vec, &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
|
||||
// Now _internal_arr is non-null and size is 0:
|
||||
assert(_vec_char_empty(&vec, &err) == 0);
|
||||
assert(_vec_int_empty(&vec, &err) == 0);
|
||||
|
||||
// Boundary element access on size 0
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_front(&vec, &err) == 0 ||
|
||||
assert(_vec_int_front(&vec, &err) == 0 ||
|
||||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_back(&vec, &err) == 0 ||
|
||||
assert(_vec_int_back(&vec, &err) == 0 ||
|
||||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// 4. Populate container
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&vec, 'x', &err);
|
||||
_vec_char_push_back(&vec, 'y', &err);
|
||||
_vec_char_push_back(&vec, 'z', &err);
|
||||
_vec_int_push_back(&vec, 10, &err);
|
||||
_vec_int_push_back(&vec, 20, &err);
|
||||
_vec_int_push_back(&vec, 30, &err);
|
||||
|
||||
assert(_vec_char_size(&vec, &err) == 3);
|
||||
assert(_vec_char_capacity(&vec, &err) >= 3);
|
||||
assert(_vec_char_data(&vec, &err) == vec._internal_arr);
|
||||
assert(_vec_char_front(&vec, &err) == 'x');
|
||||
assert(_vec_char_back(&vec, &err) == 'z');
|
||||
assert(_vec_char_begin(&vec, &err) == 0);
|
||||
assert(_vec_char_end(&vec, &err) == 2);
|
||||
assert(_vec_int_size(&vec, &err) == 3);
|
||||
assert(_vec_int_capacity(&vec, &err) >= 3);
|
||||
assert(_vec_int_data(&vec, &err) == vec._internal_arr);
|
||||
assert(_vec_int_front(&vec, &err) == 10);
|
||||
assert(_vec_int_back(&vec, &err) == 30);
|
||||
assert(_vec_int_begin(&vec, &err) == 0);
|
||||
assert(_vec_int_end(&vec, &err) == 2);
|
||||
|
||||
// Out of bounds at()
|
||||
err = (err_t)ERR_T_INIT;
|
||||
assert(_vec_char_at(&vec, 10, &err) == nullptr);
|
||||
assert(_vec_int_at(&vec, 10, &err) == nullptr);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Clear container
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_clear(&vec, &err);
|
||||
_vec_int_clear(&vec, &err);
|
||||
assert(vec._internal_size == 0);
|
||||
assert(vec._internal_arr[0] == 0);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
assert(vec._internal_arr == nullptr);
|
||||
assert(vec._internal_size == 0);
|
||||
assert(vec._internal_capacity == 0);
|
||||
@@ -435,220 +436,222 @@ test_getters_and_access(void)
|
||||
static void
|
||||
test_swap(void)
|
||||
{
|
||||
printf("[30] Testing _vec_char_swap...\n");
|
||||
_VecCharInternal a = VEC_INIT;
|
||||
_VecCharInternal b = VEC_INIT;
|
||||
printf("[30] Testing _vec_int_swap...\n");
|
||||
_VecIntInternal a = VEC_INIT;
|
||||
_VecIntInternal b = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Null vector checks
|
||||
_vec_char_swap(nullptr, &b, &err);
|
||||
_vec_int_swap(nullptr, &b, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_swap(&a, nullptr, &err);
|
||||
_vec_int_swap(&a, nullptr, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// Normal swap
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_push_back(&a, 'A', &err);
|
||||
_vec_char_push_back(&b, 'B', &err);
|
||||
_vec_char_push_back(&b, 'C', &err);
|
||||
_vec_int_push_back(&a, 100, &err);
|
||||
_vec_int_push_back(&b, 200, &err);
|
||||
_vec_int_push_back(&b, 300, &err);
|
||||
|
||||
_vec_char_swap(&a, &b, &err);
|
||||
_vec_int_swap(&a, &b, &err);
|
||||
assert(a._internal_size == 2);
|
||||
assert(a._internal_arr[0] == 'B');
|
||||
assert(a._internal_arr[0] == 200);
|
||||
assert(b._internal_size == 1);
|
||||
assert(b._internal_arr[0] == 'A');
|
||||
assert(b._internal_arr[0] == 100);
|
||||
|
||||
_vec_char_delete(&a, &err);
|
||||
_vec_char_delete(&b, &err);
|
||||
_vec_int_delete(&a, &err);
|
||||
_vec_int_delete(&b, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_erase_variants(void)
|
||||
{
|
||||
printf("[31] Testing _vec_char_erase single & range overloads...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
printf("[31] Testing _vec_int_erase single & range overloads...\n");
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
for (char c = '0'; c <= '5'; c++)
|
||||
for (int val = 0; val <= 5; val++)
|
||||
{
|
||||
_vec_char_push_back(&vec, c, &err);
|
||||
} // "012345"
|
||||
_vec_int_push_back(&vec, val, &err);
|
||||
} // {0, 1, 2, 3, 4, 5}
|
||||
|
||||
// Single element erase out of bounds (noop)
|
||||
_vec_char_erase(&vec, 10, &err);
|
||||
_vec_int_erase(&vec, 10, &err);
|
||||
assert(vec._internal_size == 6);
|
||||
|
||||
// Erase index 2 ('2') -> "01345"
|
||||
_vec_char_erase(&vec, 2, &err);
|
||||
// Erase index 2 (value 2) -> {0, 1, 3, 4, 5}
|
||||
_vec_int_erase(&vec, 2, &err);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[2] == '3');
|
||||
assert(vec._internal_arr[2] == 3);
|
||||
|
||||
// Range erase invalid bounds
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 4, 2, &err); // iter_end <= iter_start
|
||||
_vec_int_erase(&vec, 4, 2, &err); // iter_end <= iter_start
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 0, 10, &err); // iter_end > size
|
||||
_vec_int_erase(&vec, 0, 10, &err); // iter_end > size
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Range erase middle: index 1 through 3 ("0[13]45" -> "045")
|
||||
// Range erase middle: index 1 through 3 ({0, [1, 3], 4, 5} -> {0, 4,
|
||||
// 5})
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_erase(&vec, 1, 3, &err);
|
||||
_vec_int_erase(&vec, 1, 3, &err);
|
||||
assert(vec._internal_size == 3);
|
||||
assert(vec._internal_arr[0] == '0');
|
||||
assert(vec._internal_arr[1] == '4');
|
||||
assert(vec._internal_arr[2] == '5');
|
||||
assert(vec._internal_arr[0] == 0);
|
||||
assert(vec._internal_arr[1] == 4);
|
||||
assert(vec._internal_arr[2] == 5);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_resize(void)
|
||||
{
|
||||
printf("[32] Testing _vec_char_resize (zero-fill & value-fill)...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
printf("[32] Testing _vec_int_resize (zero-fill & value-fill)...\n");
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Null vector
|
||||
_vec_char_resize((_VecCharInternal*)nullptr, 10, &err);
|
||||
_vec_int_resize((_VecIntInternal*)nullptr, 10, &err);
|
||||
assert((err.flags & ERR_VEC_NULL) != 0);
|
||||
|
||||
// Resize unallocated buffer to size 5
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 5, &err);
|
||||
_vec_int_resize(&vec, 5, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[0] == 0);
|
||||
|
||||
// Same size requested
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 5, &err);
|
||||
_vec_int_resize(&vec, 5, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Exceeds max size
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, vec._internal_max_size + 1, &err);
|
||||
_vec_int_resize(&vec, vec._internal_max_size + 1, &err);
|
||||
assert((err.flags & ERR_SIZE_OVERFLOW) != 0);
|
||||
|
||||
// Grow with value fill
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 8, 'Z', &err);
|
||||
_vec_int_resize(&vec, 8, 5, &err);
|
||||
assert(vec._internal_size == 8);
|
||||
assert(vec._internal_arr[5] == 'Z');
|
||||
assert(vec._internal_arr[7] == 'Z');
|
||||
assert(vec._internal_arr[5] == 5);
|
||||
assert(vec._internal_arr[7] == 5);
|
||||
|
||||
// Shrink with value fill
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_resize(&vec, 3, 'A', &err);
|
||||
_vec_int_resize(&vec, 3, 10, &err);
|
||||
assert(vec._internal_size == 3);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_assign(void)
|
||||
{
|
||||
printf("[33] Testing _vec_char_assign overloads...\n");
|
||||
_VecCharInternal dst = VEC_INIT;
|
||||
_VecCharInternal src = VEC_INIT;
|
||||
printf("[33] Testing _vec_int_assign overloads...\n");
|
||||
_VecIntInternal dst = VEC_INIT;
|
||||
_VecIntInternal src = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Populate src: 'A', 'B', 'C', 'D', 'E'
|
||||
for (char c = 'A'; c <= 'E'; c++)
|
||||
// Populate src: 1, 2, 3, 4, 5
|
||||
for (int val = 1; val <= 5; val++)
|
||||
{
|
||||
_vec_char_push_back(&src, c, &err);
|
||||
_vec_int_push_back(&src, val, &err);
|
||||
}
|
||||
|
||||
// Allocate dst buffer first so it is not unallocated
|
||||
_vec_char_push_back(&dst, 'z', &err);
|
||||
_vec_int_push_back(&dst, 999, &err);
|
||||
err = (err_t)ERR_T_INIT;
|
||||
|
||||
// 1. Fill assign: 4 'X's
|
||||
_vec_char_assign(&dst, 4, 'X', &err);
|
||||
// 1. Fill assign: 4 42's
|
||||
_vec_int_assign(&dst, 4, 42, &err);
|
||||
assert(err.flags == 0);
|
||||
assert(dst._internal_size == 4);
|
||||
assert(dst._internal_arr[0] == 'X');
|
||||
assert(dst._internal_arr[3] == 'X');
|
||||
assert(dst._internal_arr[0] == 42);
|
||||
assert(dst._internal_arr[3] == 42);
|
||||
|
||||
// 2. Fill assign with 0 amount
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, 0, 'Y', &err);
|
||||
_vec_int_assign(&dst, 0, 50, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
|
||||
// 3. Range assign self-buffer check
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &dst, 0, 2, &err);
|
||||
_vec_int_assign(&dst, &dst, 0, 2, &err);
|
||||
assert((err.flags & ERR_DOUBLE_BUF) != 0);
|
||||
|
||||
// 4. Range assign invalid sub-range (start >= end)
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &src, 3, 2, &err);
|
||||
_vec_int_assign(&dst, &src, 3, 2, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// 5. Range assign out of bounds end
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_assign(&dst, &src, 0, 10, &err);
|
||||
_vec_int_assign(&dst, &src, 0, 10, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
_vec_char_delete(&dst, &err);
|
||||
_vec_char_delete(&src, &err);
|
||||
_vec_int_delete(&dst, &err);
|
||||
_vec_int_delete(&src, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_insert(void)
|
||||
{
|
||||
printf("[34] Testing _vec_char_insert overloads...\n");
|
||||
_VecCharInternal vec = VEC_INIT;
|
||||
_VecCharInternal other = VEC_INIT;
|
||||
printf("[34] Testing _vec_int_insert overloads...\n");
|
||||
_VecIntInternal vec = VEC_INIT;
|
||||
_VecIntInternal other = VEC_INIT;
|
||||
err_t err = ERR_T_INIT;
|
||||
|
||||
// Single insert on unallocated buffer
|
||||
_vec_char_insert(&vec, 0, 'M', &err);
|
||||
_vec_int_insert(&vec, 0, 500, &err);
|
||||
assert(vec._internal_size == 1);
|
||||
assert(vec._internal_arr[0] == 'M');
|
||||
assert(vec._internal_arr[0] == 500);
|
||||
|
||||
// Single insert out of bounds
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 5, 'O', &err);
|
||||
_vec_int_insert(&vec, 5, 999, &err);
|
||||
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
|
||||
|
||||
// Single insert at middle: index 0 ('A', then 'M' shifts to 1)
|
||||
// Single insert at middle: index 0 (100, then 500 shifts to 1)
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 0, 'A', &err);
|
||||
_vec_int_insert(&vec, 0, 100, &err);
|
||||
assert(vec._internal_size == 2);
|
||||
assert(vec._internal_arr[0] == 'A');
|
||||
assert(vec._internal_arr[1] == 'M');
|
||||
assert(vec._internal_arr[0] == 100);
|
||||
assert(vec._internal_arr[1] == 500);
|
||||
|
||||
// Repeated insert: insert 3 'B's at index 1 -> 'A', 'B', 'B', 'B', 'M'
|
||||
_vec_char_insert(&vec, 1, 3, 'B', &err);
|
||||
// Repeated insert: insert 3 200s at index 1 -> {100, 200, 200, 200,
|
||||
// 500}
|
||||
_vec_int_insert(&vec, 1, 3, 200, &err);
|
||||
assert(vec._internal_size == 5);
|
||||
assert(vec._internal_arr[1] == 'B');
|
||||
assert(vec._internal_arr[3] == 'B');
|
||||
assert(vec._internal_arr[4] == 'M');
|
||||
assert(vec._internal_arr[1] == 200);
|
||||
assert(vec._internal_arr[3] == 200);
|
||||
assert(vec._internal_arr[4] == 500);
|
||||
|
||||
// Repeated insert amount 0
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, 0, 0, 'Z', &err);
|
||||
_vec_int_insert(&vec, 0, 0, 300, &err);
|
||||
assert((err.flags & ERR_SIZE_ZERO) != 0);
|
||||
|
||||
// Vector-from-vector range insert
|
||||
_vec_char_push_back(&other, '1', &err);
|
||||
_vec_char_push_back(&other, '2', &err);
|
||||
_vec_int_push_back(&other, 1, &err);
|
||||
_vec_int_push_back(&other, 2, &err);
|
||||
|
||||
// Double buffer check
|
||||
err = (err_t)ERR_T_INIT;
|
||||
_vec_char_insert(&vec, &vec, 0, 0, 1, &err);
|
||||
_vec_int_insert(&vec, &vec, 0, 0, 1, &err);
|
||||
assert((err.flags & ERR_DOUBLE_BUF) != 0);
|
||||
|
||||
_vec_char_delete(&vec, &err);
|
||||
_vec_char_delete(&other, &err);
|
||||
_vec_int_delete(&vec, &err);
|
||||
_vec_int_delete(&other, &err);
|
||||
printf("Passed\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user