This is an automated email from the ASF dual-hosted git repository.

gangwu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new 98261472 fix: use strtod fallback when std::from_chars(float) 
unavailable (#572)
98261472 is described below

commit 98261472fc3a5ac93e239bc91ad8ba1d7ecf3fd0
Author: Junwang Zhao <[email protected]>
AuthorDate: Wed Feb 25 17:38:18 2026 +0800

    fix: use strtod fallback when std::from_chars(float) unavailable (#572)
---
 src/iceberg/util/string_util.h | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/iceberg/util/string_util.h b/src/iceberg/util/string_util.h
index 3528204e..fc202f0e 100644
--- a/src/iceberg/util/string_util.h
+++ b/src/iceberg/util/string_util.h
@@ -20,10 +20,12 @@
 #pragma once
 
 #include <algorithm>
+#include <cerrno>
 #include <charconv>
 #include <ranges>
 #include <string>
 #include <string_view>
+#include <type_traits>
 #include <typeinfo>
 #include <utility>
 
@@ -32,6 +34,9 @@
 
 namespace iceberg {
 
+template <typename T>
+concept FromChars = requires(const char* p, T& v) { std::from_chars(p, p, v); 
};
+
 class ICEBERG_EXPORT StringUtils {
  public:
   static std::string ToLower(std::string_view str) {
@@ -68,7 +73,7 @@ class ICEBERG_EXPORT StringUtils {
   }
 
   template <typename T>
-    requires std::is_arithmetic_v<T> && (!std::same_as<T, bool>)
+    requires std::is_arithmetic_v<T> && FromChars<T> && (!std::same_as<T, 
bool>)
   static Result<T> ParseNumber(std::string_view str) {
     T value = 0;
     auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), 
value);
@@ -85,6 +90,35 @@ class ICEBERG_EXPORT StringUtils {
     }
     std::unreachable();
   }
+
+  template <typename T>
+    requires std::is_floating_point_v<T> && (!FromChars<T>)
+  static Result<T> ParseNumber(std::string_view str) {
+    T value{};
+    // strto* require null-terminated input; string_view does not guarantee it.
+    std::string owned(str);
+    const char* start = owned.c_str();
+    char* end = nullptr;
+    errno = 0;
+
+    if constexpr (std::same_as<T, float>) {
+      value = std::strtof(start, &end);
+    } else if constexpr (std::same_as<T, double>) {
+      value = std::strtod(start, &end);
+    } else {
+      value = std::strtold(start, &end);
+    }
+
+    if (end == start || end != start + 
static_cast<std::ptrdiff_t>(owned.size())) {
+      return InvalidArgument("Failed to parse {} from string '{}': invalid 
argument",
+                             typeid(T).name(), str);
+    }
+    if (errno == ERANGE) {
+      return InvalidArgument("Failed to parse {} from string '{}': value out 
of range",
+                             typeid(T).name(), str);
+    }
+    return value;
+  }
 };
 
 /// \brief Transparent hash function that supports std::string_view as lookup 
key

Reply via email to