Add utils::stod/stoi

There are drop in replacements for std::stod/stoi, the differences are:
- They are locale independent
- The take string_view arguments.
This commit is contained in:
gfgtdf 2024-12-11 01:19:02 +01:00
parent 1bd64bd8aa
commit e28217b213
2 changed files with 34 additions and 5 deletions

View file

@ -24,6 +24,7 @@
#include "log.hpp"
#include "serialization/string_utils.hpp"
#include "serialization/unicode.hpp"
#include "utils/charconv.hpp"
#include "utils/general.hpp"
#include <array>
#include <limits>
@ -866,7 +867,7 @@ std::pair<int, int> parse_range(const std::string& str)
// both of those will report an invalid range.
res.first = std::numeric_limits<int>::min();
} else {
res.first = std::stoi(a);
res.first = utils::stoi(a);
}
if(!b) {
@ -874,7 +875,7 @@ std::pair<int, int> parse_range(const std::string& str)
} else if(*b == "infinity") {
res.second = std::numeric_limits<int>::max();
} else {
res.second = std::stoi(*b);
res.second = utils::stoi(*b);
if(res.second < res.first) {
res.second = res.first;
}
@ -898,7 +899,7 @@ std::pair<double, double> parse_range_real(const std::string& str)
"Don't know how negative infinity is treated on this architecture");
res.first = -std::numeric_limits<double>::infinity();
} else {
res.first = std::stod(a);
res.first = utils::stod(a);
}
if(!b) {
@ -906,7 +907,7 @@ std::pair<double, double> parse_range_real(const std::string& str)
} else if(*b == "infinity") {
res.second = std::numeric_limits<double>::infinity();
} else {
res.second = std::stod(*b);
res.second = utils::stod(*b);
if(res.second < res.first) {
res.second = res.first;
}

View file

@ -21,7 +21,7 @@
#include <cctype>
#include <string_view>
#include <string>
#include <stdexcept>
// The gcc implemenetation of from_chars is in some versions just a temporaty solution that calls
// strtod that's why we prefer the boost version if available.
#if BOOST_VERSION >= 108500 && __has_include(<boost/charconv.hpp>)
@ -134,4 +134,32 @@ namespace utils
return std::string(buffer.data(), size);
}
};
/// Same interface as std::stod and meant as a drop in replacement, except:
/// - It takes a std::string_view
/// - It is locale independent
inline double stod(std::string_view str) {
trim_for_from_chars(str);
double res;
auto [ptr, ec] = utils::charconv::from_chars(str.data(), str.data() + str.size(), res);
if(ec == std::errc::invalid_argument) {
throw std::invalid_argument("");
} else if(ec == std::errc::result_out_of_range) {
throw std::out_of_range("");
}
return res;
}
/// Same interface as std::stoi and meant as a drop in replacement, except:
/// - It takes a std::string_view
inline int stoi(std::string_view str) {
trim_for_from_chars(str);
int res;
auto [ptr, ec] = utils::charconv::from_chars(str.data(), str.data() + str.size(), res);
if(ec == std::errc::invalid_argument) {
throw std::invalid_argument("");
} else if(ec == std::errc::result_out_of_range) {
throw std::out_of_range("");
}
return res;
}
}