Reimplement rtc::ToString and rtc::FromString without streams.

Bug: webrtc:8982
Change-Id: I3977435b035fdebef449732301d6e77fc899e7ba
Reviewed-on: https://webrtc-review.googlesource.com/86941
Commit-Queue: Jonas Olsson <jonasolsson@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24319}
diff --git a/rtc_base/string_to_number.cc b/rtc_base/string_to_number.cc
index 06ac9e9..9201242 100644
--- a/rtc_base/string_to_number.cc
+++ b/rtc_base/string_to_number.cc
@@ -48,5 +48,41 @@
   return absl::nullopt;
 }
 
+template <typename T>
+T StrToT(const char* str, char** str_end);
+
+template <>
+inline float StrToT(const char* str, char** str_end) {
+  return std::strtof(str, str_end);
+}
+
+template <>
+inline double StrToT(const char* str, char** str_end) {
+  return std::strtod(str, str_end);
+}
+
+template <>
+inline long double StrToT(const char* str, char** str_end) {
+  return std::strtold(str, str_end);
+}
+
+template <typename T>
+absl::optional<T> ParseFloatingPoint(const char* str) {
+  RTC_DCHECK(str);
+  if (*str == '\0')
+    return absl::nullopt;
+  char* end = nullptr;
+  errno = 0;
+  const T value = StrToT<T>(str, &end);
+  if (end && *end == '\0' && errno == 0) {
+    return value;
+  }
+  return absl::nullopt;
+}
+
+template absl::optional<float> ParseFloatingPoint(const char* str);
+template absl::optional<double> ParseFloatingPoint(const char* str);
+template absl::optional<long double> ParseFloatingPoint(const char* str);
+
 }  // namespace string_to_number_internal
 }  // namespace rtc