From 7586d07243ee8338db25ee33e12fb191229e41b9 Mon Sep 17 00:00:00 2001 From: chatlanin Date: Thu, 30 Oct 2025 13:40:36 +0300 Subject: [PATCH] add base comparator aray from different app --- bin/examples/comparators/main.cpp | 10 +++ bin/meson.build | 3 +- src/hack/comparators/comparators.hpp | 123 +++++++++++++++++++++++++++ src/meson.build | 1 + 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 bin/examples/comparators/main.cpp create mode 100644 src/hack/comparators/comparators.hpp diff --git a/bin/examples/comparators/main.cpp b/bin/examples/comparators/main.cpp new file mode 100644 index 0000000..d9ca35d --- /dev/null +++ b/bin/examples/comparators/main.cpp @@ -0,0 +1,10 @@ +#include "hack/comparators/comparators.hpp" + +auto main(int argc, char *argv[]) -> int +{ + std::vector frequencies = { 30.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.00, 196.00, 207.65, 220.00, 233.08, 246.94 }; + float c_array[] = { 130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.00, 196.00, 207.65, 220.00, 233.08, 246.94 }; + + hack::comparators::source(c_array, frequencies.size(), "/mnt/raid/projects/hack/hack/bin/examples/comparators/test.txt"); + hack::comparators::compare(frequencies, "/mnt/raid/projects/hack/hack/bin/examples/comparators/test.txt"); +} diff --git a/bin/meson.build b/bin/meson.build index 178ba33..3c264da 100755 --- a/bin/meson.build +++ b/bin/meson.build @@ -5,8 +5,9 @@ executable( # 'examples/math/main.cpp', # 'examples/range/main.cpp', # 'examples/patterns/main.cpp', - 'examples/logger/main.cpp', + # 'examples/logger/main.cpp', # 'examples/exception/main.cpp', + 'examples/comparators/main.cpp', dependencies : deps, cpp_args: args, include_directories : inc diff --git a/src/hack/comparators/comparators.hpp b/src/hack/comparators/comparators.hpp new file mode 100644 index 0000000..3b11a02 --- /dev/null +++ b/src/hack/comparators/comparators.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "hack/logger/logger.hpp" + +namespace hack::comparators +{ + template + inline void source(const T* array, size_t size, const std::filesystem::path& path) + { + // Проверяем, что указатель не нулевой + if (!array) throw std::invalid_argument("Array pointer cannot be null"); + + // Открываем файл для записи в бинарном режиме + std::ofstream file(path, std::ios::binary); + if (!file.is_open()) throw std::runtime_error("Cannot open file for writing: " + path.string()); + + // Записываем размер массива (количество элементов) + file.write(reinterpret_cast(&size), sizeof(size_t)); + + // Записываем данные массива + file.write(reinterpret_cast(array), size * sizeof(T)); + + // Проверяем успешность записи + if (!file) throw std::runtime_error("Failed to write data to file: " + path.string()); + + log().set_devider(""); + log()("Array saved to: ", path.filename(), " (size: ", size, ", type: ", typeid(T).name(), ")" ); + log().reset(); + } + + namespace { + struct comp_result + { + bool m_is_equal; // Результат сравнения + size_t m_file_size; // Размер массива из файла + size_t m_input_size; // Размер входного массива + size_t m_mismatch_count; // Количество несовпадающих элементов + std::vector m_mismatch_indices; // Индексы несовпадений + }; + + // epsilon - допустимая погрешность для float + template + comp_result compare_float_array_with_file(const std::vector& in, const std::filesystem::path& path, float epsilon = 1e-6f) + { + comp_result res{}; + + // Открываем файл для чтения в бинарном режиме + std::ifstream file(path, std::ios::binary); + if (!file.is_open()) throw std::runtime_error("Cannot open file for reading: " + path.string()); + + // Читаем размер массива из файла + size_t file_size = 0; + file.read(reinterpret_cast(&file_size), sizeof(size_t)); + if (!file) throw std::runtime_error("Failed to read array size from file: " + path.string()); + + res.m_file_size = file_size; + res.m_input_size = in.size(); + + // Сравниваем размеры + if (file_size != in.size()) + { + res.m_is_equal = false; + return res; + } + + // Создаём вектор для данных из файла + std::vector file_array(file_size); + + // Читаем данные из файла + if (file_size > 0) + { + file.read(reinterpret_cast(file_array.data()), file_size * sizeof(float)); + if (!file) throw std::runtime_error("Failed to read data from file: " + path.string()); + } + + // Сравниваем элементы с учётом погрешности + res.m_mismatch_count = 0; + for (size_t i = 0; i < file_size; ++i) + { + if (std::fabs(file_array[i] - in[i]) > epsilon) + { + ++res.m_mismatch_count; + res.m_mismatch_indices.push_back(i); + } + } + + res.m_is_equal = (res.m_mismatch_count == 0); + + return res; + } + + template + inline void compare(const std::vector& in, const std::filesystem::path& path, float epsilon = 1e-6f) + { + auto r = compare_float_array_with_file(in, path, epsilon); + log().set_devider(""); + log()("result: ", r.m_is_equal == true ? "TRUE " : "FALSE "); + if (!r.m_is_equal) + { + log()("total errors: ", r.m_mismatch_count); + log()("source size: ", r.m_file_size, " target size: ", r.m_input_size); + log()("mismatch indices: ", r.m_mismatch_indices); + } + log().reset(); + + try + { + if (std::filesystem::exists(path)) + std::filesystem::remove(path); + } + catch (const std::filesystem::filesystem_error& e) + { + error()("Failed to delete file: ", e.what()); + } + } + } +} diff --git a/src/meson.build b/src/meson.build index 797fb62..d06ecd4 100755 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,7 @@ headers = [ 'hack/audio/play.hpp', 'hack/audio/save.hpp', + 'hack/comparators/comparators.hpp', 'hack/concepts/concepts.hpp',