// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #pragma once #include #include #include #include #include namespace utils { template struct Range { T min; T max; }; /// Perform scaling of the input value based on the input&output ranges. If the input values is not contained within /// the provided input range return std::nullopt. template std::optional scale_value(const Range inputRange, const Range outputRange, const T input) { if (input > inputRange.max || input < inputRange.min) { return {}; } const auto inRangeVal = inputRange.max - inputRange.min; const auto outRangeVal = outputRange.max - outputRange.min; if (outRangeVal == 0 || inRangeVal == 0) { return outputRange.min; } float slope = 1.0 * (outRangeVal) / (inRangeVal); auto output = outputRange.min + slope * (input - inputRange.min); return static_cast(std::floor(output)); } template struct Entry { const Range input; const Range output; }; /// Try to find the given input value in the the entries array. If the value is found, perform scaling and then /// return the scaled value. If the value is not found, return std::nullopt. template [[nodiscard]] std::optional find_and_scale_value(const std::array, N> &entries, const T val) { auto result = std::find_if( entries.begin(), entries.end(), [val](const auto &e) { return val >= e.input.min && val <= e.input.max; }); if (result != entries.end()) { return scale_value(result->input, result->output, val); } return {}; } } // namespace utils