From 2388b21f63dccdfd90e0933eb51cbf63946fe87f Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 3 Oct 2022 23:30:16 +0200 Subject: [PATCH] Use std::from_chars to parse settings integral numbers and handle errors --- components/settings/settings.cpp | 54 ++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index 5dfadd9d50..a09ddfc113 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -1,14 +1,44 @@ #include "settings.hpp" #include "parser.hpp" +#include +#include #include #include +#include #include #include namespace Settings { + namespace + { + template + auto parseIntegralNumber(const std::string& value, std::string_view setting, std::string_view category) + { + T number{}; + const auto result = std::from_chars(value.data(), value.data() + value.size(), number); + if (result.ec != std::errc()) + throw std::system_error(std::make_error_code(result.ec), + "Failed to parse number from setting [" + std::string(category) + "] " + std::string(setting) + + " value \"" + value + "\""); + return number; + } + + template + auto parseFloatingPointNumber(const std::string& value, std::string_view setting, std::string_view category) + { + std::stringstream stream(value); + T number{}; + stream >> number; + if (stream.bad()) + throw std::system_error(errno, std::generic_category(), + "Failed to parse number from setting [" + std::string(category) + "] " + std::string(setting) + + " value \"" + value + "\""); + return number; + } + } CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap(); CategorySettingValueMap Manager::mUserSettings = CategorySettingValueMap(); @@ -109,38 +139,22 @@ namespace Settings float Manager::getFloat(std::string_view setting, std::string_view category) { - const std::string& value = getString(setting, category); - std::stringstream stream(value); - float number = 0.f; - stream >> number; - return number; + return parseFloatingPointNumber(getString(setting, category), setting, category); } double Manager::getDouble(std::string_view setting, std::string_view category) { - const std::string& value = getString(setting, category); - std::stringstream stream(value); - double number = 0.0; - stream >> number; - return number; + return parseFloatingPointNumber(getString(setting, category), setting, category); } int Manager::getInt(std::string_view setting, std::string_view category) { - const std::string& value = getString(setting, category); - std::stringstream stream(value); - int number = 0; - stream >> number; - return number; + return parseIntegralNumber(getString(setting, category), setting, category); } std::int64_t Manager::getInt64(std::string_view setting, std::string_view category) { - const std::string& value = getString(setting, category); - std::stringstream stream(value); - std::int64_t number = 0; - stream >> number; - return number; + return parseIntegralNumber(getString(setting, category), setting, category); } bool Manager::getBool(std::string_view setting, std::string_view category)