148 lines
5.2 KiB
Diff
148 lines
5.2 KiB
Diff
# HG changeset patch
|
|
# User Rich Mattes <richmattes@gmail.com>
|
|
# Date 1451958768 18000
|
|
# Branch hex_float_fix
|
|
# Node ID 60b241197b435339efd4e60aa48d1127dd48fee0
|
|
# Parent e720a29dc3df958af3101297f9fb72c27f4bd62e
|
|
Use stof functions to parse hex strings as floating point params
|
|
|
|
This commit changes the Param.cc parsing of floating point values to always
|
|
use the stof family of functions to parse parameters given as hex strings
|
|
(e.g. strings starting with 0x or 0X). It removes the special case handling
|
|
for hex strings in the parser, and processes all strings using the same logic.
|
|
The isHex check is now used to specify the correct numeric base for the integer
|
|
conversion functions.
|
|
|
|
This commit also removes the boost special case in the HexFloat/HexDouble
|
|
Param.cc unit tests. Comments around the special case indicated that
|
|
boost::lexical_cast is able to handle parsing floats from hex values in boost
|
|
versions 1.58.0 and higher. This appears not to be the case based on
|
|
issue #108. The stof family does handle these hex strings properly, so the
|
|
revised tests always expect successful parsing. Tests were also added to parse
|
|
the hex value 0X2A with a capital X and an arbitrary numerical value.
|
|
|
|
Tested with gcc 5.3.1 and boost 1.58.0 on Fedora 23.
|
|
|
|
diff --git a/src/Param.cc b/src/Param.cc
|
|
--- a/src/Param.cc
|
|
+++ b/src/Param.cc
|
|
@@ -398,40 +398,28 @@
|
|
|
|
try
|
|
{
|
|
- // If the string is hex, try to use stoi and stoul, and then
|
|
- // lexical cast as a last resort.
|
|
+ // Try to use stoi and stoul for integers, and
|
|
+ // stof and stod for floating point values.
|
|
+ // Use boost lexical cast as a last resort.
|
|
+ int numericBase = 10;
|
|
if (isHex)
|
|
+ numericBase = 16;
|
|
+
|
|
+ if (this->dataPtr->typeName == "int")
|
|
+ this->dataPtr->value = std::stoi(tmp, NULL, numericBase);
|
|
+ else if (this->dataPtr->typeName == "unsigned int")
|
|
{
|
|
- if (this->dataPtr->typeName == "int")
|
|
- this->dataPtr->value = std::stoi(tmp, NULL, 16);
|
|
- else if (this->dataPtr->typeName == "unsigned int")
|
|
- {
|
|
- this->dataPtr->value = static_cast<unsigned int>(
|
|
- std::stoul(tmp, NULL, 16));
|
|
- }
|
|
- else
|
|
- {
|
|
- boost::apply_visitor(string_set(tmp), this->dataPtr->value);
|
|
- }
|
|
+ this->dataPtr->value = static_cast<unsigned int>(
|
|
+ std::stoul(tmp, NULL, numericBase));
|
|
}
|
|
- // Otherwise use stod, stof, and lexical cast
|
|
+ else if (this->dataPtr->typeName == "double")
|
|
+ this->dataPtr->value = std::stod(tmp);
|
|
+ else if (this->dataPtr->typeName == "float")
|
|
+ this->dataPtr->value = std::stof(tmp);
|
|
else
|
|
- {
|
|
- if (this->dataPtr->typeName == "int")
|
|
- this->dataPtr->value = std::stoi(tmp, NULL, 10);
|
|
- else if (this->dataPtr->typeName == "unsigned int")
|
|
- {
|
|
- this->dataPtr->value = static_cast<unsigned int>(
|
|
- std::stoul(tmp, NULL, 10));
|
|
- }
|
|
- else if (this->dataPtr->typeName == "double")
|
|
- this->dataPtr->value = std::stod(tmp);
|
|
- else if (this->dataPtr->typeName == "float")
|
|
- this->dataPtr->value = std::stof(tmp);
|
|
- else
|
|
- boost::apply_visitor(string_set(tmp), this->dataPtr->value);
|
|
- }
|
|
+ boost::apply_visitor(string_set(tmp), this->dataPtr->value);
|
|
}
|
|
+
|
|
// Catch invalid argument exception from std::stoi/stoul/stod/stof
|
|
catch(std::invalid_argument &)
|
|
{
|
|
diff --git a/src/Param_TEST.cc b/src/Param_TEST.cc
|
|
--- a/src/Param_TEST.cc
|
|
+++ b/src/Param_TEST.cc
|
|
@@ -147,21 +147,13 @@
|
|
EXPECT_TRUE(floatParam.Get<float>(value));
|
|
EXPECT_FLOAT_EQ(value, 0.0f);
|
|
|
|
- // Boost 1.58 and higher parses hex integers into floating point variables
|
|
- // successfully, while older versions don't
|
|
-#if (BOOST_VERSION >= 105800)
|
|
- {
|
|
- EXPECT_TRUE(floatParam.SetFromString("0x01"));
|
|
- EXPECT_TRUE(floatParam.Get<float>(value));
|
|
- EXPECT_FLOAT_EQ(value, 1.0f);
|
|
- }
|
|
-#else
|
|
- {
|
|
- EXPECT_FALSE(floatParam.SetFromString("0x01"));
|
|
- EXPECT_TRUE(floatParam.Get<float>(value));
|
|
- EXPECT_FLOAT_EQ(value, 0.0f);
|
|
- }
|
|
-#endif
|
|
+ EXPECT_TRUE(floatParam.SetFromString("0x01"));
|
|
+ EXPECT_TRUE(floatParam.Get<float>(value));
|
|
+ EXPECT_FLOAT_EQ(value, 1.0f);
|
|
+
|
|
+ EXPECT_TRUE(floatParam.SetFromString("0X2A"));
|
|
+ EXPECT_TRUE(floatParam.Get<float>(value));
|
|
+ EXPECT_FLOAT_EQ(value, 42.0f);
|
|
|
|
EXPECT_TRUE(floatParam.SetFromString("0.123"));
|
|
EXPECT_TRUE(floatParam.Get<float>(value));
|
|
@@ -181,21 +173,13 @@
|
|
EXPECT_TRUE(doubleParam.Get<double>(value));
|
|
EXPECT_DOUBLE_EQ(value, 0.0);
|
|
|
|
- // Boost 1.58 and higher parses hex integers into floating point variables
|
|
- // successfully, while older versions don't
|
|
-#if (BOOST_VERSION >= 105800)
|
|
- {
|
|
- EXPECT_TRUE(doubleParam.SetFromString("0x01"));
|
|
- EXPECT_TRUE(doubleParam.Get<double>(value));
|
|
- EXPECT_DOUBLE_EQ(value, 1.0);
|
|
- }
|
|
-#else
|
|
- {
|
|
- EXPECT_FALSE(doubleParam.SetFromString("0x01"));
|
|
- EXPECT_TRUE(doubleParam.Get<double>(value));
|
|
- EXPECT_DOUBLE_EQ(value, 0.0);
|
|
- }
|
|
-#endif
|
|
+ EXPECT_TRUE(doubleParam.SetFromString("0x01"));
|
|
+ EXPECT_TRUE(doubleParam.Get<double>(value));
|
|
+ EXPECT_DOUBLE_EQ(value, 1.0);
|
|
+
|
|
+ EXPECT_TRUE(doubleParam.SetFromString("0X2A"));
|
|
+ EXPECT_TRUE(doubleParam.Get<double>(value));
|
|
+ EXPECT_DOUBLE_EQ(value, 42.0);
|
|
|
|
EXPECT_TRUE(doubleParam.SetFromString("0.123"));
|
|
EXPECT_TRUE(doubleParam.Get<double>(value));
|