Skip to content

Commit 41d3f37

Browse files
committed
Add StringToDoubleConverter::StringTo<T> member function templates
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 issue #157 With help from Florian Loitsch (floitsch)
1 parent af900a7 commit 41d3f37

3 files changed

Lines changed: 133 additions & 0 deletions

File tree

double-conversion/string-to-double.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,40 @@ float StringToDoubleConverter::StringToFloat(
779779
processed_characters_count));
780780
}
781781

782+
783+
template<>
784+
double StringToDoubleConverter::StringTo<double>(
785+
const char* buffer,
786+
int length,
787+
int* processed_characters_count) const {
788+
return StringToDouble(buffer, length, processed_characters_count);
789+
}
790+
791+
792+
template<>
793+
float StringToDoubleConverter::StringTo<float>(
794+
const char* buffer,
795+
int length,
796+
int* processed_characters_count) const {
797+
return StringToFloat(buffer, length, processed_characters_count);
798+
}
799+
800+
801+
template<>
802+
double StringToDoubleConverter::StringTo<double>(
803+
const uc16* buffer,
804+
int length,
805+
int* processed_characters_count) const {
806+
return StringToDouble(buffer, length, processed_characters_count);
807+
}
808+
809+
810+
template<>
811+
float StringToDoubleConverter::StringTo<float>(
812+
const uc16* buffer,
813+
int length,
814+
int* processed_characters_count) const {
815+
return StringToFloat(buffer, length, processed_characters_count);
816+
}
817+
782818
} // namespace double_conversion

double-conversion/string-to-double.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,20 @@ class StringToDoubleConverter {
204204
int length,
205205
int* processed_characters_count) const;
206206

207+
// Same as StringToDouble for T = double, and StringToFloat for T = float.
208+
template <typename T>
209+
T StringTo(
210+
const char* buffer,
211+
int length,
212+
int* processed_characters_count) const;
213+
214+
// Same as StringTo above but for 16 bit characters.
215+
template <typename T>
216+
T StringTo(
217+
const uc16* buffer,
218+
int length,
219+
int* processed_characters_count) const;
220+
207221
private:
208222
const int flags_;
209223
const double empty_string_value_;

test/cctest/test-conversions.cc

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5889,3 +5889,86 @@ TEST(StringToDoubleCaseInsensitiveSpecialValues) {
58895889
CHECK_EQ(1.0, converter.StringToDouble("+inf", 4, &processed));
58905890
CHECK_EQ(0, processed);
58915891
}
5892+
5893+
5894+
TEST(StringToTemplate) {
5895+
const StringToDoubleConverter converter(StringToDoubleConverter::ALLOW_HEX, 0.0, Double::NaN(), "inf", "nan");
5896+
{
5897+
int processed = 0;
5898+
CHECK_EQ(converter.StringTo<double>("1", 1, &processed), 1.0);
5899+
CHECK_EQ(processed, 1);
5900+
5901+
processed = 0;
5902+
CHECK_EQ(converter.StringTo<float>("1", 1, &processed), 1.0f);
5903+
CHECK_EQ(processed, 1);
5904+
5905+
const uc16 buffer16[1] = { static_cast<uc16>('1') };
5906+
5907+
processed = 0;
5908+
CHECK_EQ(converter.StringTo<double>(buffer16, 1, &processed), 1.0);
5909+
CHECK_EQ(processed, 1);
5910+
5911+
processed = 0;
5912+
CHECK_EQ(converter.StringTo<float>(buffer16, 1, &processed), 1.0f);
5913+
CHECK_EQ(processed, 1);
5914+
}
5915+
{
5916+
// A number that can be represented by a double, but not by a float.
5917+
// Allows testing that StringTo<double> behaves like StringToDouble
5918+
// (and not like StringToFloat).
5919+
const char buffer[] = "1e+100";
5920+
const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
5921+
5922+
int processed1 = 1;
5923+
int processed2 = 2;
5924+
5925+
CHECK_EQ(
5926+
converter.StringToDouble(buffer, length, &processed1),
5927+
converter.StringTo<double>(buffer, length, &processed2));
5928+
CHECK_EQ(processed1, processed2);
5929+
5930+
uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
5931+
5932+
for (int i = 0; i <= length; ++i) {
5933+
buffer16[i] = buffer[i];
5934+
}
5935+
5936+
processed1 = 1;
5937+
processed2 = 2;
5938+
5939+
CHECK_EQ(
5940+
converter.StringToDouble(buffer16, length, &processed1),
5941+
converter.StringTo<double>(buffer16, length, &processed2));
5942+
CHECK_EQ(processed1, processed2);
5943+
}
5944+
{
5945+
// The double rounding example from TEST(StringToFloatHexString), which
5946+
// yields a slightly different result from StringToFloat than from
5947+
// StringToDouble. Allows testing that StringTo<float> behaves like
5948+
// StringToFloat (rather than like StringToDouble).
5949+
const char buffer[] = "0x100000100000008";
5950+
const int length = DOUBLE_CONVERSION_ARRAY_SIZE(buffer) - 1;
5951+
5952+
int processed1 = 1;
5953+
int processed2 = 2;
5954+
5955+
CHECK_EQ(
5956+
converter.StringToFloat(buffer, length, &processed1),
5957+
converter.StringTo<float>(buffer, length, &processed2));
5958+
CHECK_EQ(processed1, processed2);
5959+
5960+
uc16 buffer16[DOUBLE_CONVERSION_ARRAY_SIZE(buffer)];
5961+
5962+
for (int i = 0; i <= length; ++i) {
5963+
buffer16[i] = buffer[i];
5964+
}
5965+
5966+
processed1 = 1;
5967+
processed2 = 2;
5968+
5969+
CHECK_EQ(
5970+
converter.StringToFloat(buffer16, length, &processed1),
5971+
converter.StringTo<float>(buffer16, length, &processed2));
5972+
CHECK_EQ(processed1, processed2);
5973+
}
5974+
}

0 commit comments

Comments
 (0)