Commit 1ceec221 by Maarten L. Hekkelman

Better conversion from string to int

parent 641f06a7
......@@ -2,6 +2,7 @@ Version 5.2.2
- Remove dependency on Eigen3 for users of libcifpp
- Fix typos in documentation
- Do not build latex files in documentation
- Fixed conversion from string to integer, would fail on +2 e.g.
Version 5.2.1
- New versionstring module
......
......@@ -459,9 +459,14 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
{
auto txt = ref.text();
std::from_chars_result r = selected_charconv<value_type>::from_chars(txt.data(), txt.data() + txt.size(), result);
auto b = txt.data();
auto e = txt.data() + txt.size();
if (r.ec != std::errc())
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
selected_charconv<value_type>::from_chars(b + 1, e, result) :
selected_charconv<value_type>::from_chars(b, e, result);
if (r.ec != std::errc() or r.ptr != e)
{
result = {};
if (cif::VERBOSE)
......@@ -470,6 +475,8 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
std::cerr << "Attempt to convert " << std::quoted(txt) << " into a number\n";
else if (r.ec == std::errc::result_out_of_range)
std::cerr << "Conversion of " << std::quoted(txt) << " into a type that is too small\n";
else
std::cerr << "Not a valid number " << std::quoted(txt) << '\n';
}
}
}
......@@ -489,9 +496,14 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
{
value_type v = {};
std::from_chars_result r = selected_charconv<value_type>::from_chars(txt.data(), txt.data() + txt.size(), v);
auto b = txt.data();
auto e = txt.data() + txt.size();
if (r.ec != std::errc())
std::from_chars_result r = (b + 1 < e and *b == '+' and std::isdigit(b[1])) ?
selected_charconv<value_type>::from_chars(b + 1, e, v) :
selected_charconv<value_type>::from_chars(b, e, v);
if (r.ec != std::errc() or r.ptr != e)
{
if (cif::VERBOSE)
{
......@@ -499,6 +511,8 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_arithmetic_v<T> an
std::cerr << "Attempt to convert " << std::quoted(txt) << " into a number\n";
else if (r.ec == std::errc::result_out_of_range)
std::cerr << "Conversion of " << std::quoted(txt) << " into a type that is too small\n";
else
std::cerr << "Not a valid number " << std::quoted(txt) << '\n';
}
result = 1;
}
......
......@@ -150,6 +150,31 @@ BOOST_AUTO_TEST_CASE(cc_2)
}
}
BOOST_AUTO_TEST_CASE(cc_3)
{
cif::category c("foo");
c.emplace({
{ "f-1", 1 },
{ "f-2", "-1" },
{ "f-3", "+1" },
{ "f-4", " 1" },
{ "f-5", " +1" },
{ "f-6", "1 " },
});
auto row = c.front();
BOOST_CHECK_EQUAL(row["f-1"].as<int>(), 1);
BOOST_CHECK_EQUAL(row["f-2"].as<int>(), -1);
BOOST_CHECK_EQUAL(row["f-3"].as<int>(), 1);
// BOOST_CHECK_THROW(row["f-4"].as<int>(), std::exception);
// BOOST_CHECK_THROW(row["f-5"].as<int>(), std::exception);
// BOOST_CHECK_THROW(row["f-6"].as<int>(), std::exception);
BOOST_CHECK_EQUAL(row["f-4"].as<int>(), 0);
BOOST_CHECK_EQUAL(row["f-5"].as<int>(), 0);
BOOST_CHECK_EQUAL(row["f-6"].as<int>(), 0);
}
BOOST_AUTO_TEST_CASE(item_1)
{
using namespace cif;
......
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