Skip to content

Commit

Permalink
Add StringToDoubleConverter::StringTo<T> member function templates (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
N-Dekker authored Apr 10, 2021
1 parent af900a7 commit eee1a45
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
36 changes: 36 additions & 0 deletions double-conversion/string-to-double.cc
Original file line number Diff line number Diff line change
Expand Up @@ -779,4 +779,40 @@ float StringToDoubleConverter::StringToFloat(
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
12 changes: 12 additions & 0 deletions double-conversion/string-to-double.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ class StringToDoubleConverter {
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_;
Expand Down
86 changes: 86 additions & 0 deletions test/cctest/test-conversions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5889,3 +5889,89 @@ TEST(StringToDoubleCaseInsensitiveSpecialValues) {
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);
}
}

0 comments on commit eee1a45

Please sign in to comment.