Refactored to avoid using exceptions, as there are plans to support exceptionless mode

This commit is contained in:
Alex Astashyn 2016-12-07 19:53:27 -05:00
parent 6774457733
commit 0a4a6a8399
2 changed files with 118 additions and 38 deletions

View file

@ -9079,10 +9079,42 @@ basic_json_parser_66:
struct strtonum struct strtonum
{ {
public: public:
strtonum(const char* start, const char* end) template<typename T>
struct maybe
{
T x;
bool valid;
maybe(const T& xx)
: x(xx), valid(true)
{}
maybe() : x(), valid(false)
{}
operator bool() const
{
return valid;
}
const T& operator*() const
{
return x;
}
};
strtonum(const char* start, const char* end)
: m_start(start), m_end(end) : m_start(start), m_end(end)
{} {}
template<typename T,
typename = typename std::enable_if<
std::is_arithmetic<T>::value>::type >
bool to(T& val) const
{
return parse(val, std::is_integral<T>());
}
template<typename T, template<typename T,
typename = typename std::enable_if< typename = typename std::enable_if<
std::is_arithmetic<T>::value>::type > std::is_arithmetic<T>::value>::type >
@ -9361,31 +9393,39 @@ basic_json_parser_66:
const bool is_negative = *m_start == '-'; const bool is_negative = *m_start == '-';
try { result.m_type = value_t::discarded;
if (not num.is_integral())
{ if (not num.is_integral())
; {
} ; // will parse as float below
else if (is_negative) }
{ else if (is_negative)
{
number_integer_t val{0};
if(num.to(val)) {
result.m_type = value_t::number_integer; result.m_type = value_t::number_integer;
result.m_value = static_cast<number_integer_t>(num); result.m_value = val;
return;
}
else
{
result.m_type = value_t::number_unsigned;
result.m_value = static_cast<number_unsigned_t>(num);
return;
} }
} }
catch (std::invalid_argument&) else
{ {
; // overflow - will parse as double number_unsigned_t val{0};
if(num.to(val)) {
result.m_type = value_t::number_unsigned;
result.m_value = val;
}
}
number_float_t val{0};
if (result.m_type != value_t::discarded
or !num.to(val))
{
return; // already have a value from above
// or couldn't parse as float_t
} }
result.m_type = value_t::number_float; result.m_type = value_t::number_float;
result.m_value = static_cast<number_float_t>(num); result.m_value = val;
// replace infinity and NAN by null // replace infinity and NAN by null
if (not std::isfinite(result.m_value.number_float)) if (not std::isfinite(result.m_value.number_float))

View file

@ -8228,10 +8228,42 @@ class basic_json
struct strtonum struct strtonum
{ {
public: public:
strtonum(const char* start, const char* end) template<typename T>
struct maybe
{
T x;
bool valid;
maybe(const T& xx)
: x(xx), valid(true)
{}
maybe() : x(), valid(false)
{}
operator bool() const
{
return valid;
}
const T& operator*() const
{
return x;
}
};
strtonum(const char* start, const char* end)
: m_start(start), m_end(end) : m_start(start), m_end(end)
{} {}
template<typename T,
typename = typename std::enable_if<
std::is_arithmetic<T>::value>::type >
bool to(T& val) const
{
return parse(val, std::is_integral<T>());
}
template<typename T, template<typename T,
typename = typename std::enable_if< typename = typename std::enable_if<
std::is_arithmetic<T>::value>::type > std::is_arithmetic<T>::value>::type >
@ -8510,31 +8542,39 @@ class basic_json
const bool is_negative = *m_start == '-'; const bool is_negative = *m_start == '-';
try { result.m_type = value_t::discarded;
if (not num.is_integral())
{ if (not num.is_integral())
; {
} ; // will parse as float below
else if (is_negative) }
{ else if (is_negative)
{
number_integer_t val{0};
if(num.to(val)) {
result.m_type = value_t::number_integer; result.m_type = value_t::number_integer;
result.m_value = static_cast<number_integer_t>(num); result.m_value = val;
return;
}
else
{
result.m_type = value_t::number_unsigned;
result.m_value = static_cast<number_unsigned_t>(num);
return;
} }
} }
catch (std::invalid_argument&) else
{ {
; // overflow - will parse as double number_unsigned_t val{0};
if(num.to(val)) {
result.m_type = value_t::number_unsigned;
result.m_value = val;
}
}
number_float_t val{0};
if (result.m_type != value_t::discarded
or !num.to(val))
{
return; // already have a value from above
// or couldn't parse as float_t
} }
result.m_type = value_t::number_float; result.m_type = value_t::number_float;
result.m_value = static_cast<number_float_t>(num); result.m_value = val;
// replace infinity and NAN by null // replace infinity and NAN by null
if (not std::isfinite(result.m_value.number_float)) if (not std::isfinite(result.m_value.number_float))