Commit c27bff0d authored by Steven Murray's avatar Steven Murray
Browse files

Added utils::isValidDouble() and utils::toDouble()

parent 9e458596
......@@ -484,6 +484,67 @@ TEST_F(cta_UtilsTest, toUint64_not_a_number) {
ASSERT_THROW(utils::toUint64("one"), exception::Exception);
}
TEST_F(cta_UtilsTest, isValidDouble) {
using namespace cta;
ASSERT_TRUE(utils::isValidDouble("1.234"));
}
TEST_F(cta_UtilsTest, isValidDouble_empty_string) {
using namespace cta;
ASSERT_FALSE(utils::isValidDouble(""));
}
TEST_F(cta_UtilsTest, isValidDouble_negative_double) {
using namespace cta;
ASSERT_TRUE(utils::isValidDouble("-1.234"));
}
TEST_F(cta_UtilsTest, isValidDouble_not_a_number) {
using namespace cta;
ASSERT_FALSE(utils::isValidDouble("one"));
}
TEST_F(cta_UtilsTest, isValidDouble_two_decimal_points) {
using namespace cta;
ASSERT_FALSE(utils::isValidDouble("1.2.34"));
}
TEST_F(cta_UtilsTest, toDouble_double) {
using namespace cta;
ASSERT_EQ((double)1.234, utils::toDouble("1.234"));
}
TEST_F(cta_UtilsTest, toDouble_negative_double) {
using namespace cta;
ASSERT_EQ((double)-1.234, utils::toDouble("-1.234"));
}
TEST_F(cta_UtilsTest, toDouble_too_big) {
using namespace cta;
// std::numeric_limits<double>::max=1.79769e+308
ASSERT_THROW(utils::toDouble("1.79770e+308"), exception::Exception);
}
TEST_F(cta_UtilsTest, toDouble_empty_string) {
using namespace cta;
ASSERT_THROW(utils::toDouble(""), exception::Exception);
}
TEST_F(cta_UtilsTest, toDouble_not_a_number) {
using namespace cta;
ASSERT_THROW(utils::toDouble("one"), exception::Exception);
}
TEST_F(cta_UtilsTest, adler32_empty_buf) {
using namespace cta;
......
......@@ -638,6 +638,61 @@ uint64_t toUint64(const std::string &str) {
}
}
//------------------------------------------------------------------------------
// isValidDouble
//------------------------------------------------------------------------------
bool isValidDouble(const std::string &str) {
// An empty string is not a valid double
if(str.empty()) {
return false;
}
uint64_t nbDecimalPoints = 0;
// For each character in the string
for(std::string::const_iterator itor = str.begin(); itor != str.end(); itor++) {
const bool isFirstChar = itor == str.begin();
const bool isMinusChar = '-' == *itor;
const bool isANumericalDigit = '0' <= *itor && *itor <= '9';
const bool isADecimalPoint = '.' == *itor;
if(!(isFirstChar && isMinusChar) && !isANumericalDigit && !isADecimalPoint) {
return false;
}
if(isADecimalPoint) {
nbDecimalPoints++;
}
if(1 < nbDecimalPoints) {
return false;
}
}
return true;
}
//------------------------------------------------------------------------------
// toDouble
//------------------------------------------------------------------------------
double toDouble(const std::string &str) {
try {
try {
return std::stod(str);
} catch(std::invalid_argument &) {
throw exception::Exception("Invalid double");
} catch(std::out_of_range &) {
throw exception::Exception("Out of range");
} catch(std::exception &se) {
throw exception::Exception(se.what());
}
} catch(exception::Exception &ex) {
throw exception::Exception(std::string("Failed to parse ") + str + " as a double: " +
ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// toUpper
//------------------------------------------------------------------------------
......
......@@ -280,6 +280,21 @@ namespace utils {
*/
uint64_t toUint64(const std::string &str);
/**
* Checks if the specified string is a double unsigned integer.
*
* @param str The string to be checked.
* @returns true if the string is a valid double, else false.
*/
bool isValidDouble(const std::string &str);
/**
* Parses the specified string representation of a double.
*
* @return The parsed double.
*/
double toDouble(const std::string &str);
/**
* Converts the specified string to uppercase.
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment