Compare commits

..
13 Commits
Author SHA1 Message Date
DarthMooMancer 12b560fb37 CHORE: bugfixes 2026-10-14 13:38:18 -04:00
DarthMooMancer 0e7c2cafaa CHORE: Bugfixing 2026-10-14 13:20:58 -04:00
DarthMooMancer 1654b86640 CHORE: cleaning up files and bug fixing 2026-10-14 11:32:35 -04:00
DarthMooMancer 4d96592a1e REFACTOR: Made everything public and new name scheme 2026-10-14 10:20:19 -04:00
DarthMooMancer 813390b6ac 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.
2026-10-14 09:48:58 -04:00
DarthMooMancer b89579a5e7 CHORE: Bug fixing. Major changes to bugs and also unit testing 2026-10-13 00:11:27 -04:00
DarthMooMancer fbd97f7112 CHORE: Just fixed some random bugs 2026-10-12 11:09:15 -04:00
DarthMooMancer 6b7a560156 CHORE: Heavily cleaned up broken and redundant code 2026-10-12 10:16:48 -04:00
DarthMooMancer b39911f57e REFACTOR: Completely refactored and fixed the error handling 2026-10-08 13:25:26 -04:00
DarthMooMancer 4bc6efd89e REFACTOR: Error handling 2026-10-01 13:06:57 -04:00
DarthMooMancer b218af2952 BACKUP 2026-09-28 12:26:29 -04:00
DarthMooMancer 74873807dd REFACTOR: Translated to internal file for setup towards singular Vec 2026-09-25 18:22:09 -04:00
DarthMooMancer 924c45e223 REFACTOR: Resize is completely refactored and bug free 2026-09-25 12:57:12 -04:00
25 changed files with 5083 additions and 618 deletions
Vendored
BIN
View File
Binary file not shown.
+1
View File
@@ -17,3 +17,4 @@ AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
IndentGotoLabels: InnerIndent
+8
View File
@@ -0,0 +1,8 @@
Checks: >
-*,
clang-analyzer-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-reserved-identifier,
performance-*,
security-*
+7 -1
View File
@@ -1,2 +1,8 @@
build/ build/
.cache/ .cache/
tests/cache/
tests/bin/
coverage.html
tests
Makefile
+34 -6
View File
@@ -3,12 +3,40 @@ project(libvec LANGUAGES C)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories(include)
set(SOURCES add_library(libvec STATIC
src/main.c src/char.c
src/char.c src/int.c
src/utils.c src/utils.c
src/float.c
src/string.c
# Add your other types here as you implement them:
) )
add_executable(libvec ${SOURCES}) include(FetchContent)
FetchContent_Declare(libstr
GIT_REPOSITORY https://git.moomancer.xyz/DarthMooMancer/libstr.git
GIT_TAG main
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(libstr)
target_link_libraries(libvec PRIVATE libstr)
target_include_directories(libvec
# PRIVATE: Internal headers under src/lib are only visible
# to files being compiled into libvec (char.c, utils.c, libvec.c).
# PRIVATE
# 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
)
add_executable(libvec_bin src/main.c)
set_target_properties(libvec_bin PROPERTIES OUTPUT_NAME "libvec")
# Linking libvec privately gives test_runner access to include/libvec.h,
# but strictly hides src/lib/char/char.h and src/lib/utils/utils.h.
target_link_libraries(libvec_bin PRIVATE libvec)
+143
View File
@@ -0,0 +1,143 @@
# ==============================================================================
# Toolchain & Executables
# ==============================================================================
LLVM_DIR ?= /opt/homebrew/opt/llvm/bin
CC := $(LLVM_DIR)/clang
LLVM_PROFDATA := $(LLVM_DIR)/llvm-profdata
LLVM_COV := $(LLVM_DIR)/llvm-cov
CPPCHECK := cppcheck
# libstr is populated by CMake's FetchContent (run `cmake -B build` once)
LIBSTR_DIR := build/_deps/libstr-src
# ==============================================================================
# Flags & Directories
# ==============================================================================
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/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"
CPPCHECK_FLAGS := --enable=all \
--inconclusive \
--error-exitcode=1 \
--check-level=exhaustive \
--suppress=missingIncludeSystem \
--suppress=unmatchedSuppression \
--suppress=unusedFunction \
--suppress=staticFunction \
--inline-suppr \
$(INCLUDES)
# Sources & Build Directories
SRCS := src/lib/int/int.c src/lib/utils/utils.c
TEST_SRC := tests/test_learn.c
FUZZ_SRC := tests/fuzz_char.c
STRING_SRCS := src/string.c src/utils.c $(LIBSTR_DIR)/src/string.c
TEST_STRING_SRC := tests/test_string.c
BIN_DIR := tests/bin
CACHE_DIR := tests/cache
TEST_BIN := $(BIN_DIR)/test_learn_runner
TSAN_BIN := $(BIN_DIR)/test_tsan_runner
FUZZ_BIN := $(BIN_DIR)/fuzz_char_runner
COV_BIN := $(BIN_DIR)/test_cov_runner
TEST_STRING_BIN := $(BIN_DIR)/test_string_runner
# ==============================================================================
# Targets & Workflow Rules
# ==============================================================================
.PHONY: all test test-string sanitize check check-sources analyze cppcheck fuzz cov-build cov clean
all: test
$(BIN_DIR) $(CACHE_DIR):
@mkdir -p $@
# --- Compilation Targets ---
$(TEST_BIN): $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) $^ -o $@
$(TEST_STRING_BIN): $(STRING_SRCS) $(TEST_STRING_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) -I$(LIBSTR_DIR)/include $^ -o $@
$(TSAN_BIN): $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) -fsanitize=thread $(INCLUDES) $^ -o $@
$(FUZZ_BIN): $(SRCS) $(FUZZ_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) -fsanitize=fuzzer,address,undefined $(INCLUDES) $^ -o $@
# --- Testing & Sanitizer Suites ---
test: $(TEST_BIN)
@echo "=== Running Unit Tests (ASan + UBSan) ==="
@$(ASAN_ENV) ./$(TEST_BIN)
test-string: $(TEST_STRING_BIN)
@echo "=== Running vec_string Unit Tests (ASan + UBSan) ==="
@$(ASAN_ENV) ./$(TEST_STRING_BIN)
sanitize: $(TEST_BIN) $(TSAN_BIN)
@echo "\n=== [1/2] Running Address + UndefinedBehavior Sanitizers ==="
@$(ASAN_ENV) ./$(TEST_BIN)
@echo "\n=== [2/2] Running ThreadSanitizer ==="
@./$(TSAN_BIN)
@echo "\n>>> Sanitizers passed with zero defects."
# Unified master check: runtime sanitizers, static analyzer, and cppcheck
check: sanitize analyze cppcheck
@echo "\n=============================================="
@echo " ALL TESTS, SANITIZERS & STATIC CHECKS PASSED "
@echo "=============================================="
fuzz: $(FUZZ_BIN)
@echo "=== Starting Fuzzer (Press Ctrl+C to stop) ==="
@$(ASAN_ENV) ./$(FUZZ_BIN) -max_total_time=60
# --- Coverage Profiling ---
cov-build: $(SRCS) $(TEST_SRC) | $(BIN_DIR)
$(CC) $(CFLAGS) $(SAN_FLAGS) -fprofile-instr-generate -fcoverage-mapping $(INCLUDES) $^ -o $(COV_BIN)
cov: cov-build | $(CACHE_DIR)
@echo "=== Recording Coverage Profile Data ==="
@$(ASAN_ENV) LLVM_PROFILE_FILE="$(CACHE_DIR)/test_char.profdata_raw" ./$(COV_BIN)
@$(LLVM_PROFDATA) merge -sparse $(CACHE_DIR)/test_char.profdata_raw -o $(CACHE_DIR)/test_char.profdata
@echo "\n=== Line & Branch Coverage Report: src/lib/char/char.c ==="
@$(LLVM_COV) report $(COV_BIN) -instr-profile=$(CACHE_DIR)/test_char.profdata src/lib/char/char.c
@$(LLVM_COV) show $(COV_BIN) -instr-profile=$(CACHE_DIR)/test_char.profdata src/lib/char/char.c --format=html > coverage.html
@echo "\nDetailed HTML report written to coverage.html."
# --- Static Analysis & Object Checking ---
check-sources: | $(BIN_DIR)
@echo "=== Compiling Sources to Object Files (ASan + UBSan) ==="
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) -c src/lib/char/char.c -o $(BIN_DIR)/char.o
$(CC) $(CFLAGS) $(SAN_FLAGS) $(INCLUDES) -c src/lib/utils/utils.c -o $(BIN_DIR)/utils.o
@echo "Library sources compiled cleanly."
analyze:
@echo "=== Running Clang Static Analyzer ==="
@$(CC) $(CFLAGS) $(INCLUDES) \
--analyze \
-Xanalyzer -analyzer-output=text \
-Xanalyzer -analyzer-checker=core,unix,deadcode,security \
$(SRCS)
@echo "Clang Static Analyzer complete: zero defects."
cppcheck:
@echo "=== Running Cppcheck Static Analysis ==="
@$(CPPCHECK) $(CPPCHECK_FLAGS) include/ src/
@echo "Cppcheck passed with zero defects."
# --- Housekeeping ---
clean:
rm -rf $(BIN_DIR)/* $(CACHE_DIR)/* coverage.html
-112
View File
@@ -1,112 +0,0 @@
/*
* Andrew Haynes
* dmm.dev@icloud.com
* No LICENSE
* Vector Library For C
*/
#ifndef CHAR_H
#define CHAR_H
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utils.h>
typedef struct
{
char* arr;
size_t size;
size_t capacity;
size_t max_size;
} Vec8_t;
int
is_valid(const Vec8_t* vec);
Vec8_t
create(const char* buf, const size_t len);
Vec8_t
push_back(Vec8_t* vec, const char val);
Vec8_t
pop_back(Vec8_t* ptr);
Vec8_t
reserve(const Vec8_t* ptr, const size_t max_size);
Vec8_t
shrink_to_fit(Vec8_t* ptr);
int
swap(Vec8_t* ptr, Vec8_t* ptr_other);
char*
data(const Vec8_t* ptr);
size_t
capacity(const Vec8_t* ptr);
size_t
max_size(const Vec8_t* ptr);
void delete (const Vec8_t* vec);
Vec8_t
clear(const Vec8_t* vec);
char
at(const Vec8_t* vec, const size_t idx);
void
print_vec(const Vec8_t* vec);
int
begin(const Vec8_t* vec);
int
end(const Vec8_t* vec);
char
front(const Vec8_t* vec);
char
back(const Vec8_t* vec);
int
empty(const Vec8_t* vec);
__attribute__((overloadable)) Vec8_t
erase(const Vec8_t* vec, const size_t iter);
__attribute__((overloadable)) Vec8_t
erase(const Vec8_t* vec, const size_t iter_start, const size_t iter_end);
__attribute__((overloadable)) Vec8_t
resize(const Vec8_t* vec, const size_t size);
__attribute__((overloadable)) Vec8_t
resize(Vec8_t* vec, const size_t size, const char val);
__attribute__((overloadable)) Vec8_t
assign(const Vec8_t* vec, const Vec8_t* iterator, const size_t iter_start,
const size_t iter_end);
__attribute__((overloadable)) Vec8_t
assign(const Vec8_t* vec, const size_t amount, const char val);
__attribute__((overloadable)) Vec8_t
insert(const Vec8_t* vec, const size_t iter, const char val);
__attribute__((overloadable)) Vec8_t
insert(const Vec8_t* vec, const size_t iter, const size_t amount,
const char val);
__attribute__((overloadable)) Vec8_t
insert(const Vec8_t* dst_vec, const Vec8_t* src_vec, const size_t iter,
const size_t iter_start, const size_t iter_end);
#endif
+113
View File
@@ -0,0 +1,113 @@
#ifndef LIBVEC_CHAR_H
#define LIBVEC_CHAR_H
#include <libvec/utils.h>
// Will add DOCS later
typedef struct
{
char* array;
size_t size;
size_t capacity;
size_t max_size;
} vec_char;
__attribute__((overloadable)) size_t
__null_check(const vec_char* 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 vec_char* ptr, err_t* err);
vec_char
vec_char_cpy(const char* src, const size_t src_size, err_t* err);
void
vec_char_push_back(vec_char* ptr, const char val, err_t* err);
void
vec_char_pop_back(vec_char* ptr, err_t* err);
void
vec_char_reserve(vec_char* ptr, const size_t capacity, err_t* err);
void
vec_char_shrink_to_fit(vec_char* ptr, err_t* err);
void
vec_char_swap(vec_char* ptr_a, vec_char* ptr_b, err_t* err);
const char*
vec_char_data(const vec_char* ptr, err_t* err);
size_t
vec_char_size(const vec_char* ptr, err_t* err);
size_t
vec_char_capacity(const vec_char* ptr, err_t* err);
size_t
vec_char_max_size(const vec_char* ptr, err_t* err);
void
vec_char_delete(vec_char* ptr, err_t* err);
void
vec_char_clear(vec_char* ptr, err_t* err);
char*
vec_char_at(const vec_char* ptr, const size_t idx, err_t* err);
size_t
vec_char_begin(const vec_char* ptr, err_t* err);
size_t
vec_char_end(const vec_char* ptr, err_t* err);
char
vec_char_front(const vec_char* ptr, err_t* err);
char
vec_char_back(const vec_char* ptr, err_t* err);
size_t
vec_char_empty(const vec_char* ptr, err_t* err);
__attribute__((overloadable)) void
vec_char_erase(vec_char* ptr, const size_t iter, err_t* err);
__attribute__((overloadable)) void
vec_char_erase(vec_char* ptr, const size_t iter_start, const size_t iter_end,
err_t* err);
__attribute__((overloadable)) void
vec_char_resize(vec_char* ptr, const size_t size, err_t* err);
__attribute__((overloadable)) void
vec_char_resize(vec_char* ptr, const size_t size, const char val, err_t* err);
__attribute__((overloadable)) void
vec_char_assign(vec_char* ptr, const vec_char* iterator,
const size_t iter_start, const size_t iter_end, err_t* err);
__attribute__((overloadable)) void
vec_char_assign(vec_char* ptr, const size_t amount, const char val, err_t* err);
__attribute__((overloadable)) void
vec_char_insert(vec_char* ptr, const size_t iter, const char val, err_t* err);
__attribute__((overloadable)) void
vec_char_insert(vec_char* ptr, const size_t iter, const size_t amount,
const char val, err_t* err);
__attribute__((overloadable)) void
vec_char_insert(vec_char* ptr, const vec_char* iterator, const size_t iter,
const size_t iter_start, const size_t iter_end, err_t* err);
#endif
+107
View File
@@ -0,0 +1,107 @@
#ifndef LIBVEC_FLOAT_H
#define LIBVEC_FLOAT_H
#include <libvec/utils.h>
// Will add DOCS later
typedef struct
{
float* array;
size_t size;
size_t capacity;
size_t max_size;
} vec_float;
void
vec_float_print_vec(const vec_float* ptr, err_t* err);
vec_float
vec_float_cpy(const float* src, const size_t src_size, err_t* err);
void
vec_float_push_back(vec_float* ptr, const float val, err_t* err);
void
vec_float_pop_back(vec_float* ptr, err_t* err);
void
vec_float_reserve(vec_float* ptr, const size_t capacity, err_t* err);
void
vec_float_shrink_to_fit(vec_float* ptr, err_t* err);
void
vec_float_swap(vec_float* ptr_a, vec_float* ptr_b, err_t* err);
const float*
vec_float_data(const vec_float* ptr, err_t* err);
size_t
vec_float_size(const vec_float* ptr, err_t* err);
size_t
vec_float_capacity(const vec_float* ptr, err_t* err);
size_t
vec_float_max_size(const vec_float* ptr, err_t* err);
void
vec_float_delete(vec_float* ptr, err_t* err);
void
vec_float_clear(vec_float* ptr, err_t* err);
float*
vec_float_at(const vec_float* ptr, const size_t idx, err_t* err);
size_t
vec_float_begin(const vec_float* ptr, err_t* err);
size_t
vec_float_end(const vec_float* ptr, err_t* err);
float
vec_float_front(const vec_float* ptr, err_t* err);
float
vec_float_back(const vec_float* ptr, err_t* err);
size_t
vec_float_empty(const vec_float* ptr, err_t* err);
__attribute__((overloadable)) void
vec_float_erase(vec_float* ptr, const size_t iter, err_t* err);
__attribute__((overloadable)) void
vec_float_erase(vec_float* ptr, const size_t iter_start, const size_t iter_end,
err_t* err);
__attribute__((overloadable)) void
vec_float_resize(vec_float* ptr, const size_t size, err_t* err);
__attribute__((overloadable)) void
vec_float_resize(vec_float* ptr, const size_t size, const float val,
err_t* err);
__attribute__((overloadable)) void
vec_float_assign(vec_float* ptr, const vec_float* iterator,
const size_t iter_start, const size_t iter_end, err_t* err);
__attribute__((overloadable)) void
vec_float_assign(vec_float* ptr, const size_t amount, const float val,
err_t* err);
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const size_t iter, const float val,
err_t* err);
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const size_t iter, const size_t amount,
const float val, err_t* err);
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const vec_float* iterator, const size_t iter,
const size_t iter_start, const size_t iter_end, err_t* err);
#endif
+113
View File
@@ -0,0 +1,113 @@
#ifndef LIBVEC_INT_H
#define LIBVEC_INT_H
#include <libvec/utils.h>
// Will add DOCS later
typedef struct
{
int* array;
size_t size;
size_t capacity;
size_t max_size;
} vec_int;
__attribute__((overloadable)) size_t
__null_check(const vec_int* 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 vec_int* ptr, err_t* err);
vec_int
vec_int_cpy(const int* src, const size_t src_size, err_t* err);
void
vec_int_push_back(vec_int* ptr, const int val, err_t* err);
void
vec_int_pop_back(vec_int* ptr, err_t* err);
void
vec_int_reserve(vec_int* ptr, const size_t capacity, err_t* err);
void
vec_int_shrink_to_fit(vec_int* ptr, err_t* err);
void
vec_int_swap(vec_int* ptr_a, vec_int* ptr_b, err_t* err);
const int*
vec_int_data(const vec_int* ptr, err_t* err);
size_t
vec_int_size(const vec_int* ptr, err_t* err);
size_t
vec_int_capacity(const vec_int* ptr, err_t* err);
size_t
vec_int_max_size(const vec_int* ptr, err_t* err);
void
vec_int_delete(vec_int* ptr, err_t* err);
void
vec_int_clear(vec_int* ptr, err_t* err);
int*
vec_int_at(const vec_int* ptr, const size_t idx, err_t* err);
size_t
vec_int_begin(const vec_int* ptr, err_t* err);
size_t
vec_int_end(const vec_int* ptr, err_t* err);
int
vec_int_front(const vec_int* ptr, err_t* err);
int
vec_int_back(const vec_int* ptr, err_t* err);
size_t
vec_int_empty(const vec_int* ptr, err_t* err);
__attribute__((overloadable)) void
vec_int_erase(vec_int* ptr, const size_t iter, err_t* err);
__attribute__((overloadable)) void
vec_int_erase(vec_int* ptr, const size_t iter_start, const size_t iter_end,
err_t* err);
__attribute__((overloadable)) void
vec_int_resize(vec_int* ptr, const size_t size, err_t* err);
__attribute__((overloadable)) void
vec_int_resize(vec_int* ptr, const size_t size, const int val, err_t* err);
__attribute__((overloadable)) void
vec_int_assign(vec_int* ptr, const vec_int* iterator, const size_t iter_start,
const size_t iter_end, err_t* err);
__attribute__((overloadable)) void
vec_int_assign(vec_int* ptr, const size_t amount, const int val, err_t* err);
__attribute__((overloadable)) void
vec_int_insert(vec_int* ptr, const size_t iter, const int val, err_t* err);
__attribute__((overloadable)) void
vec_int_insert(vec_int* ptr, const size_t iter, const size_t amount,
const int val, err_t* err);
__attribute__((overloadable)) void
vec_int_insert(vec_int* ptr, const vec_int* iterator, const size_t iter,
const size_t iter_start, const size_t iter_end, err_t* err);
#endif
+115
View File
@@ -0,0 +1,115 @@
#ifndef LIBVEC_STRING_H
#define LIBVEC_STRING_H
#include <libstr/string.h>
#include <libvec/utils.h>
// Will add DOCS later
typedef struct
{
String* array;
size_t size;
size_t capacity;
size_t max_size;
} vec_string;
__attribute__((overloadable)) size_t
__null_check(const vec_string* ptr, err_t* status);
__attribute__((overloadable)) size_t
__null_check(const char* ptr, err_t* status);
void
vec_string_print_vec(const vec_string* ptr, err_t* err);
vec_string
vec_string_cpy(const String* src, const size_t src_size, err_t* err);
void
vec_string_push_back(vec_string* ptr, const String val, err_t* err);
void
vec_string_pop_back(vec_string* ptr, err_t* err);
void
vec_string_reserve(vec_string* ptr, const size_t capacity, err_t* err);
void
vec_string_shrink_to_fit(vec_string* ptr, err_t* err);
void
vec_string_swap(vec_string* ptr_a, vec_string* ptr_b, err_t* err);
const String*
vec_string_data(const vec_string* ptr, err_t* err);
size_t
vec_string_size(const vec_string* ptr, err_t* err);
size_t
vec_string_capacity(const vec_string* ptr, err_t* err);
size_t
vec_string_max_size(const vec_string* ptr, err_t* err);
void
vec_string_delete(vec_string* ptr, err_t* err);
void
vec_string_clear(vec_string* ptr, err_t* err);
String*
vec_string_at(const vec_string* ptr, const size_t idx, err_t* err);
size_t
vec_string_begin(const vec_string* ptr, err_t* err);
size_t
vec_string_end(const vec_string* ptr, err_t* err);
String
vec_string_front(const vec_string* ptr, err_t* err);
String
vec_string_back(const vec_string* ptr, err_t* err);
size_t
vec_string_empty(const vec_string* ptr, err_t* err);
__attribute__((overloadable)) void
vec_string_erase(vec_string* ptr, const size_t iter, err_t* err);
__attribute__((overloadable)) void
vec_string_erase(vec_string* ptr, const size_t iter_start,
const size_t iter_end, err_t* err);
__attribute__((overloadable)) void
vec_string_resize(vec_string* ptr, const size_t size, err_t* err);
__attribute__((overloadable)) void
vec_string_resize(vec_string* ptr, const size_t size, const String val,
err_t* err);
__attribute__((overloadable)) void
vec_string_assign(vec_string* ptr, const vec_string* iterator,
const size_t iter_start, const size_t iter_end, err_t* err);
__attribute__((overloadable)) void
vec_string_assign(vec_string* ptr, const size_t amount, const String val,
err_t* err);
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const size_t iter, const String val,
err_t* err);
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const size_t iter, const size_t amount,
const String val, err_t* err);
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const vec_string* iterator,
const size_t iter, const size_t iter_start,
const size_t iter_end, err_t* err);
#endif
View File
+65
View File
@@ -0,0 +1,65 @@
#ifndef UTILS_H
#define UTILS_H
#include <stddef.h>
#include <stdint.h>
static const size_t VEC_MAX = SIZE_MAX / sizeof(int);
#define ERROR_LIST(X) \
X(SUCCESS, 0, "No Errors Found") \
X(ERR_ALLOC_FAIL, (1u << 0), "Alloc :- Failed to allocate") \
X(ERR_VEC_NULL, (1u << 1), "Vector :- Given vector is null") \
X(ERR_BUF_NULL, (1u << 2), "Buffer :- NULL") \
X(ERR_SIZE_ZERO, (1u << 3), \
"Size :- Size is or is less than 0 or invalid") \
X(ERR_OUT_OF_BOUNDS, (1u << 4), "Bounds:- Value is out of bounds") \
X(ERR_DOUBLE_BUF, (1u << 5), \
"Buffer :- Both buffers are copies of each other") \
X(ERR_SIZE_OVERFLOW, (1u << 6), \
"Max :- Vector Max value is overloaded") \
X(ERR_ORIGIN_UNALTERABLE, (1u << 7), \
"Origin :- Origin is non-null and cannot be overridden") \
X(ERR_STR_NULL, (1u << 8), "String :- String is null value") \
X(ERR_ERR_T_NULL, (1u << 9), "ERR_T :- Passed error is null")
typedef enum
{
#define X(name, val, desc) name = (val),
ERROR_LIST(X)
#undef X
} ERROR_CODES;
/* NOTE
* Value is the return value for functions like _vec_char_capacity
* Err is the unsigned bit range for all the errors tracked
* origin is a string for where the bug started and IS CHANGED ONLY WHEN NULL
* */
typedef struct
{
unsigned int flags;
char* origin; // Where the main bug started
} err_t;
#define ERR_T_INIT { .flags = 0, .origin = NULL }
#define VEC_INIT \
{ .array = NULL, .size = 0, .capacity = 0, .max_size = VEC_MAX }
void
vec_print_errs(const err_t err);
void
vec_print_bits(unsigned int num);
size_t
__origin_override(err_t* status, char* str);
__attribute__((overloadable)) size_t
__null_check(const float* ptr, err_t* status);
#define LOG(msg) printf("LOG: %s\n", msg) /**< Print log message*/
#define DEBUG(msg) printf("DEBUG: %s\n", msg) /**< Print debug message*/
#define find_len(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
-31
View File
@@ -1,31 +0,0 @@
#ifndef UTILS_H
#define UTILS_H
#include <stddef.h>
#include <stdint.h>
#define CAPACITY 1024
#define SUCCESS 0
#define FAILURE 1
#define ERR_ALLOC_FAIL 20
#define ERR_BUF_NULL 21
#define ERR_SIZE_ZERO 22
#define ERR_VECTOR_NULL 23
#define ERR_MAX_PASSED 24
#define ERR_OUT_OF_BOUNDS 25
#define ERR_NULL 26
#define ERR_DOUBLE_BUF 27
extern const char* error_messages[];
#define LOG(msg) printf("LOG: %s\n", msg) /**< Print log message*/
#define LOGERROR(error_code) \
printf("ERROR: %s\n", \
error_messages[error_code]) /**< Print log error message*/
#define find_len(arr) sizeof(arr) / sizeof(arr[0])
static const size_t VEC_MAX = SIZE_MAX / sizeof(int);
#endif
BIN
View File
Binary file not shown.
+702 -416
View File
File diff suppressed because it is too large Load Diff
+891
View File
@@ -0,0 +1,891 @@
#include <libvec/float.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__((overloadable)) size_t
__null_check(const vec_float* 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->array == nullptr)
{
status->flags |= ERR_BUF_NULL;
}
return status->flags;
}
void
vec_float_print_vec(const vec_float* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
return;
}
for (size_t i = 0; i < ptr->size; i++)
{
printf("%f ", ptr->array[i]);
}
printf("\n");
}
vec_float
vec_float_cpy(const float* src, const size_t src_size, err_t* err)
{
vec_float 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.max_size)
{
__origin_override(err, "CPY");
err->flags |= ERR_SIZE_OVERFLOW;
return self;
}
self.array = malloc(src_size * sizeof(float));
if (self.array == nullptr)
{
__origin_override(err, "CPY");
err->flags |= ERR_ALLOC_FAIL;
return self;
}
memcpy(self.array, src, src_size * sizeof(float));
self.size = src_size;
self.capacity = src_size;
return self;
}
void
vec_float_push_back(vec_float* ptr, const float val, err_t* err)
{
err_t status = ERR_T_INIT;
float* 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->size + 1 > ptr->max_size)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
if ((status.flags & ERR_BUF_NULL) != 0)
{
res = malloc(1 * sizeof(float));
if (res == nullptr)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->array = res;
ptr->capacity = 1;
ptr->size = 0;
}
else if (ptr->size + 1 > ptr->capacity)
{
size_t dst_cap = (ptr->capacity / 2) + ptr->capacity;
if (dst_cap == ptr->capacity)
{
dst_cap++;
}
if (dst_cap > ptr->max_size)
{
dst_cap = ptr->max_size;
DEBUG(
"Capacity cannot be grown any further due "
"to hitting max size");
}
res = realloc(ptr->array, dst_cap * sizeof(float));
if (res == nullptr)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
ptr->array = res;
ptr->capacity = dst_cap;
}
ptr->array[ptr->size] = val;
ptr->size++;
return;
}
void
vec_float_pop_back(vec_float* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
__origin_override(err, "POP_BACK");
return;
}
if (ptr->size == 0)
{
__origin_override(err, "POP_BACK");
err->flags |= ERR_SIZE_ZERO;
return;
}
ptr->array[ptr->size - 1] = 0;
ptr->size--;
}
void
vec_float_reserve(vec_float* 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->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;
}
float* res = realloc(ptr->array, capacity * sizeof(float));
if (res == nullptr)
{
__origin_override(err, "RESERVE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->array = res;
ptr->capacity = capacity;
if (ptr->size > capacity)
{
ptr->size = capacity;
}
return;
}
void
vec_float_shrink_to_fit(vec_float* 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->size == 0)
{
__origin_override(err, "SHRINK_TO_FIT");
err->flags |= ERR_SIZE_ZERO;
return;
}
vec_float_reserve(ptr, ptr->size, err);
}
void
vec_float_swap(vec_float* ptr_a, vec_float* 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;
}
vec_float self = *ptr_a;
*ptr_a = *ptr_b;
*ptr_b = self;
return;
}
const float*
vec_float_data(const vec_float* 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->array[0];
}
size_t
vec_float_size(const vec_float* 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->size;
}
size_t
vec_float_capacity(const vec_float* 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->capacity;
}
size_t
vec_float_max_size(const vec_float* 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->max_size;
}
void
vec_float_delete(vec_float* 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->array != nullptr)
{
free(ptr->array);
ptr->array = nullptr;
}
ptr->size = 0;
ptr->capacity = 0;
}
void
vec_float_clear(vec_float* 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->size > 0)
{
memset(ptr->array, 0, ptr->size);
ptr->size = 0;
}
}
float*
vec_float_at(const vec_float* 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->size)
{
__origin_override(err, "AT");
err->flags |= ERR_OUT_OF_BOUNDS;
return nullptr;
}
return &ptr->array[idx];
}
size_t
vec_float_begin(const vec_float* 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_float_end(const vec_float* 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->size == 0)
{
__origin_override(err, "END");
err->flags |= ERR_SIZE_ZERO;
return status.flags;
}
return (size_t)(ptr->size - 1);
}
float
vec_float_front(const vec_float* 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_float_at(ptr, 0, err) == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return 0;
}
return *vec_float_at(ptr, 0, err);
}
float
vec_float_back(const vec_float* 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_float_at(ptr, 0, err) == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return 0;
}
return *vec_float_at(ptr, ptr->size - 1, err);
}
size_t
vec_float_empty(const vec_float* 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->size == 0)
{
return ptr->size;
}
return status.flags;
}
__attribute__((overloadable)) void
vec_float_erase(vec_float* 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->size)
{
return;
}
memmove(&ptr->array[iter], &ptr->array[iter + 1],
(ptr->size - iter - 1) * sizeof(float));
ptr->array[ptr->size - 1] = 0;
ptr->size--;
return;
}
__attribute__((overloadable)) void
vec_float_erase(vec_float* 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->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->array[iter_start], &ptr->array[iter_end],
(ptr->size - iter_end) * sizeof(float));
memset(&ptr->array[ptr->size - diff], 0, sizeof(float) * diff);
ptr->size -= diff;
return;
}
__attribute__((overloadable)) void
vec_float_resize(vec_float* 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->max_size;
err_t verr = ERR_T_INIT;
vec_float_reserve(ptr, size, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
for (size_t i = 0; i < size; i++)
{
ptr->array[i] = 0;
}
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->max_size)
{
tmpcp = size;
}
vec_float_reserve(ptr, tmpcp, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != tmpcp)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
memset(&ptr->array[size], 0, ptr->size - size);
}
if (ptr->size < size && size <= ptr->capacity)
{
memset(&ptr->array[ptr->size], 0, size - ptr->size);
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_float_resize(vec_float* ptr, const size_t size, const float 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->max_size;
err_t verr = ERR_T_INIT;
vec_float_reserve(ptr, size, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
for (size_t i = 0; i < size; i++)
{
ptr->array[i] = val;
}
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->max_size)
{
tmpcp = size;
}
vec_float_reserve(ptr, tmpcp, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
memset(&ptr->array[size], val, ptr->size - size);
}
if (ptr->size < size && size <= ptr->capacity)
{
memset(&ptr->array[ptr->size], val, size - ptr->size);
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_float_assign(vec_float* ptr, const vec_float* 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->array == iterator->array)
{
__origin_override(err, "ASSIGN");
err->flags |= ERR_DOUBLE_BUF;
return;
}
if (iterator->size < iter_end || iter_end <= iter_start)
{
__origin_override(err, "ASSIGN");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
vec_float_erase(ptr, vec_float_begin(ptr, &status),
vec_float_end(ptr, &status) + 1, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
vec_float_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++)
{
float* res = vec_float_at(iterator, i, &status);
if (res == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
vec_float_push_back(ptr, *res, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_float_assign(vec_float* ptr, const size_t amount, const float 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_float_erase(ptr, vec_float_begin(ptr, &status),
vec_float_end(ptr, &status) + 1, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
vec_float_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_float_push_back(ptr, val, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const size_t iter, const float 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)
{
float* res = malloc(1 * sizeof(float));
if (res == nullptr)
{
__origin_override(err, "INSERT");
err->flags |= ERR_BUF_NULL;
return;
}
ptr->array = res;
ptr->capacity = 1;
ptr->array[0] = val;
ptr->size = 1;
return;
}
if (ptr->max_size < ptr->size + 1)
{
__origin_override(err, "INSERT");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
if (iter > ptr->size)
{
__origin_override(err, "INSERT");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
vec_float_push_back(ptr, 0, &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
for (size_t i = ptr->size - 1; i > iter; i--)
{
ptr->array[i] = ptr->array[i - 1];
}
ptr->array[iter] = val;
return;
}
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const size_t iter, const size_t amount,
const float 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->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_float_insert(ptr, i, val, &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_float_insert(vec_float* ptr, const vec_float* 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->size ||
iter > ptr->size)
{
__origin_override(err, "INSERT");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
if (ptr->array == iterator->array)
{
__origin_override(err, "INSERT");
err->flags |= ERR_DOUBLE_BUF;
return;
}
for (size_t i = iter_start; i < iter_end; i++)
{
vec_float_insert(ptr, iter + (i - iter_start),
iterator->array[i], &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
}
return;
}
+894
View File
@@ -0,0 +1,894 @@
#include <libvec/int.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__((overloadable)) size_t
__null_check(const vec_int* 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->array == nullptr)
{
status->flags |= ERR_BUF_NULL;
}
return status->flags;
}
void
vec_int_print_vec(const vec_int* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
return;
}
for (size_t i = 0; i < ptr->size; i++)
{
printf("%d ", ptr->array[i]);
}
printf("\n");
}
vec_int
vec_int_cpy(const int* src, const size_t src_size, err_t* err)
{
vec_int 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.max_size)
{
__origin_override(err, "CPY");
err->flags |= ERR_SIZE_OVERFLOW;
return self;
}
self.array = malloc(src_size * sizeof(int));
if (self.array == nullptr)
{
__origin_override(err, "CPY");
err->flags |= ERR_ALLOC_FAIL;
return self;
}
memcpy(self.array, src, src_size * sizeof(int));
self.size = src_size;
self.capacity = src_size;
return self;
}
void
vec_int_push_back(vec_int* 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->size + 1 > ptr->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->array = res;
ptr->capacity = 1;
ptr->size = 0;
}
else if (ptr->size + 1 > ptr->capacity)
{
size_t dst_cap = (ptr->capacity / 2) + ptr->capacity;
if (dst_cap == ptr->capacity)
{
dst_cap++;
}
if (dst_cap > ptr->max_size)
{
dst_cap = ptr->max_size;
DEBUG(
"Capacity cannot be grown any further due "
"to hitting max size");
}
res = realloc(ptr->array, dst_cap * sizeof(int));
if (res == nullptr)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
ptr->array = res;
ptr->capacity = dst_cap;
}
ptr->array[ptr->size] = val;
ptr->size++;
return;
}
void
vec_int_pop_back(vec_int* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
__origin_override(err, "POP_BACK");
return;
}
if (ptr->size == 0)
{
__origin_override(err, "POP_BACK");
err->flags |= ERR_SIZE_ZERO;
return;
}
ptr->array[ptr->size - 1] = 0;
ptr->size--;
}
void
vec_int_reserve(vec_int* 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->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->array, capacity * sizeof(int));
if (res == nullptr)
{
__origin_override(err, "RESERVE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->array = res;
ptr->capacity = capacity;
if (ptr->size > capacity)
{
ptr->size = capacity;
}
return;
}
void
vec_int_shrink_to_fit(vec_int* 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->size == 0)
{
__origin_override(err, "SHRINK_TO_FIT");
err->flags |= ERR_SIZE_ZERO;
return;
}
vec_int_reserve(ptr, ptr->size, err);
}
void
vec_int_swap(vec_int* ptr_a, vec_int* 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;
}
vec_int self = *ptr_a;
*ptr_a = *ptr_b;
*ptr_b = self;
return;
}
const int*
vec_int_data(const vec_int* 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->array[0];
}
size_t
vec_int_size(const vec_int* 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->size;
}
size_t
vec_int_capacity(const vec_int* 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->capacity;
}
size_t
vec_int_max_size(const vec_int* 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->max_size;
}
void
vec_int_delete(vec_int* 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->array != nullptr)
{
free(ptr->array);
ptr->array = nullptr;
}
ptr->size = 0;
ptr->capacity = 0;
}
void
vec_int_clear(vec_int* 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->size > 0)
{
memset(ptr->array, 0, ptr->size * sizeof(int));
ptr->size = 0;
}
}
int*
vec_int_at(const vec_int* 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->size)
{
__origin_override(err, "AT");
err->flags |= ERR_OUT_OF_BOUNDS;
return nullptr;
}
return &ptr->array[idx];
}
size_t
vec_int_begin(const vec_int* 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 vec_int* 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->size == 0)
{
__origin_override(err, "END");
err->flags |= ERR_SIZE_ZERO;
return status.flags;
}
return (size_t)(ptr->size - 1);
}
int
vec_int_front(const vec_int* 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 vec_int* 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->size - 1, err);
}
size_t
vec_int_empty(const vec_int* 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->size == 0)
{
return ptr->size;
}
return status.flags;
}
__attribute__((overloadable)) void
vec_int_erase(vec_int* 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->size)
{
return;
}
memmove(&ptr->array[iter], &ptr->array[iter + 1],
(ptr->size - iter - 1) * sizeof(int));
ptr->array[ptr->size - 1] = 0;
ptr->size--;
return;
}
__attribute__((overloadable)) void
vec_int_erase(vec_int* 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->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->array[iter_start], &ptr->array[iter_end],
(ptr->size - iter_end) * sizeof(int));
memset(&ptr->array[ptr->size - diff], 0, sizeof(int) * diff);
ptr->size -= diff;
return;
}
__attribute__((overloadable)) void
vec_int_resize(vec_int* 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->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->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
memset(ptr->array, 0, size * sizeof(int));
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->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->capacity != tmpcp)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
memset(&ptr->array[size], 0, (ptr->size - size) * sizeof(int));
}
if (ptr->size < size && size <= ptr->capacity)
{
memset(&ptr->array[ptr->size], 0,
(size - ptr->size) * sizeof(int));
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_int_resize(vec_int* 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->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->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
for (size_t i = 0; i < size; i++)
{
ptr->array[i] = val;
}
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->max_size)
{
tmpcp = size;
}
vec_int_reserve(ptr, tmpcp, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
for (size_t i = size; i < ptr->size; i++)
{
ptr->array[i] = 0;
}
}
if (ptr->size < size && size <= ptr->capacity)
{
for (size_t i = ptr->size; i < size; i++)
{
ptr->array[i] = val;
}
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_int_assign(vec_int* ptr, const vec_int* 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->array == iterator->array)
{
__origin_override(err, "ASSIGN");
err->flags |= ERR_DOUBLE_BUF;
return;
}
if (iterator->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(vec_int* 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(vec_int* 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->array = res;
ptr->capacity = 1;
ptr->array[0] = val;
ptr->size = 1;
return;
}
if (ptr->max_size < ptr->size + 1)
{
__origin_override(err, "INSERT");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
if (iter > ptr->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->size - 1; i > iter; i--)
{
ptr->array[i] = ptr->array[i - 1];
}
ptr->array[iter] = val;
return;
}
__attribute__((overloadable)) void
vec_int_insert(vec_int* 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->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(vec_int* ptr, const vec_int* 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->size ||
iter > ptr->size)
{
__origin_override(err, "INSERT");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
if (ptr->array == iterator->array)
{
__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->array[i],
&status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
}
return;
}
BIN
View File
Binary file not shown.
+22 -41
View File
@@ -6,59 +6,40 @@
*/ */
/* /*
* Types Wanted: * Types Wanted:
* Char 8 Bits
* Float 32 Bits with suffix of 'f'
* Int 32 bits
* String 32 Bits with suffix of 's' * String 32 Bits with suffix of 's'
*/ */
#include <libvec/utils.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "char.h" void
#include "utils.h" print_bits(unsigned int num);
int int
main() main()
{ {
char ar1[] = { '1', '2', '3', '4' }; // TODO:
char ar2[] = { 'a', 'b', 'c', 'd' }; //
// Vec8_t v1; // Fix the error checking because you make a status to hold all local
Vec8_t v1 = create(ar2, find_len(ar2)); // errors but then in some cases you or them to the main err handler and
// print_vec(&v1); // if the error doesnt need to be there like a good error but one that
// printf("Hello\n"); // exists (i.e push_back getting a blank array), then you will have a
// v1 = assign(&v1, &v2, 0, 1); // bloated and broken error handler
v1 = reserve(&v1, 9); //
print_vec(&v1); // Your pop back is a great example of how to handle it and is a clean
v1 = insert(&v1, 1, 'x'); // if statement as a header to all functions.
v1 = resize(&v1, 12); // char res[4] = { 'a', 'b', 'c', 'd' };
// v1 = insert(&v1, 1, 5, 'a'); err_t status = ERR_T_INIT;
// printf("%c", at(&v1, 1)); status.flags |= ERR_BUF_NULL | ERR_VEC_NULL | ERR_STR_NULL;
// printf("RESERVED SIZE: %zu", v1.max_size);
print_vec(&v1);
// v2 = resize(&v2, 3);
// print_vec(&v2); unsigned int mask = 0;
mask = ERR_BUF_NULL ^ status.flags;
// if (swap(&v1, &v2)) vec_print_bits(mask);
// { vec_print_bits(status.flags);
// print_vec(&v1); vec_print_errs(status);
// print_vec(&v2);
// }
// Vec8_t v1 = create(nullptr, 0);
// v1 = reserve(&v1, 10);
// v1 = pop_back(&v1);
// for (int i = 0; i < 10; i++)
// {
// v1 = push_back(&v1, 'a');
// }
// print_vec(&v1);
// printf("SIZE: %zu\n", v1.size);
// v1 = push_back(&v1, 'a');
// print_vec(&v1);
// printf("SIZE: %zu\n", v1.size);
delete(&v1);
// delete(&v2);
return 0; return 0;
} }
+938
View File
@@ -0,0 +1,938 @@
#include "libstr/string.h"
#include <libvec/string.h>
#include <libvec/utils.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__((overloadable)) size_t
__null_check(const vec_string* 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->array == nullptr)
{
status->flags |= ERR_BUF_NULL;
}
return status->flags;
}
__attribute__((overloadable)) size_t
__null_check(const String* ptr, err_t* status)
{
if (status == nullptr)
{
return ERR_ERR_T_NULL;
}
if (ptr == nullptr)
{
status->flags |= ERR_STR_NULL;
return status->flags;
}
if (ptr->data == nullptr)
{
status->flags |= ERR_BUF_NULL;
}
return status->flags;
}
void
vec_string_print_vec(const vec_string* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
return;
}
for (size_t i = 0; i < ptr->size; i++)
{
printf("%s ", ptr->array[i].data);
}
printf("\n");
}
vec_string
vec_string_cpy(const String* src, const size_t src_size, err_t* err)
{
vec_string 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.max_size)
{
__origin_override(err, "CPY");
err->flags |= ERR_SIZE_OVERFLOW;
return self;
}
self.array = malloc(src_size * sizeof(String));
if (self.array == nullptr)
{
__origin_override(err, "CPY");
err->flags |= ERR_ALLOC_FAIL;
return self;
}
memcpy(self.array, src, src_size * sizeof(String));
self.size = src_size;
self.capacity = src_size;
return self;
}
void
vec_string_push_back(vec_string* ptr, const String val, err_t* err)
{
err_t status = ERR_T_INIT;
String* 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->size + 1 > ptr->max_size)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
if ((status.flags & ERR_BUF_NULL) != 0)
{
res = malloc(1 * sizeof(String));
if (res == nullptr)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->array = res;
ptr->capacity = 1;
ptr->size = 0;
}
else if (ptr->size + 1 > ptr->capacity)
{
size_t dst_cap = (ptr->capacity / 2) + ptr->capacity;
if (dst_cap == ptr->capacity)
{
dst_cap++;
}
if (dst_cap > ptr->max_size)
{
dst_cap = ptr->max_size;
DEBUG(
"Capacity cannot be grown any further due "
"to hitting max size");
}
res = realloc(ptr->array, dst_cap * sizeof(String));
if (res == nullptr)
{
__origin_override(err, "PUSH_BACK");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
ptr->array = res;
ptr->capacity = dst_cap;
}
ptr->array[ptr->size] = val;
ptr->size++;
return;
}
void
vec_string_pop_back(vec_string* ptr, err_t* err)
{
if (__null_check(ptr, err) != 0)
{
__origin_override(err, "POP_BACK");
return;
}
if (ptr->size == 0)
{
__origin_override(err, "POP_BACK");
err->flags |= ERR_SIZE_ZERO;
return;
}
ptr->array[ptr->size - 1] = (String)STR_INIT;
ptr->size--;
}
void
vec_string_reserve(vec_string* 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->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;
}
String* res = realloc(ptr->array, capacity * sizeof(String));
if (res == nullptr)
{
__origin_override(err, "RESERVE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->array = res;
ptr->capacity = capacity;
if (ptr->size > capacity)
{
ptr->size = capacity;
}
return;
}
void
vec_string_shrink_to_fit(vec_string* 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->size == 0)
{
__origin_override(err, "SHRINK_TO_FIT");
err->flags |= ERR_SIZE_ZERO;
return;
}
vec_string_reserve(ptr, ptr->size, err);
}
void
vec_string_swap(vec_string* ptr_a, vec_string* 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;
}
vec_string self = *ptr_a;
*ptr_a = *ptr_b;
*ptr_b = self;
return;
}
const String*
vec_string_data(const vec_string* 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->array[0];
}
size_t
vec_string_size(const vec_string* 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->size;
}
size_t
vec_string_capacity(const vec_string* 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->capacity;
}
size_t
vec_string_max_size(const vec_string* 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->max_size;
}
void
vec_string_delete(vec_string* 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->array != nullptr)
{
free(ptr->array);
ptr->array = nullptr;
}
ptr->size = 0;
ptr->capacity = 0;
}
void
vec_string_clear(vec_string* 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->size > 0)
{
memset(ptr->array, 0, ptr->size * (sizeof(String)));
ptr->size = 0;
}
}
String*
vec_string_at(const vec_string* 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->size)
{
__origin_override(err, "AT");
err->flags |= ERR_OUT_OF_BOUNDS;
return nullptr;
}
return &ptr->array[idx];
}
size_t
vec_string_begin(const vec_string* 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_string_end(const vec_string* 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->size == 0)
{
__origin_override(err, "END");
err->flags |= ERR_SIZE_ZERO;
return status.flags;
}
return (size_t)(ptr->size - 1);
}
String
vec_string_front(const vec_string* ptr, err_t* err)
{
err_t status = ERR_T_INIT;
String tmp = STR_INIT;
if (__null_check(ptr, &status) != 0)
{
__origin_override(err, "FRONT");
err->flags |= status.flags;
return tmp;
}
if (vec_string_at(ptr, 0, err) == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return tmp;
}
return *vec_string_at(ptr, 0, err);
}
String
vec_string_back(const vec_string* 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 (String)STR_INIT;
}
if (vec_string_at(ptr, ptr->size - 1, err) == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return (String)STR_INIT;
}
return *vec_string_at(ptr, ptr->size - 1, err);
}
size_t
vec_string_empty(const vec_string* 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->size == 0)
{
return 1;
}
return 0;
}
__attribute__((overloadable)) void
vec_string_erase(vec_string* 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->size)
{
__origin_override(err, "ERASE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
memmove(&ptr->array[iter], &ptr->array[iter + 1],
(ptr->size - iter - 1) * sizeof(String));
ptr->array[ptr->size - 1] = (String)STR_INIT;
ptr->size--;
return;
}
__attribute__((overloadable)) void
vec_string_erase(vec_string* 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->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->array[iter_start], &ptr->array[iter_end],
(ptr->size - iter_end) * sizeof(String));
memset(&ptr->array[ptr->size - diff], 0, sizeof(String) * diff);
ptr->size -= diff;
return;
}
__attribute__((overloadable)) void
vec_string_resize(vec_string* 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->max_size;
err_t verr = ERR_T_INIT;
vec_string_reserve(ptr, size, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
for (size_t i = 0; i < size; i++)
{
ptr->array[i] = (String)STR_INIT;
}
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->max_size)
{
tmpcp = size;
}
vec_string_reserve(ptr, tmpcp, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != tmpcp)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
for (size_t i = size; i < ptr->size; i++)
{
ptr->array[i] = (String)STR_INIT;
}
}
if (ptr->size < size && size <= ptr->capacity)
{
for (size_t i = ptr->size; i < size; i++)
{
ptr->array[i] = (String)STR_INIT;
}
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_string_resize(vec_string* ptr, const size_t size, const String 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->size == size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
else if (size > ptr->max_size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
else if ((status.flags & ERR_BUF_NULL) != 0 || ptr->size == 0)
{
size_t max = ptr->max_size;
err_t verr = ERR_T_INIT;
vec_string_reserve(ptr, size, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
if (ptr->capacity != size)
{
__origin_override(err, "RESIZE");
err->flags |= ERR_ALLOC_FAIL;
return;
}
for (size_t i = 0; i < size; i++)
{
ptr->array[i] = val;
}
ptr->max_size = max;
ptr->size = size;
return;
}
else if (size > ptr->capacity)
{
size_t tmpcp = ptr->capacity;
size_t tmpmx = ptr->max_size;
err_t verr = ERR_T_INIT;
while (size > tmpcp)
{
tmpcp *= 2;
}
if (tmpcp > ptr->max_size)
{
tmpcp = size;
}
vec_string_reserve(ptr, tmpcp, &verr);
if (verr.flags != 0)
{
__origin_override(err, "RESIZE");
err->flags |= verr.flags;
return;
}
ptr->max_size = tmpmx;
}
if (size < ptr->size)
{
for (size_t i = size; i < ptr->size; i++)
{
ptr->array[i] = val;
}
}
if (ptr->size < size && size <= ptr->capacity)
{
for (size_t i = ptr->size; i < size; i++)
{
ptr->array[i] = val;
}
}
ptr->size = size;
return;
}
__attribute__((overloadable)) void
vec_string_assign(vec_string* ptr, const vec_string* 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->array == iterator->array)
{
__origin_override(err, "ASSIGN");
err->flags |= ERR_DOUBLE_BUF;
return;
}
if (iterator->size < iter_end || iter_end <= iter_start)
{
__origin_override(err, "ASSIGN");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
if (ptr->size > 0)
{
vec_string_erase(ptr, 0, ptr->size, &status);
}
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
vec_string_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++)
{
String* res = vec_string_at(iterator, i, &status);
if (res == nullptr)
{
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
vec_string_push_back(ptr, *res, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_string_assign(vec_string* ptr, const size_t amount, const String 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;
}
if (ptr->size > 0)
{
vec_string_erase(ptr, vec_string_begin(ptr, &status),
vec_string_end(ptr, &status) + 1, &status);
}
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
vec_string_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_string_push_back(ptr, val, &status);
if (status.flags != 0)
{
__origin_override(err, "ASSIGN");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const size_t iter, const String 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)
{
String* res = malloc(1 * sizeof(String));
if (res == nullptr)
{
__origin_override(err, "INSERT");
err->flags |= ERR_BUF_NULL;
return;
}
ptr->array = res;
ptr->capacity = 1;
ptr->array[0] = val;
ptr->size = 1;
return;
}
if (ptr->max_size < ptr->size + 1)
{
__origin_override(err, "INSERT");
err->flags |= ERR_SIZE_OVERFLOW;
return;
}
if (iter > ptr->size)
{
__origin_override(err, "INSERT");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
String empty = STR_INIT;
vec_string_push_back(ptr, empty, &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
for (size_t i = ptr->size - 1; i > iter; i--)
{
ptr->array[i] = ptr->array[i - 1];
}
ptr->array[iter] = val;
return;
}
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const size_t iter, const size_t amount,
const String 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 (iter > ptr->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_string_insert(ptr, i, val, &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
}
return;
}
__attribute__((overloadable)) void
vec_string_insert(vec_string* ptr, const vec_string* 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->size ||
iter > ptr->size)
{
__origin_override(err, "INSERT");
err->flags |= ERR_OUT_OF_BOUNDS;
return;
}
if (ptr->array == iterator->array)
{
__origin_override(err, "INSERT");
err->flags |= ERR_DOUBLE_BUF;
return;
}
for (size_t i = iter_start; i < iter_end; i++)
{
vec_string_insert(ptr, iter + (i - iter_start),
iterator->array[i], &status);
if (status.flags != 0)
{
__origin_override(err, "INSERT");
err->flags |= status.flags;
return;
}
}
return;
}
+91 -11
View File
@@ -1,12 +1,92 @@
#include <utils.h> #include <libvec/utils.h>
#include <stdio.h>
const char* error_messages[] = { const char*
[ERR_ALLOC_FAIL] = "Calloc :- Failed to allocate", vec_get_error_desc(ERROR_CODES err)
[ERR_BUF_NULL] = "Buffer :- NULL", {
[ERR_SIZE_ZERO] = "Size :- Size is or is less than 0 or invalid", switch (err)
[ERR_VECTOR_NULL] = "Vector :- Given vector is null", {
[ERR_MAX_PASSED] = "Max :- Vector Max value is overloaded", #define X(name, val, desc) \
[ERR_OUT_OF_BOUNDS] = "Bounds:- Value is out of bounds", case name: \
[ERR_NULL] = "Null:- Vector or buffer is null", return desc;
[ERR_DOUBLE_BUF] = "Buffer :- Both buffers are copies of each other", ERROR_LIST(X)
}; #undef X
default:
return "Unknown";
}
}
void
vec_print_errs(const err_t err)
{
if (err.flags == SUCCESS)
{
printf("%s: %s\n", err.origin, vec_get_error_desc(SUCCESS));
return;
}
{
#define X(name, val, desc) \
if ((val) != 0 && ((err.flags) & (val))) \
{ \
printf("%s\n", vec_get_error_desc(name)); \
}
ERROR_LIST(X)
#undef X
}
}
void
vec_print_bits(unsigned int num)
{
unsigned int total_bits = sizeof(num) * 8;
for (unsigned int i = total_bits - 1; i >= 0; i--)
{
unsigned int bit = (num >> i) & 1;
printf("%d ", bit);
if (i % 8 == 0)
{
printf(" ");
}
}
printf("\n");
}
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;
}
}
__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;
}
+46
View File
@@ -0,0 +1,46 @@
#include <stddef.h>
#include <stdint.h>
#include "char/char.h"
#include "utils/utils.h"
int
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
if (size < 2) return 0;
err_t err = ERR_T_INIT;
_VecCharInternal vec = VEC_INIT;
// Use input bytes to drive arbitrary vector operations
for (size_t i = 0; i < size; i++)
{
uint8_t op = data[i] % 5;
switch (op)
{
case 0:
_vec_char_push_back(&vec, (char)data[i], &err);
break;
case 1:
_vec_char_pop_back(&vec, &err);
break;
case 2:
if (vec._internal_size > 0)
{
size_t idx = (size_t)data[i] %
vec._internal_size;
_vec_char_erase(&vec, idx, &err);
}
break;
case 3:
_vec_char_reserve(&vec, (size_t)data[i], &err);
break;
case 4:
_vec_char_shrink_to_fit(&vec, &err);
break;
}
}
_vec_char_delete(&vec, &err);
return 0;
}
+104
View File
@@ -0,0 +1,104 @@
#include <assert.h>
#include <stdio.h>
#include "char/char.h"
#include "utils/utils.h"
static void
test_empty_vector_underflows(void)
{
printf("[RUN] Testing empty vector boundaries & underflows...\n");
err_t err = ERR_T_INIT;
_VecCharInternal vec = VEC_INIT;
// 1. Pop back on an empty container must not underflow size_t (0 - 1)
_vec_char_pop_back(&vec, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0 || err.flags != 0);
// 2. Reading back/end of an empty container
err = (err_t)ERR_T_INIT;
_vec_char_back(&vec, &err);
assert(err.flags != 0);
// 3. Reserving 0 capacity
err = (err_t)ERR_T_INIT;
_vec_char_reserve(&vec, 0, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0);
_vec_char_delete(&vec, &err);
printf("[PASS] Empty vector boundaries handled.\n");
}
static void
test_push_growth_and_shrink(void)
{
printf("[RUN] Testing push, capacity growth, and indexing...\n");
err_t err = ERR_T_INIT;
_VecCharInternal vec = VEC_INIT;
// Push elements to trigger initial malloc then realloc
for (char c = 'a'; c <= 'z'; c++)
{
_vec_char_push_back(&vec, c, &err);
assert(err.flags == 0);
}
assert(vec._internal_size == 26);
assert(vec._internal_capacity >= 26);
// Verify boundary indexing
assert(_vec_char_front(&vec, &err) == 'a');
assert(_vec_char_back(&vec, &err) == 'z');
// Index out of bounds check
err = (err_t)ERR_T_INIT;
_vec_char_at(&vec, 26, &err);
assert(err.flags != 0);
// Shrink to fit verification
err = (err_t)ERR_T_INIT;
_vec_char_shrink_to_fit(&vec, &err);
assert(vec._internal_capacity == 26);
_vec_char_delete(&vec, &err);
printf("[PASS] Growth and indexing passed.\n");
}
static void
test_range_insert_and_erase(void)
{
printf("[RUN] Testing range insertions and erasures...\n");
err_t err = ERR_T_INIT;
_VecCharInternal vec = VEC_INIT;
_vec_char_push_back(&vec, 'A', &err);
_vec_char_push_back(&vec, 'B', &err);
_vec_char_push_back(&vec, 'E', &err);
// Single insert between 'B' and 'E' at index 2
_vec_char_insert(&vec, 2, 'C', &err);
assert(vec._internal_size == 4);
assert(*_vec_char_at(&vec, 2, &err) == 'C');
// Erase test
_vec_char_erase(&vec, 2, &err);
assert(vec._internal_size == 3);
assert(*_vec_char_at(&vec, 2, &err) == 'E');
// Inverted range check: iter_end <= iter_start must report error
err = (err_t)ERR_T_INIT;
_vec_char_erase(&vec, 2, 1, &err);
assert(err.flags != 0);
_vec_char_delete(&vec, &err);
printf("[PASS] Range insert and erase passed.\n");
}
int
main(void)
{
test_empty_vector_underflows();
test_push_growth_and_shrink();
test_range_insert_and_erase();
printf("\nAll char vector edge-case tests passed cleanly!\n");
return 0;
}
+689
View File
@@ -0,0 +1,689 @@
#include <assert.h>
#include <int/int.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <utils/utils.h>
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
const char*
__asan_default_options(void)
{
return "allocator_may_return_null=1";
}
#endif
#endif
/* =========================================================================
* 1. BASIC LIFECYCLE & NULL GUARDS
* ========================================================================= */
static void
test_push_back_single(void)
{
printf("[1] Testing push_back with a single integer...\n");
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
_vec_int_push_back(&vec, 65, &err);
assert(err.flags == 0);
assert(vec._internal_size == 1);
assert(vec._internal_arr[0] == 65);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
static void
test_null_guards(void)
{
printf("[2] Testing null pointer checks in __null_check...\n");
_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 _VecIntInternal*)nullptr, &err);
assert(res2 == ERR_VEC_NULL);
assert((err.flags & ERR_VEC_NULL) != 0);
err = (err_t)ERR_T_INIT;
size_t res3 = __null_check(&vec, &err);
assert(res3 == ERR_BUF_NULL);
assert((err.flags & ERR_BUF_NULL) != 0);
err = (err_t)ERR_T_INIT;
size_t res4 = __null_check(vec._internal_arr, &err);
assert(res4 == ERR_BUF_NULL);
assert((err.flags & ERR_BUF_NULL) != 0);
err = (err_t)ERR_T_INIT;
size_t res5 = __null_check((const int*)nullptr, nullptr);
assert(res5 == ERR_ERR_T_NULL);
printf("Passed\n");
}
static void
test_origin_override(void)
{
printf("[3] Testing __origin_override...\n");
err_t err = ERR_T_INIT;
size_t res_null_status = __origin_override(nullptr, "TEST");
assert(res_null_status == ERR_ERR_T_NULL);
size_t res = __origin_override(&err, nullptr);
assert(res == ERR_STR_NULL);
assert((err.flags & ERR_STR_NULL) != 0);
err = (err_t)ERR_T_INIT;
__origin_override(&err, "INITIAL");
assert(strcmp(err.origin, "INITIAL") == 0);
// Override existing origin -> ERR_ORIGIN_UNALTERABLE
__origin_override(&err, "REPLACED");
assert((err.flags & ERR_ORIGIN_UNALTERABLE) != 0);
assert(strcmp(err.origin, "INITIAL") == 0);
printf("Passed\n");
}
/* =========================================================================
* 2. PRINT & COPY
* ========================================================================= */
static void
test_print_vec(void)
{
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
printf("[4] Testing print_vec with null vector\n");
_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_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_int_print_vec(&vec, nullptr);
printf("Passed\n");
printf("[7] Testing print_vec with valid parameters\n");
err = (err_t)ERR_T_INIT;
_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)
{
int arr[3] = { 1, 2, 3 };
_VecIntInternal blank = VEC_INIT;
printf("[8] Testing _vec_int_cpy with null source arr\n");
err_t err1 = ERR_T_INIT;
_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 &&
blank._internal_max_size == tmp._internal_max_size);
assert((err1.flags & ERR_BUF_NULL) != 0);
printf("Passed\n");
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_int_cpy with size 0\n");
err_t err3 = ERR_T_INIT;
_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 &&
blank._internal_max_size == res3._internal_max_size);
assert((err3.flags & ERR_SIZE_ZERO) != 0);
printf("Passed\n");
printf("[11] Testing _vec_int_cpy with size exceeding max_size\n");
err_t err4 = ERR_T_INIT;
_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 &&
blank._internal_max_size == res4._internal_max_size);
assert((err4.flags & ERR_SIZE_OVERFLOW) != 0);
printf("Passed\n");
printf("[12] Testing _vec_int_cpy allocation failure\n");
err_t err5 = ERR_T_INIT;
size_t huge_size = ((size_t)1 << 40);
_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_int_cpy with valid inputs\n");
err_t err = ERR_T_INIT;
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, sizeof(int) * 4) == 0);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
/* =========================================================================
* 3. PUSH, POP, CAPACITY & SIZING
* ========================================================================= */
static void
test_push_back(void)
{
printf("[14] Testing _vec_int_push_back null vec\n");
err_t err = ERR_T_INIT;
_vec_int_push_back(nullptr, 1, &err);
assert((err.flags & ERR_VEC_NULL) != 0);
printf("Passed\n");
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_int_delete(&vec1, &err);
printf("Passed\n");
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_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;
_VecIntInternal vec3 = VEC_INIT;
for (int val = 0; val < 10; val++)
{
_vec_int_push_back(&vec3, val, &err3);
assert(err3.flags == 0);
}
assert(vec3._internal_size == 10);
assert(vec3._internal_capacity >= 10);
_vec_int_delete(&vec3, &err3);
printf("Passed\n");
}
static void
test_pop_back(void)
{
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
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_int_pop_back size 0\n");
err = (err_t)ERR_T_INIT;
_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_int_pop_back(&vec, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0);
printf("Passed\n");
printf("[20] Testing _vec_int_pop_back valid pop\n");
err = (err_t)ERR_T_INIT;
_vec_int_push_back(&vec, 1, &err);
_vec_int_push_back(&vec, 2, &err);
assert(vec._internal_size == 2);
_vec_int_pop_back(&vec, &err);
assert(vec._internal_size == 1);
assert(vec._internal_arr[0] == 1);
assert(vec._internal_arr[1] == 0);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
static void
test_reserve(void)
{
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
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_int_reserve capacity 0\n");
err = (err_t)ERR_T_INIT;
_vec_int_reserve(&vec, 0, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0);
printf("Passed\n");
printf("[23] Testing _vec_int_reserve calloc on unallocated buffer\n");
err = (err_t)ERR_T_INIT;
_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_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_int_reserve truncating size\n");
vec._internal_size = 50;
_vec_int_reserve(&vec, 20, &err);
assert(vec._internal_size == 20);
assert(vec._internal_capacity == 20);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
static void
test_shrink_to_fit(void)
{
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
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_int_shrink_to_fit size 0 with allocated "
"buffer\n");
err = (err_t)ERR_T_INIT;
_vec_int_push_back(&vec, 1, &err);
_vec_int_pop_back(&vec, &err);
err = (err_t)ERR_T_INIT;
_vec_int_shrink_to_fit(&vec, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0);
printf("Passed\n");
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_int_push_back(&vec, val, &err);
}
assert(vec._internal_capacity == 128);
assert(vec._internal_size == 5);
err = (err_t)ERR_T_INIT;
_vec_int_shrink_to_fit(&vec, &err);
assert(err.flags == 0);
assert(vec._internal_capacity == 5);
assert(vec._internal_size == 5);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
/* =========================================================================
* 4. GETTERS, ELEMENT ACCESS & CLEAR
* ========================================================================= */
static void
test_getters_and_access(void)
{
printf("[29] Testing getters, clear, and boundary element access...\n");
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
// 1. Null pointer check
assert(_vec_int_data(nullptr, &err) == nullptr);
assert((err.flags & ERR_VEC_NULL) != 0);
err = (err_t)ERR_T_INIT;
assert(_vec_int_size(nullptr, &err) == 0);
assert((err.flags & ERR_VEC_NULL) != 0);
err = (err_t)ERR_T_INIT;
assert(_vec_int_capacity(nullptr, &err) == 0);
assert((err.flags & ERR_VEC_NULL) != 0);
err = (err_t)ERR_T_INIT;
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_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_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_int_empty(&vec, &err) == 0);
// Boundary element access on size 0
err = (err_t)ERR_T_INIT;
assert(_vec_int_front(&vec, &err) == 0 ||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
err = (err_t)ERR_T_INIT;
assert(_vec_int_back(&vec, &err) == 0 ||
(err.flags & ERR_OUT_OF_BOUNDS) != 0);
// 4. Populate container
err = (err_t)ERR_T_INIT;
_vec_int_push_back(&vec, 10, &err);
_vec_int_push_back(&vec, 20, &err);
_vec_int_push_back(&vec, 30, &err);
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_int_at(&vec, 10, &err) == nullptr);
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
// Clear container
err = (err_t)ERR_T_INIT;
_vec_int_clear(&vec, &err);
assert(vec._internal_size == 0);
assert(vec._internal_arr[0] == 0);
_vec_int_delete(&vec, &err);
assert(vec._internal_arr == nullptr);
assert(vec._internal_size == 0);
assert(vec._internal_capacity == 0);
printf("Passed\n");
}
/* =========================================================================
* 5. SWAP, ERASE, RESIZE, ASSIGN & INSERT
* ========================================================================= */
static void
test_swap(void)
{
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_int_swap(nullptr, &b, &err);
assert((err.flags & ERR_VEC_NULL) != 0);
err = (err_t)ERR_T_INIT;
_vec_int_swap(&a, nullptr, &err);
assert((err.flags & ERR_VEC_NULL) != 0);
// Normal swap
err = (err_t)ERR_T_INIT;
_vec_int_push_back(&a, 100, &err);
_vec_int_push_back(&b, 200, &err);
_vec_int_push_back(&b, 300, &err);
_vec_int_swap(&a, &b, &err);
assert(a._internal_size == 2);
assert(a._internal_arr[0] == 200);
assert(b._internal_size == 1);
assert(b._internal_arr[0] == 100);
_vec_int_delete(&a, &err);
_vec_int_delete(&b, &err);
printf("Passed\n");
}
static void
test_erase_variants(void)
{
printf("[31] Testing _vec_int_erase single & range overloads...\n");
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
for (int val = 0; val <= 5; val++)
{
_vec_int_push_back(&vec, val, &err);
} // {0, 1, 2, 3, 4, 5}
// Single element erase out of bounds (noop)
_vec_int_erase(&vec, 10, &err);
assert(vec._internal_size == 6);
// 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);
// Range erase invalid bounds
err = (err_t)ERR_T_INIT;
_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_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, [1, 3], 4, 5} -> {0, 4,
// 5})
err = (err_t)ERR_T_INIT;
_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);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
static void
test_resize(void)
{
printf("[32] Testing _vec_int_resize (zero-fill & value-fill)...\n");
_VecIntInternal vec = VEC_INIT;
err_t err = ERR_T_INIT;
// Null vector
_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_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_int_resize(&vec, 5, &err);
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
// Exceeds max size
err = (err_t)ERR_T_INIT;
_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_int_resize(&vec, 8, 5, &err);
assert(vec._internal_size == 8);
assert(vec._internal_arr[5] == 5);
assert(vec._internal_arr[7] == 5);
// Shrink with value fill
err = (err_t)ERR_T_INIT;
_vec_int_resize(&vec, 3, 10, &err);
assert(vec._internal_size == 3);
_vec_int_delete(&vec, &err);
printf("Passed\n");
}
static void
test_assign(void)
{
printf("[33] Testing _vec_int_assign overloads...\n");
_VecIntInternal dst = VEC_INIT;
_VecIntInternal src = VEC_INIT;
err_t err = ERR_T_INIT;
// Populate src: 1, 2, 3, 4, 5
for (int val = 1; val <= 5; val++)
{
_vec_int_push_back(&src, val, &err);
}
// Allocate dst buffer first so it is not unallocated
_vec_int_push_back(&dst, 999, &err);
err = (err_t)ERR_T_INIT;
// 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] == 42);
assert(dst._internal_arr[3] == 42);
// 2. Fill assign with 0 amount
err = (err_t)ERR_T_INIT;
_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_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_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_int_assign(&dst, &src, 0, 10, &err);
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
_vec_int_delete(&dst, &err);
_vec_int_delete(&src, &err);
printf("Passed\n");
}
static void
test_insert(void)
{
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_int_insert(&vec, 0, 500, &err);
assert(vec._internal_size == 1);
assert(vec._internal_arr[0] == 500);
// Single insert out of bounds
err = (err_t)ERR_T_INIT;
_vec_int_insert(&vec, 5, 999, &err);
assert((err.flags & ERR_OUT_OF_BOUNDS) != 0);
// Single insert at middle: index 0 (100, then 500 shifts to 1)
err = (err_t)ERR_T_INIT;
_vec_int_insert(&vec, 0, 100, &err);
assert(vec._internal_size == 2);
assert(vec._internal_arr[0] == 100);
assert(vec._internal_arr[1] == 500);
// 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] == 200);
assert(vec._internal_arr[3] == 200);
assert(vec._internal_arr[4] == 500);
// Repeated insert amount 0
err = (err_t)ERR_T_INIT;
_vec_int_insert(&vec, 0, 0, 300, &err);
assert((err.flags & ERR_SIZE_ZERO) != 0);
// Vector-from-vector range insert
_vec_int_push_back(&other, 1, &err);
_vec_int_push_back(&other, 2, &err);
// Double buffer check
err = (err_t)ERR_T_INIT;
_vec_int_insert(&vec, &vec, 0, 0, 1, &err);
assert((err.flags & ERR_DOUBLE_BUF) != 0);
_vec_int_delete(&vec, &err);
_vec_int_delete(&other, &err);
printf("Passed\n");
}
/* =========================================================================
* MAIN TEST RUNNER
* ========================================================================= */
int
main(void)
{
printf("=========================================\n");
printf(" Starting Complete libvec Unit Test Suite\n");
printf("=========================================\n");
test_push_back_single();
test_null_guards();
test_origin_override();
test_print_vec();
test_cpy();
test_push_back();
test_pop_back();
test_reserve();
test_shrink_to_fit();
test_getters_and_access();
test_swap();
test_erase_variants();
test_resize();
test_assign();
test_insert();
printf("=========================================\n");
printf(" All 34 Test Suites Executed Successfully!\n");
printf("=========================================\n");
return 0;
}