Commit 473f4927 authored by Praetorius, Simon's avatar Praetorius, Simon

return value of from_chars with consumed characters

parent 8e11daa7
Pipeline #1610 passed with stage
in 12 minutes and 41 seconds
......@@ -89,13 +89,15 @@ namespace Dune
if (s.fail()) {
if (value == std::numeric_limits<T>::max() || value == std::numeric_limits<T>::min())
// range error
return from_chars_result{first + s.tellg(), std::errc::result_out_of_range};
return from_chars_result{s.eof() ? last : first, std::errc::result_out_of_range};
else
// extraction fails
return from_chars_result{first, std::errc::invalid_argument};
}
return from_chars_result{first + s.tellg(), std::errc{}};
// NOTE: Can not determine pointer to the first character not matching the pattern.
// Returning last if all characters are consumed.
return from_chars_result{s.eof() ? last : first, std::errc{}};
}
template<typename T, typename StreamManipulator>
......
......@@ -60,19 +60,17 @@ namespace Dune
T value;
auto result = Std::from_chars(first, last, value);
// require that all characters are consumed during conversion
char const* end = result.ptr;
bool all_consumed = (end != first);
while (all_consumed && (end != last) && (*end != '\0'))
all_consumed = std::isspace(*end++);
if (result.ec == std::errc::result_out_of_range) {
DUNE_THROW(RangeError, std::error_condition(result.ec).message());
}
else if (result.ec == std::errc::invalid_argument || !all_consumed) {
else if (result.ec == std::errc::invalid_argument) {
DUNE_THROW(InvalidArgument,
"Conversion of '" << first << "' to number failed. Possible reason: invalid string or locale format.");
}
else if (result.ptr != last) {
DUNE_THROW(InvalidArgument,
"Conversion of '" << first << "' to number failed. Not all characters consumed during conversion.");
}
else if (result.ec == std::errc::not_supported) {
DUNE_THROW(NotImplemented,
"Parameter passed to from_chars not supported.");
......@@ -84,7 +82,7 @@ namespace Dune
/// \brief Implementation of a fallback parser using std::strtoXXX like functions
/**
* Allows leading and trailing whitespace characters.
* Allows leading whitespace characters.
* NOTE: This parser is not locale independent, but throws an error if whole
* string can not be parsed completely.
*
......@@ -108,14 +106,10 @@ namespace Dune
DUNE_THROW(RangeError, std::strerror(old_errno));
}
// test whether all non-space characters are consumed during conversion
bool all_consumed = (end != first);
while (all_consumed && (end != last) && (*end != '\0'))
all_consumed = std::isspace(*end++);
if (!all_consumed) {
// test whether all characters are consumed during conversion
if (end != last) {
DUNE_THROW(InvalidArgument,
"Conversion of '" << first << "' to number failed. Possible reason: invalid string or locale format");
"Conversion of '" << first << "' to number failed. Possible reason: invalid string or locale format, or trailing characters.");
}
return convertToRange<T>(x);
......
......@@ -211,7 +211,7 @@ int main()
} catch(Dune::InvalidArgument const&) {
exception = true;
}
test.check(!exception, "InvalidArgument Exception: trailing whitespace");
test.check(exception, "InvalidArgument Exception: trailing whitespace");
exception = false;
try {
......
Markdown is supported
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