diff --git a/Include/Fledasty/Core/DynamicArray.h b/Include/Fledasty/Core/DynamicArray.h index df7d978..544e4cb 100644 --- a/Include/Fledasty/Core/DynamicArray.h +++ b/Include/Fledasty/Core/DynamicArray.h @@ -26,34 +26,225 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" -typedef struct { - size_t size, capacity; +#define FLEDASTY_DYNAMIC_ARRAY_DEFINE(type, name) \ +typedef struct { \ + size_t size, capacity; \ + type *buffer; \ +} FledastyDynamicArray_##name; \ + \ +FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index); \ +FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array); \ +FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value); \ +inline static bool fledasty_dynamic_array_##name##_is_empty(const FledastyDynamicArray_##name *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } - size_t element_byte_size; - unsigned char *buffer; -} FledastyDynamicArray; - -FledastyError fledasty_dynamic_array_initialize(FledastyDynamicArray *new_dynamic_array, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_dynamic_array_destroy(FledastyDynamicArray *current_dynamic_array); - -FledastyError fledasty_dynamic_array_append(FledastyDynamicArray *current_dynamic_array, void *value); - -FledastyError fledasty_dynamic_array_insert_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index, void *value); -FledastyError fledasty_dynamic_array_insert_before_value(FledastyDynamicArray *current_dynamic_array, void *before_value, void *value); -FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *current_dynamic_array, void *after_value, void *value); - -void *fledasty_dynamic_array_get(const FledastyDynamicArray *current_dynamic_array, const size_t index); - -FledastyError fledasty_dynamic_array_remove_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index); -FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_dynamic_array, void *value); - -FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array); -FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array); - -bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value); -inline static bool fledasty_dynamic_array_is_empty(const FledastyDynamicArray *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } +#define FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(type, name, compare_function) \ +FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_dynamic_array->size = 0; \ + current_dynamic_array->capacity = 0; \ + current_dynamic_array->buffer = NULL; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + current_dynamic_array->buffer[current_dynamic_array->size++] = value; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + if (index >= current_dynamic_array->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], before_value)) { \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], after_value)) { \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index + 1; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index >= current_dynamic_array->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + type *remove_pointer = current_dynamic_array->buffer + index; \ + hallocy_copy_memory(remove_pointer, remove_pointer + 1, (current_dynamic_array->size - index + 1) * sizeof(type)); \ + current_dynamic_array->size -= 1; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], value)) { \ + hallocy_copy_memory(current_dynamic_array->buffer + index, current_dynamic_array->buffer + index + 1, (current_dynamic_array->size - index) * sizeof(type)); \ + current_dynamic_array->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_dynamic_array->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_dynamic_array->capacity = current_dynamic_array->size; \ + type *shrinked_buffer = (type*)hallocy_malloc(current_dynamic_array->capacity * sizeof(type)); \ + if (shrinked_buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + hallocy_copy_memory(shrinked_buffer, current_dynamic_array->buffer, (current_dynamic_array->size - 1) * sizeof(type)); \ + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_dynamic_array->buffer = shrinked_buffer; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return false; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], value)) { \ + return true; \ + } \ + } \ + \ + return false; \ +} #endif diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index 5c1ceaa..e7e99d1 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -29,16 +29,19 @@ #include "../Utils/Error.h" #include "DynamicArray.h" +#include "Hallocy/Core/Memory.h" typedef struct { void *key, *value; } FledastyHashTablePair; +FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair, pair) + typedef struct { size_t size, capacity; size_t key_byte_size, value_byte_size; - FledastyDynamicArray *Table; + FledastyDynamicArray_pair *Table; size_t (*hash_function)(const void *key); } FledastyHashTable; @@ -55,5 +58,6 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key); static inline bool fledasty_hash_table_is_empty(const FledastyHashTable *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } +static inline bool fledasty_hash_table_compare_pair(const FledastyHashTablePair first_pair, const FledastyHashTablePair second_pair) { return first_pair.key == second_pair.key && first_pair.value == second_pair.value; } #endif diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index 9f7aad0..b2752d4 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -103,7 +103,7 @@ FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, \ type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue) { \ if (current_queue == NULL || current_queue->size == 0) { \ - return 0; \ + return 0; \ } \ \ current_queue->size -= 1; \ diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c deleted file mode 100644 index bce2953..0000000 --- a/Src/Core/DynamicArray.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: DynamicArray.c - * Description: - * This file contains the functions for modifying the Dynamic Array. It includes - * functions to append, Insert before, Insert after, Insert at index, - * Get, Remove element, Remove at index, Check if has element and Check if is empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/DynamicArray.h" - -#include -#include -#include - -FledastyError fledasty_dynamic_array_initialize(FledastyDynamicArray *new_dynamic_array, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - new_dynamic_array->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_dynamic_array->size = 0; - new_dynamic_array->capacity = 10; - - new_dynamic_array->buffer = (unsigned char*)hallocy_malloc(new_dynamic_array->capacity * element_byte_size); - if (new_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } else { - new_dynamic_array->size = values_size; - new_dynamic_array->capacity = new_dynamic_array->size + new_dynamic_array->size; - - new_dynamic_array->buffer = (unsigned char*)hallocy_malloc(new_dynamic_array->capacity * element_byte_size); - if (new_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_dynamic_array->buffer, values, values_size * element_byte_size); - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_destroy(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_dynamic_array->buffer = NULL; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_append(FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_copy_memory(current_dynamic_array->buffer + (current_dynamic_array->size * current_dynamic_array->element_byte_size), value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_insert_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (index >= current_dynamic_array->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - unsigned char *insert_pointer = current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); - hallocy_move_memory(insert_pointer + current_dynamic_array->element_byte_size, insert_pointer, (current_dynamic_array->size - index) * current_dynamic_array->element_byte_size); - hallocy_copy_memory(insert_pointer, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_insert_before_value(FledastyDynamicArray *current_dynamic_array, void *before_value, void *value) { - if (current_dynamic_array == NULL || before_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, before_value, current_dynamic_array->element_byte_size)) { - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *current_dynamic_array, void *after_value, void *value) { - if (current_dynamic_array == NULL || after_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, after_value, current_dynamic_array->element_byte_size)) { - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - byte_index += current_dynamic_array->element_byte_size; - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -void *fledasty_dynamic_array_get(const FledastyDynamicArray *current_dynamic_array, const size_t index) { - if (current_dynamic_array == NULL || index >= current_dynamic_array->size) { - return NULL; - } - - return current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); -} - -FledastyError fledasty_dynamic_array_remove_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index >= current_dynamic_array->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - unsigned char *index_pointer = current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); - hallocy_copy_memory(index_pointer, index_pointer + current_dynamic_array->element_byte_size, (current_dynamic_array->size + index) * current_dynamic_array->element_byte_size); - current_dynamic_array->size -= 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), byte_size - (byte_index + current_dynamic_array->element_byte_size)); - current_dynamic_array->size -= 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_dynamic_array->size = 0; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_dynamic_array->capacity = (current_dynamic_array->size == 0) ? 10 : current_dynamic_array->size; - unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - if (shrinked_buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(shrinked_buffer, current_dynamic_array->buffer, current_dynamic_array->size * current_dynamic_array->element_byte_size); - if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_dynamic_array->buffer = shrinked_buffer; - return FLEDASTY_ERROR_NONE; -} - -bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL) { - return false; - } - - for (size_t byte_index = 0; byte_index < current_dynamic_array->size * current_dynamic_array->element_byte_size; byte_index += current_dynamic_array->element_byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { - return true; - } - } - - return false; -} diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index b801bc4..6370bf6 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -26,6 +26,8 @@ #include #include +FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(FledastyHashTablePair, pair, fledasty_hash_table_compare_pair) + static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)) { @@ -39,7 +41,7 @@ FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, new_hash_table->size = 0; new_hash_table->capacity = 1024; - new_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), new_hash_table->capacity); + new_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), new_hash_table->capacity); if (new_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -53,7 +55,7 @@ FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table) } for (size_t i = 0; i < current_hash_table->capacity; i += 1) { - FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[i]); + FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[i]); if (result != FLEDASTY_ERROR_NONE) { return result; } @@ -73,32 +75,25 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray *previous_table = current_hash_table->Table; + FledastyDynamicArray_pair *previous_table = current_hash_table->Table; current_hash_table->capacity += current_hash_table->capacity; - current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); + current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray *current_dynamic_array = previous_table + index; + FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; if (current_dynamic_array->buffer != NULL) { for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); + FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; - if (current_hash_table->Table[key_index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - - fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; + fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); } - fledasty_dynamic_array_destroy(current_dynamic_array); + fledasty_dynamic_array_pair_free(current_dynamic_array); } } @@ -106,15 +101,8 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - if (current_hash_table->Table[index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(¤t_hash_table->Table[index], NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } FledastyHashTablePair pair; - pair.key = hallocy_malloc(current_hash_table->key_byte_size); if (pair.key == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -128,7 +116,7 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); + fledasty_dynamic_array_pair_append(¤t_hash_table->Table[index], pair); current_hash_table->size += 1; return FLEDASTY_ERROR_NONE; @@ -146,9 +134,9 @@ void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { - return value->value; + const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { + return value.value; } list_index += 1; @@ -169,17 +157,17 @@ FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { - if (hallocy_free(value->key) != HALLOCY_ERROR_NONE) { + FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { + if (hallocy_free(value.key) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - if (hallocy_free(value->value) != HALLOCY_ERROR_NONE) { + if (hallocy_free(value.value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - fledasty_dynamic_array_remove_at_index(¤t_hash_table->Table[index], list_index); + fledasty_dynamic_array_pair_remove_at_index(¤t_hash_table->Table[index], list_index); current_hash_table->size -= 1; return FLEDASTY_ERROR_NONE; } @@ -197,7 +185,7 @@ FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table) { for (size_t index = 0; index < current_hash_table->capacity; index += 1) { if (current_hash_table->Table[index].buffer != NULL) { - FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[index]); + FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[index]); if (result != FLEDASTY_ERROR_NONE) { return result; } @@ -214,7 +202,7 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ } const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray *previous_table = current_hash_table->Table; + FledastyDynamicArray_pair *previous_table = current_hash_table->Table; if (current_hash_table->size == 0) { current_hash_table->capacity = 1024; @@ -222,29 +210,22 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; } - current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); + current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray *current_dynamic_array = previous_table + index; + FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; if (current_dynamic_array->buffer != NULL) { for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); + FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; - if (current_hash_table->Table[key_index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - - fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; + fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); } - fledasty_dynamic_array_destroy(current_dynamic_array); + fledasty_dynamic_array_pair_free(current_dynamic_array); } } @@ -264,8 +245,8 @@ bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, vo size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { + const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { return true; } diff --git a/Tests/Main.c b/Tests/Main.c index 0df15e9..8c5cb59 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -30,13 +30,17 @@ #include #include +static inline bool compare_integers(const int first_value, const int second_value) { return first_value == second_value; } +static inline size_t integer_hash_function(const void *key) { return *(int*)key; } + FLEDASTY_STACK_DEFINE(int) FLEDASTY_STACK_IMPLEMENT(int) FLEDASTY_QUEUE_DEFINE(int) FLEDASTY_QUEUE_IMPLEMENT(int) -static inline size_t integer_hash_function(const void *key) { return *(int*)key; } +FLEDASTY_DYNAMIC_ARRAY_DEFINE(int, int) +FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(int, int, compare_integers) int main() { FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; @@ -80,44 +84,35 @@ int main() { fledasty_stack_int_free(&test_stack); - FledastyDynamicArray test_dynamic_array; - fledasty_dynamic_array_initialize(&test_dynamic_array, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); + FledastyDynamicArray_int test_dynamic_array = { 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_dynamic_array_append(&test_dynamic_array, &i); + fledasty_dynamic_array_int_append(&test_dynamic_array, i); } - fledasty_dynamic_array_shrink_to_fit(&test_dynamic_array); + fledasty_dynamic_array_int_shrink_to_fit(&test_dynamic_array); printf("Dynamic array schrinked to fit %s\n", (test_dynamic_array.capacity == test_dynamic_array.size) ? "succeeded" : "failed"); - int insert_value = 18; - fledasty_dynamic_array_insert_at_index(&test_dynamic_array, 1, &insert_value); + fledasty_dynamic_array_int_insert_at_index(&test_dynamic_array, 1, 18); + fledasty_dynamic_array_int_insert_before_value(&test_dynamic_array, 1, 35); + fledasty_dynamic_array_int_insert_after_value(&test_dynamic_array, 35, 90); - insert_value = 35; - int insert_at_value = 11; - fledasty_dynamic_array_insert_before_value(&test_dynamic_array, &insert_at_value, &insert_value); - insert_value = 90; - insert_at_value = 35; - fledasty_dynamic_array_insert_after_value(&test_dynamic_array, &insert_at_value, &insert_value); - - int remove_value = 15; - fledasty_dynamic_array_remove_value(&test_dynamic_array, &remove_value); - fledasty_dynamic_array_remove_at_index(&test_dynamic_array, test_dynamic_array.size - 2); + fledasty_dynamic_array_int_remove_value(&test_dynamic_array, 35); + fledasty_dynamic_array_int_remove_at_index(&test_dynamic_array, test_dynamic_array.size - 2); for (int i = 0; i < test_dynamic_array.size; i += 1) { - int *dynamic_array_data = (int*)fledasty_dynamic_array_get(&test_dynamic_array, i); - printf("Dynamic array get: %d\n", *dynamic_array_data); + printf("Dynamic array get: %d\n", test_dynamic_array.buffer[i]); } - if (fledasty_dynamic_array_has_value(&test_dynamic_array, &insert_value)) { - printf("Dynamic array contains %d\n", insert_value); + if (fledasty_dynamic_array_int_has_value(&test_dynamic_array, 90)) { + printf("Dynamic array contains 90\n"); } - fledasty_dynamic_array_clear(&test_dynamic_array); - if (fledasty_dynamic_array_is_empty(&test_dynamic_array)) { + fledasty_dynamic_array_int_clear(&test_dynamic_array); + if (fledasty_dynamic_array_int_is_empty(&test_dynamic_array)) { printf("Dynamic array is empty\n"); } - fledasty_dynamic_array_destroy(&test_dynamic_array); + fledasty_dynamic_array_int_free(&test_dynamic_array); FledastyLinkedList test_linked_list; fledasty_linked_list_initialize(&test_linked_list, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); @@ -126,16 +121,16 @@ int main() { fledasty_linked_list_append(&test_linked_list, &i); } - insert_value = 35; + int insert_value = 35; fledasty_linked_list_insert_at_index(&test_linked_list, 1, &insert_value); insert_value = 28; - insert_at_value = 35; + int insert_at_value = 35; fledasty_linked_list_insert_before_value(&test_linked_list, &insert_at_value, &insert_value); insert_value = 90; fledasty_linked_list_insert_after_value(&test_linked_list, &insert_at_value, &insert_value); fledasty_linked_list_remove_at_index(&test_linked_list, 2); - remove_value = 0; + int remove_value = 0; fledasty_linked_list_remove_value(&test_linked_list, &remove_value); FledastyLinkedListNode *test_linked_list_node = test_linked_list.start;