2020#pragma once
2121
2222#include < algorithm>
23+ #include < cerrno>
2324#include < charconv>
2425#include < ranges>
2526#include < string>
2627#include < string_view>
28+ #include < type_traits>
2729#include < typeinfo>
2830#include < utility>
2931
3234
3335namespace iceberg {
3436
37+ template <typename T>
38+ concept FromChars = requires (const char * p, T& v) { std::from_chars (p, p, v); };
39+
3540class ICEBERG_EXPORT StringUtils {
3641 public:
3742 static std::string ToLower (std::string_view str) {
@@ -68,7 +73,7 @@ class ICEBERG_EXPORT StringUtils {
6873 }
6974
7075 template <typename T>
71- requires std::is_arithmetic_v<T> && (!std::same_as<T, bool >)
76+ requires std::is_arithmetic_v<T> && FromChars<T> && (!std::same_as<T, bool >)
7277 static Result<T> ParseNumber (std::string_view str) {
7378 T value = 0 ;
7479 auto [ptr, ec] = std::from_chars (str.data (), str.data () + str.size (), value);
@@ -85,6 +90,35 @@ class ICEBERG_EXPORT StringUtils {
8590 }
8691 std::unreachable ();
8792 }
93+
94+ template <typename T>
95+ requires std::is_floating_point_v<T> && (!FromChars<T>)
96+ static Result<T> ParseNumber (std::string_view str) {
97+ T value{};
98+ // strto* require null-terminated input; string_view does not guarantee it.
99+ std::string owned (str);
100+ const char * start = owned.c_str ();
101+ char * end = nullptr ;
102+ errno = 0 ;
103+
104+ if constexpr (std::same_as<T, float >) {
105+ value = std::strtof (start, &end);
106+ } else if constexpr (std::same_as<T, double >) {
107+ value = std::strtod (start, &end);
108+ } else {
109+ value = std::strtold (start, &end);
110+ }
111+
112+ if (end == start || end != start + static_cast <std::ptrdiff_t >(owned.size ())) {
113+ return InvalidArgument (" Failed to parse {} from string '{}': invalid argument" ,
114+ typeid (T).name (), str);
115+ }
116+ if (errno == ERANGE) {
117+ return InvalidArgument (" Failed to parse {} from string '{}': value out of range" ,
118+ typeid (T).name (), str);
119+ }
120+ return value;
121+ }
88122};
89123
90124// / \brief Transparent hash function that supports std::string_view as lookup key
0 commit comments