Add `StringToDoubleConverter::StringTo<T>` member function templates (#158)
Allowed users to write generic code more easily, like this (when `T` is
either `float` or `double`):
converter.StringTo<T>(buffer, length, &processed);
Included a unit test, `TEST(StringToTemplate)`.
Fixes #157.
diff --git a/double-conversion/string-to-double.cc b/double-conversion/string-to-double.cc
index 85c3a08..fe633aa 100644
--- a/double-conversion/string-to-double.cc
+++ b/double-conversion/string-to-double.cc
@@ -779,4 +779,40 @@
processed_characters_count));
}
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToFloat(buffer, length, processed_characters_count);
+}
+
+
+template<>
+double StringToDoubleConverter::StringTo<double>(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToDouble(buffer, length, processed_characters_count);
+}
+
+
+template<>
+float StringToDoubleConverter::StringTo<float>(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToFloat(buffer, length, processed_characters_count);
+}
+
} // namespace double_conversion
diff --git a/double-conversion/string-to-double.h b/double-conversion/string-to-double.h
index ecd6c76..770ccbc 100644
--- a/double-conversion/string-to-double.h
+++ b/double-conversion/string-to-double.h
@@ -204,6 +204,18 @@
int length,
int* processed_characters_count) const;
+ // Same as StringToDouble for T = double, and StringToFloat for T = float.
+ template <typename T>
+ T StringTo(const char* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringTo above but for 16 bit characters.
+ template <typename T>
+ T StringTo(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
+
private:
const int flags_;
const double empty_string_value_;
diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc
index 325b7a1..504d946 100644
--- a/test/cctest/test-conversions.cc
+++ b/test/cctest/test-conversions.cc
@@ -5889,3 +5889,89 @@
CHECK_EQ(1.0, converter.StringToDouble("+inf", 4, &processed));
CHECK_EQ(0, processed);
}
+
+
+TEST(StringToTemplate) {
+ // Test StringToDoubleConverter::StringTo<T>.
+
+ const StringToDoubleConverter converter(StringToDoubleConverter::ALLOW_HEX, 0.0, Double::NaN(), "inf", "nan");
+
+ // First simply check conversion from "0" and "1":
+ for (int i = 0; i <= 1; ++i)
+ {
+ const char c = '0' + i;
+
+ int processed = 0;
+ CHECK_EQ(static_cast<double>(i), converter.StringTo<double>(&c, 1, &processed));
+ CHECK_EQ(1, processed);
+
+ processed = 0;
+ CHECK_EQ(static_cast<float>(i), converter.StringTo<float>(&c, 1, &processed));
+ CHECK_EQ(1, processed);
+
+ const uc16 buffer16[1] = { static_cast<uc16>(c) };
+
+ processed = 0;
+ CHECK_EQ(static_cast<double>(i), converter.StringTo<double>(buffer16, 1, &processed));
+ CHECK_EQ(1, processed);
+
+ processed = 0;
+ CHECK_EQ(static_cast<float>(i), converter.StringTo<float>(buffer16, 1, &processed));
+ CHECK_EQ(1, processed);
+ }
+ {
+ // A number that can be represented by a double, but not by a float.
+ // Allows testing that StringTo<double> behaves like StringToDouble
+ // (and not like StringToFloat).
+ const char buffer[] = "1e+100";
+ const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
+
+ int processed1 = 1;
+ int processed2 = 2;
+
+ CHECK_EQ(converter.StringToDouble(buffer, length, &processed1),
+ converter.StringTo<double>(buffer, length, &processed2));
+ CHECK_EQ(processed1, processed2);
+
+ uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
+
+ for (int i = 0; i <= length; ++i) {
+ buffer16[i] = buffer[i];
+ }
+
+ processed1 = 1;
+ processed2 = 2;
+
+ CHECK_EQ(converter.StringToDouble(buffer16, length, &processed1),
+ converter.StringTo<double>(buffer16, length, &processed2));
+ CHECK_EQ(processed1, processed2);
+ }
+ {
+ // The double rounding example from TEST(StringToFloatHexString), which
+ // yields a slightly different result from StringToFloat than from
+ // StringToDouble. Allows testing that StringTo<float> behaves like
+ // StringToFloat (rather than like StringToDouble).
+ const char buffer[] = "0x100000100000008";
+ const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
+
+ int processed1 = 1;
+ int processed2 = 2;
+
+ CHECK_EQ(converter.StringToFloat(buffer, length, &processed1),
+ converter.StringTo<float>(buffer, length, &processed2));
+ CHECK_EQ(processed1, processed2);
+
+ uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
+
+ for (int i = 0; i <= length; ++i) {
+ buffer16[i] = buffer[i];
+ }
+
+ processed1 = 1;
+ processed2 = 2;
+
+ CHECK_EQ(converter.StringToFloat(buffer16, length, &processed1),
+ converter.StringTo<float>(buffer16, length, &processed2));
+ CHECK_EQ(processed1, processed2);
+ }
+}