Skip to content

Commit

Permalink
Refs #2480 - Abandon use of boost::optional.
Browse files Browse the repository at this point in the history
After a discussion with Martyn it seems likely that for the version of
GCC and/or Boost we have for RHEL6 we are unable to return boost::optional
objects from functions without getting the warning I've been trying to
fix.  Elsewhere, we pass them into functions by reference and therefore
avoid the problem.

I'm not a huge fan of that option, so in this case exceptions will provide
the functionality I need instead.

Also, renamed a function and some variables to make things clearer.
  • Loading branch information
PeterParker committed Mar 10, 2014
1 parent bea4d5b commit 34d3144
Showing 1 changed file with 28 additions and 15 deletions.
43 changes: 28 additions & 15 deletions Code/Mantid/MantidQt/API/src/PropertyWidget.cpp
Expand Up @@ -3,7 +3,6 @@
#include "MantidKernel/EmptyValues.h"
#include "MantidAPI/IWorkspaceProperty.h"

#include <boost/optional.hpp>
#include <boost/assign.hpp>

#include <cmath>
Expand All @@ -22,27 +21,29 @@ namespace // anonymous
{
/**
* Attempts to convert the given string into a double representation of a number.
* Rounding will occur so that "0.0200000000001" will be output as 0.02, for example.
*
* @param s :: the string to convert.
* @returns :: the converted number, wrapped in an optional. Else an empty optional
* if conversion was unsuccesful.
* @returns :: the converted number
*
* @throws std::runtime_error :: if conversion was unsuccesful.
*/
boost::optional<double> stringToNumber(const std::string & s)
double stringToRoundedNumber(const std::string & s)
{
// Using std::istringstream is a nice way to do string-to-double conversion
// in this situation as it rounds numbers for us at the same time. Unfortunately,
// commas seem to confuse it ("0,0,0" is converted to "0" without any warning).
const bool containsComma = s.find(",") != std::string::npos;
if( containsComma )
return boost::optional<double>();
throw std::runtime_error("");

std::istringstream i(s);
double result;
double roundedNumber;

if (!(i >> result))
return boost::optional<double>();
if (!(i >> roundedNumber))
throw std::runtime_error("");

return boost::optional<double>(result);
return roundedNumber;
}

/**
Expand Down Expand Up @@ -74,9 +75,15 @@ namespace // anonymous
if( value == "2.14748e+09" )
return true;

const auto number = stringToNumber(value);
if( !number )
double roundedNumber;
try
{
roundedNumber = stringToRoundedNumber(value);
}
catch( std::runtime_error & )
{
return false;
}

static const std::vector<double> EMPTY_NUM_MACROS = boost::assign::list_of
(EMPTY_DBL()) (-DBL_MAX) (DBL_MAX)
Expand All @@ -85,7 +92,7 @@ namespace // anonymous
(static_cast<double>(-INT_MAX))
(static_cast<double>(-LONG_MAX));

return std::find(EMPTY_NUM_MACROS.begin(), EMPTY_NUM_MACROS.end(), *number) != EMPTY_NUM_MACROS.end();
return std::find(EMPTY_NUM_MACROS.begin(), EMPTY_NUM_MACROS.end(), roundedNumber) != EMPTY_NUM_MACROS.end();
}

/**
Expand Down Expand Up @@ -124,17 +131,23 @@ namespace // anonymous
if( defaultValue == "-0" || defaultValue == "-0.0" )
return "0";

const auto number = stringToNumber(defaultValue);
if( !number )
double roundedNumber;
try
{
roundedNumber = stringToRoundedNumber(defaultValue);
}
catch( std::runtime_error & )
{
return defaultValue;
}

// We'd like to round off any instances of "2.7999999999999998", "0.050000000000000003",
// or similar, but we want to keep the decimal point in values like "0.0" or "1.0" since
// they can be a visual clue that a double is expected.
if( defaultValue.length() > 5 )
{
std::stringstream roundedValue;
roundedValue << number.get();
roundedValue << roundedNumber;
return roundedValue.str();
}

Expand Down

0 comments on commit 34d3144

Please sign in to comment.