@@ -70,23 +70,26 @@ class ICEBERG_EXPORT StringUtils {
7070 }
7171
7272 template <typename T>
73- requires std::is_arithmetic_v <T> && (!std::same_as<T, bool >)
73+ requires std::is_integral_v <T> && (!std::same_as<T, bool >)
7474 static Result<T> ParseNumber (std::string_view str) {
75- T value = 0 ;
76- if constexpr (std::is_integral_v<T>) {
77- auto [ptr, ec] = std::from_chars (str.data (), str.data () + str.size (), value);
78- if (ec == std::errc () && ptr == str.data () + str.size ()) [[likely]] {
79- return value;
80- }
81- if (ec == std::errc::result_out_of_range) {
82- return InvalidArgument (" Failed to parse {} from string '{}': value out of range" ,
83- typeid (T).name (), str);
84- }
85- return InvalidArgument (" Failed to parse {} from string '{}': invalid argument" ,
75+ T value{};
76+ auto [ptr, ec] = std::from_chars (str.data (), str.data () + str.size (), value);
77+ if (ec == std::errc () && ptr == str.data () + str.size ()) [[likely]] {
78+ return value;
79+ }
80+ if (ec == std::errc::result_out_of_range) {
81+ return InvalidArgument (" Failed to parse {} from string '{}': value out of range" ,
8682 typeid (T).name (), str);
87- } else {
88- // libc++ 20+ provides floating-point std::from_chars. Use fallback for older libc++
89- #if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 200000
83+ }
84+ return InvalidArgument (" Failed to parse {} from string '{}': invalid argument" ,
85+ typeid (T).name (), str);
86+ }
87+
88+ template <typename T>
89+ requires std::is_floating_point_v<T>
90+ static Result<T> ParseNumber (std::string_view str) {
91+ T value{};
92+ if constexpr (kHasFloatFromChars ) {
9093 auto [ptr, ec] = std::from_chars (str.data (), str.data () + str.size (), value);
9194 if (ec == std::errc () && ptr == str.data () + str.size ()) [[likely]] {
9295 return value;
@@ -97,7 +100,7 @@ class ICEBERG_EXPORT StringUtils {
97100 }
98101 return InvalidArgument (" Failed to parse {} from string '{}': invalid argument" ,
99102 typeid (T).name (), str);
100- # else
103+ } else {
101104 // strto* require null-terminated input; string_view does not guarantee it.
102105 std::string owned (str);
103106 const char * start = owned.c_str ();
@@ -121,9 +124,17 @@ class ICEBERG_EXPORT StringUtils {
121124 typeid (T).name (), str);
122125 }
123126 return value;
124- #endif
125127 }
126128 }
129+
130+ private:
131+ // libc++ 20+ provides floating-point std::from_chars; use strto* fallback for older
132+ // versions.
133+ #if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 200000
134+ static constexpr bool kHasFloatFromChars = false ;
135+ #else
136+ static constexpr bool kHasFloatFromChars = true ;
137+ #endif
127138};
128139
129140// / \brief Transparent hash function that supports std::string_view as lookup key
0 commit comments