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 ...@@ -89,13 +89,15 @@ namespace Dune
if (s.fail()) { if (s.fail()) {
if (value == std::numeric_limits<T>::max() || value == std::numeric_limits<T>::min()) if (value == std::numeric_limits<T>::max() || value == std::numeric_limits<T>::min())
// range error // 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 else
// extraction fails // extraction fails
return from_chars_result{first, std::errc::invalid_argument}; 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> template<typename T, typename StreamManipulator>
......
...@@ -60,19 +60,17 @@ namespace Dune ...@@ -60,19 +60,17 @@ namespace Dune
T value; T value;
auto result = Std::from_chars(first, last, 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) { if (result.ec == std::errc::result_out_of_range) {
DUNE_THROW(RangeError, std::error_condition(result.ec).message()); 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, 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.");
} }
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) { else if (result.ec == std::errc::not_supported) {
DUNE_THROW(NotImplemented, DUNE_THROW(NotImplemented,
"Parameter passed to from_chars not supported."); "Parameter passed to from_chars not supported.");
...@@ -84,7 +82,7 @@ namespace Dune ...@@ -84,7 +82,7 @@ namespace Dune
/// \brief Implementation of a fallback parser using std::strtoXXX like functions /// \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 * NOTE: This parser is not locale independent, but throws an error if whole
* string can not be parsed completely. * string can not be parsed completely.
* *
...@@ -108,14 +106,10 @@ namespace Dune ...@@ -108,14 +106,10 @@ namespace Dune
DUNE_THROW(RangeError, std::strerror(old_errno)); DUNE_THROW(RangeError, std::strerror(old_errno));
} }
// test whether all non-space characters are consumed during conversion // test whether all characters are consumed during conversion
bool all_consumed = (end != first); if (end != last) {
while (all_consumed && (end != last) && (*end != '\0'))
all_consumed = std::isspace(*end++);
if (!all_consumed) {
DUNE_THROW(InvalidArgument, 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); return convertToRange<T>(x);
......
...@@ -211,7 +211,7 @@ int main() ...@@ -211,7 +211,7 @@ int main()
} catch(Dune::InvalidArgument const&) { } catch(Dune::InvalidArgument const&) {
exception = true; exception = true;
} }
test.check(!exception, "InvalidArgument Exception: trailing whitespace"); test.check(exception, "InvalidArgument Exception: trailing whitespace");
exception = false; exception = false;
try { 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