Refactored to avoid using exceptions, as there are plans to support exceptionless mode
This commit is contained in:
parent
6774457733
commit
0a4a6a8399
2 changed files with 118 additions and 38 deletions
78
src/json.hpp
78
src/json.hpp
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue