This commit is contained in:
Alexey Zholtikov 2025-05-02 11:48:56 +03:00
parent b487617d3a
commit 6d47829675
2 changed files with 4958 additions and 223 deletions

View File

@ -1,115 +1,492 @@
#pragma once
#ifndef ZH_VECTOR_H
#define ZH_VECTOR_H
#include "string.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include <stdint.h>
#include <stdbool.h>
#include <esp_err.h>
/**
* @brief Structure representing a dynamic vector.
*/
typedef struct {
void **items; ///< Pointer to the array of items.
uint16_t size; ///< Current number of elements in the vector.
uint16_t capacity; ///< Current capacity of the vector.
uint16_t unit; ///< Size of each element in bytes.
bool status; ///< Indicates whether the vector is initialized.
} zh_vector_t;
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
typedef struct // Main structure of vector data.
{
void **items; // Array of pointers of vector items.
uint16_t capacity; // Maximum capacity of the vector. @note Used to control the size of allocated memory for array of pointers of vector items. Usually equal to the current number of items in the vector. Automatically changes when items are added or deleted.
uint16_t size; // Number of items in the vector. @note Can be read with zh_vector_get_size().
uint16_t unit; // Vector item size. @note Possible values from 1 to 65535.
bool status; // Vector initialization status flag. @note Used to prevent execution of vector functions without prior vector initialization.
} zh_vector_t;
/**
* @brief Initializes a vector.
*
* @param vector Pointer to the vector to initialize.
* @param unit Size of each element in bytes.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_t vector;
* esp_err_t err = zh_vector_init(&vector, sizeof(int));
* if (err == ESP_OK) {
* // Vector initialized successfully.
* }
* @endcode
*/
esp_err_t zh_vector_init(zh_vector_t *vector, uint16_t unit);
/**
* @brief Initialize vector.
*
* @param[in] vector Pointer to main structure of vector data.
* @param[in] unit Size of vector item.
*
* @return
* - ESP_OK if initialization was success
* - ESP_ERR_INVALID_ARG if parameter error
* - ESP_ERR_INVALID_STATE if vector already initialized
*/
esp_err_t zh_vector_init(zh_vector_t *vector, uint16_t unit);
/**
* @brief Frees the memory allocated for the vector.
*
* @param vector Pointer to the vector to free.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_free(&vector);
* @endcode
*/
esp_err_t zh_vector_free(zh_vector_t *vector);
/**
* @brief Deinitialize vector. Free all allocated memory.
*
* @param[in] vector Pointer to main structure of vector data.
*
* @return
* - ESP_OK if deinitialization was success
* - ESP_ERR_INVALID_ARG if parameter error
* - ESP_ERR_INVALID_STATE if vector not initialized
*/
esp_err_t zh_vector_free(zh_vector_t *vector);
/**
* @brief Adds an item to the end of the vector.
*
* @param vector Pointer to the vector.
* @param item Pointer to the item to add.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* int value = 42;
* zh_vector_push_back(&vector, &value);
* @endcode
*/
esp_err_t zh_vector_push_back(zh_vector_t *vector, void *item);
/**
* @brief Get current vector size.
*
* @param[in] vector Pointer to main structure of vector data.
*
* @return
* - Vector size
* - ESP_FAIL if parameter error or vector not initialized
*/
esp_err_t zh_vector_get_size(zh_vector_t *vector);
/**
* @brief Adds an item to the end of the vector without copying its contents.
*
* This function directly assigns the provided pointer to the vector's internal storage,
* avoiding the need to allocate memory or copy data. It is useful when the item is already
* allocated and managed externally.
*
* @param vector Pointer to the vector.
* @param item Pointer to the item to add.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_t vector;
* zh_vector_init(&vector, sizeof(int));
* int *value = malloc(sizeof(int));
* *value = 42;
* zh_vector_emplace_back(&vector, value);
* @endcode
*/
esp_err_t zh_vector_emplace_back(zh_vector_t *vector, void *item);
/**
* @brief Add item at end of vector.
*
* @param[in] vector Pointer to main structure of vector data.
* @param[in] item Pointer to item for add.
*
* @return
* - ESP_OK if add was success
* - ESP_ERR_INVALID_ARG if parameter error
* - ESP_ERR_NO_MEM if memory allocation fail or no free memory in the heap
* - ESP_ERR_INVALID_STATE if vector not initialized
*/
esp_err_t zh_vector_push_back(zh_vector_t *vector, void *item);
/**
* @brief Removes the last item from the vector.
*
* @param vector Pointer to the vector.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_pop_back(&vector);
* @endcode
*/
esp_err_t zh_vector_pop_back(zh_vector_t *vector);
/**
* @brief Change item by index.
*
* @param[in] vector Pointer to main structure of vector data.
* @param[in] index Index of item for change.
* @param[in] item Pointer to new data of item.
*
* @return
* - ESP_OK if change was success
* - ESP_ERR_INVALID_ARG if parameter error
* - ESP_ERR_INVALID_STATE if vector not initialized
* - ESP_FAIL if index does not exist
*/
esp_err_t zh_vector_change_item(zh_vector_t *vector, uint16_t index, void *item);
/**
* @brief Gets the item at the specified index.
*
* @param vector Pointer to the vector.
* @param index Index of the item to retrieve.
* @return Pointer to the item, or NULL if the index is out of bounds.
*
* Example usage:
* @code
* int *item = (int *)zh_vector_get_item(&vector, 0);
* if (item != NULL) {
* // Use the item.
* }
* @endcode
*/
void *zh_vector_get_item(zh_vector_t *vector, uint16_t index);
/**
* @brief Get item by index.
*
* @param[in] vector Pointer to main structure of vector data.
* @param[in] index Index of item for get.
*
* @return
* - Pointer to item
* - NULL if parameter error or vector not initialized or if index does not exist
*/
void *zh_vector_get_item(zh_vector_t *vector, uint16_t index);
/**
* @brief Checks if the vector is empty.
*
* @param vector Pointer to the vector.
* @return true if the vector is empty, false otherwise.
*
* Example usage:
* @code
* if (zh_vector_is_empty(&vector)) {
* // Vector is empty.
* }
* @endcode
*/
bool zh_vector_is_empty(zh_vector_t *vector);
/**
* @brief Delete item by index and shifts all elements in vector.
*
* @param[in] vector Pointer to main structure of vector data.
* @param[in] index Index of item for delete.
*
* @return
* - ESP_OK if delete was success
* - ESP_ERR_INVALID_ARG if parameter error
* - ESP_ERR_INVALID_STATE if vector not initialized
* - ESP_FAIL if index does not exist
*/
esp_err_t zh_vector_delete_item(zh_vector_t *vector, uint16_t index);
/**
* @brief Clears all items from the vector.
*
* @param vector Pointer to the vector.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_clear(&vector);
* @endcode
*/
esp_err_t zh_vector_clear(zh_vector_t *vector);
/**
* @brief Sorts the vector in ascending order.
*
* @param vector Pointer to the vector.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* int compare(const void *a, const void *b) {
* return (*(int *)a - *(int *)b);
* }
* zh_vector_sort(&vector, compare);
* @endcode
*/
esp_err_t zh_vector_sort(zh_vector_t *vector, int (*cmp)(const void *, const void *));
/**
* @brief Finds the index of the specified item in the vector.
*
* @param vector Pointer to the vector.
* @param item Pointer to the item to find.
* @param cmp Comparison function to compare items.
* @return Index of the found item, or -1 if the item is not found.
*
* Example usage:
* @code
* int value = 42;
* int index = zh_vector_find(&vector, &value, compare);
* if (index != -1) {
* // Item found at index.
* }
* @endcode
*/
int zh_vector_find(zh_vector_t *vector, void *item, int (*cmp)(const void *, const void *));
/**
* @brief Removes all occurrences of the specified item from the vector.
*
* @param vector Pointer to the vector.
* @param item Pointer to the item to remove.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* int value = 42;
* zh_vector_remove_all(&vector, &value, compare);
* @endcode
*/
esp_err_t zh_vector_remove_all(zh_vector_t *vector, void *item, int (*cmp)(const void *, const void *));
/**
* @brief Replaces all occurrences of an item in the vector with a new item.
*
* @param vector Pointer to the vector.
* @param old_item Pointer to the item to replace.
* @param new_item Pointer to the new item.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* int old_value = 42;
* int new_value = 84;
* zh_vector_replace_all(&vector, &old_value, &new_value, compare);
* @endcode
*/
esp_err_t zh_vector_replace_all(zh_vector_t *vector, void *old_item, void *new_item, int (*cmp)(const void *, const void *));
/**
* @brief Counts the number of items in the vector that satisfy a predicate.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @return Number of items that satisfy the predicate.
*
* Example usage:
* @code
* bool is_even(const void *item) {
* return (*(int *)item % 2) == 0;
* }
* uint16_t count = zh_vector_count_if(&vector, is_even);
* @endcode
*/
uint16_t zh_vector_count_if(zh_vector_t *vector, bool (*predicate)(const void *));
/**
* @brief Shuffles the elements of the vector randomly.
*
* @param vector Pointer to the vector.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_shuffle(&vector);
* @endcode
*/
esp_err_t zh_vector_shuffle(zh_vector_t *vector);
/**
* @brief Finds the minimum item in the vector.
*
* @param vector Pointer to the vector.
* @param cmp Comparison function to compare items.
* @return Pointer to the minimum item, or NULL if the vector is empty.
*
* Example usage:
* @code
* int *min_item = (int *)zh_vector_min(&vector, compare);
* if (min_item != NULL) {
* // Use the minimum item.
* }
* @endcode
*/
void *zh_vector_min(zh_vector_t *vector, int (*cmp)(const void *, const void *));
/**
* @brief Finds the maximum item in the vector.
*
* @param vector Pointer to the vector.
* @param cmp Comparison function to compare items.
* @return Pointer to the maximum item, or NULL if the vector is empty.
*
* Example usage:
* @code
* int *max_item = (int *)zh_vector_max(&vector, compare);
* if (max_item != NULL) {
* // Use the maximum item.
* }
* @endcode
*/
void *zh_vector_max(zh_vector_t *vector, int (*cmp)(const void *, const void *));
/**
* @brief Rotates the vector to the left by the specified number of positions.
*
* @param vector Pointer to the vector.
* @param positions Number of positions to rotate.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_rotate_left(&vector, 3);
* @endcode
*/
esp_err_t zh_vector_rotate_left(zh_vector_t *vector, uint16_t positions);
/**
* @brief Rotates the vector to the right by the specified number of positions.
*
* @param vector Pointer to the vector.
* @param positions Number of positions to rotate.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_rotate_right(&vector, 2);
* @endcode
*/
esp_err_t zh_vector_rotate_right(zh_vector_t *vector, uint16_t positions);
/**
* @brief Removes all items from the vector that satisfy a predicate.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_remove_if(zh_vector_t *vector, bool (*predicate)(const void *));
/**
* @brief Removes all items from the vector that do not satisfy a predicate.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_remove_if_not(zh_vector_t *vector, bool (*predicate)(const void *));
/**
* @brief Replaces items in the vector that satisfy a predicate with a new item.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @param new_item Pointer to the new item to replace with.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_replace(zh_vector_t *vector, bool (*predicate)(const void *), void *new_item);
/**
* @brief Merges the source vector into the destination vector.
*
* @param dest Pointer to the destination vector.
* @param src Pointer to the source vector.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_merge(zh_vector_t *dest, const zh_vector_t *src);
/**
* @brief Removes duplicate items from the vector using a comparison function.
*
* @param vector Pointer to the vector.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_unique(zh_vector_t *vector, int (*cmp)(const void *, const void *));
/**
* @brief Converts the vector to an array of pointers.
*
* @param vector Pointer to the vector.
* @return Pointer to the array of pointers, or NULL on failure.
*/
void **zh_vector_to_array(zh_vector_t *vector);
/**
* @brief Partitions the vector into two parts based on a predicate.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @param true_part Pointer to the vector to store items satisfying the predicate.
* @param false_part Pointer to the vector to store items not satisfying the predicate.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_partition(zh_vector_t *vector, bool (*predicate)(const void *), zh_vector_t *true_part, zh_vector_t *false_part);
/**
* @brief Copies items from the source vector to the destination vector that satisfy a predicate.
*
* @param src Pointer to the source vector.
* @param dest Pointer to the destination vector.
* @param predicate Predicate function to evaluate items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_copy_if(const zh_vector_t *src, zh_vector_t *dest, bool (*predicate)(const void *));
/**
* @brief Rotates the vector by the specified number of positions.
*
* @param vector Pointer to the vector.
* @param positions Number of positions to rotate (positive for right, negative for left).
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_rotate(zh_vector_t *vector, int16_t positions);
/**
* @brief Finds all items in the vector that match a predicate and returns their indices.
*
* @param vector Pointer to the vector.
* @param predicate Predicate function to evaluate items.
* @param indices Pointer to an array of indices (allocated dynamically).
* @param count Pointer to store the number of found indices.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_find_all(zh_vector_t *vector, bool (*predicate)(const void *), uint16_t **indices, uint16_t *count);
/**
* @brief Finds the intersection of two vectors and stores the result in a third vector.
*
* @param vector1 Pointer to the first vector.
* @param vector2 Pointer to the second vector.
* @param result Pointer to the vector to store the intersection.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_intersect(const zh_vector_t *vector1, const zh_vector_t *vector2, zh_vector_t *result, int (*cmp)(const void *, const void *));
/**
* @brief Finds the union of two vectors and stores the result in a third vector.
*
* @param vector1 Pointer to the first vector.
* @param vector2 Pointer to the second vector.
* @param result Pointer to the vector to store the union.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_union(const zh_vector_t *vector1, const zh_vector_t *vector2, zh_vector_t *result, int (*cmp)(const void *, const void *));
/**
* @brief Finds the difference of two vectors and stores the result in a third vector.
*
* @param vector1 Pointer to the first vector.
* @param vector2 Pointer to the second vector.
* @param result Pointer to the vector to store the difference.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_difference(const zh_vector_t *vector1, const zh_vector_t *vector2, zh_vector_t *result, int (*cmp)(const void *, const void *));
/**
* @brief Finds the symmetric difference of two vectors and stores the result in a third vector.
*
* @param vector1 Pointer to the first vector.
* @param vector2 Pointer to the second vector.
* @param result Pointer to the vector to store the symmetric difference.
* @param cmp Comparison function to compare items.
* @return ESP_OK on success, or an error code otherwise.
*/
esp_err_t zh_vector_symmetric_difference(const zh_vector_t *vector1, const zh_vector_t *vector2, zh_vector_t *result, int (*cmp)(const void *, const void *));
/**
* @brief Gets the current size (number of elements) of the vector.
*
* @param vector Pointer to the vector.
* @return The size of the vector, or -1 if the vector is not initialized or invalid.
*
* Example usage:
* @code
* zh_vector_t vector;
* zh_vector_init(&vector, sizeof(int));
* int size = zh_vector_get_size(&vector);
* printf("Vector size: %d\n", size);
* @endcode
*/
esp_err_t zh_vector_get_size(zh_vector_t *vector);
/**
* @brief Adds an item to the end of the vector without copying its contents.
*
* This function directly assigns the provided pointer to the vector's internal storage,
* avoiding the need to allocate memory or copy data. It is useful when the item is already
* allocated and managed externally.
*
* @param vector Pointer to the vector.
* @param item Pointer to the item to add.
* @return ESP_OK on success, or an error code otherwise.
*
* Example usage:
* @code
* zh_vector_t vector;
* zh_vector_init(&vector, sizeof(int));
* int *value = malloc(sizeof(int));
* *value = 42;
* zh_vector_emplace_back(&vector, value);
* @endcode
*/
esp_err_t zh_vector_emplace_back(zh_vector_t *vector, void *item);
#ifdef __cplusplus
}
#endif
#endif // ZH_VECTOR_H

File diff suppressed because it is too large Load Diff