continuing work on our own strtold - reduced to 3 failing assertions
this changes a few things. the name of the function to better represent what it does (string to json number) - we aren't strtoul compliant so best not to lie about that. we remove template code and just use one function. this makes it a bit simpler and we can always add it back if it buys us anything. the penalty for casting down from long double seems to be inconsequential.
This commit is contained in:
parent
973ee97a93
commit
7dcc8a56bb
37
src/json.hpp
37
src/json.hpp
@ -8810,24 +8810,15 @@ basic_json_parser_63:
|
|||||||
/*!
|
/*!
|
||||||
@brief parse string to floating point number
|
@brief parse string to floating point number
|
||||||
|
|
||||||
This function is a reimplementation of the strtold family without
|
This function is a partial reimplementation of the strtold in order to meet needs of JSON number
|
||||||
regard to locale
|
|
||||||
|
|
||||||
@tparam T a is_floating_point type
|
|
||||||
|
|
||||||
@param[in] str the string we will parse
|
@param[in] str the string we will parse
|
||||||
|
|
||||||
@return the floating point number
|
@return the floating point number
|
||||||
*/
|
*/
|
||||||
template <typename T, typename = typename std::enable_if<
|
long double strtojnum(const char *str) const
|
||||||
std::is_floating_point<T>::value>::type>
|
|
||||||
T strtox(const char *str) const
|
|
||||||
{
|
{
|
||||||
constexpr std::array<long double, 9> powerof10 {
|
long double result = 0;
|
||||||
{1.e1L, 1.e2L, 1.e4L, 1.e8L, 1.e16L, 1.e32L, 1.e64L, 1.e128L, 1.e256L}
|
|
||||||
};
|
|
||||||
|
|
||||||
T result = 0;
|
|
||||||
char cp = *str;
|
char cp = *str;
|
||||||
int exp = 0; // exponent
|
int exp = 0; // exponent
|
||||||
{
|
{
|
||||||
@ -8909,22 +8900,26 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// adjust number by powers of ten specified by format and exponent.
|
// adjust number by powers of ten specified by format and exponent.
|
||||||
if (result != 0.0)
|
if (result != 0.0L)
|
||||||
{
|
{
|
||||||
if (exp > std::numeric_limits<T>::max_exponent10)
|
constexpr std::array<long double, 9> powerof10 = {
|
||||||
|
{1.e1L, 1.e2L, 1.e4L, 1.e8L, 1.e16L, 1.e32L, 1.e64L, 1.e128L, 1.e256L}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (exp > std::numeric_limits<long double>::max_exponent10)
|
||||||
{
|
{
|
||||||
constexpr T inf = std::numeric_limits<T>::infinity();
|
constexpr long double inf = std::numeric_limits<long double>::infinity();
|
||||||
result = (result < 0) ? -inf : inf;
|
result = (result < 0) ? -inf : inf;
|
||||||
}
|
}
|
||||||
else if (exp < std::numeric_limits<T>::min_exponent10)
|
else if (exp < std::numeric_limits<long double>::min_exponent10)
|
||||||
{
|
{
|
||||||
result = 0.0;
|
result = 0.0L;
|
||||||
}
|
}
|
||||||
else if (exp < 0)
|
else if (exp < 0)
|
||||||
{
|
{
|
||||||
exp = -exp;
|
exp = -exp;
|
||||||
|
|
||||||
for (std::size_t count = 0; exp; count++, exp >>= 1)
|
for (std::size_t count = 0; exp; ++count, exp >>= 1)
|
||||||
{
|
{
|
||||||
if (exp & 1)
|
if (exp & 1)
|
||||||
{
|
{
|
||||||
@ -8934,7 +8929,7 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (std::size_t count = 0; exp; count++, exp >>= 1)
|
for (std::size_t count = 0; exp; ++count, exp >>= 1)
|
||||||
{
|
{
|
||||||
if (exp & 1)
|
if (exp & 1)
|
||||||
{
|
{
|
||||||
@ -9045,8 +9040,8 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// parse with strtod
|
// convert string by json number format to floating point
|
||||||
result.m_value.number_float = strtox<number_float_t>(reinterpret_cast<typename string_t::const_pointer>(m_start));
|
result.m_value.number_float = strtojnum(reinterpret_cast<typename string_t::const_pointer>(m_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the type
|
// save the type
|
||||||
|
|||||||
@ -8107,24 +8107,15 @@ class basic_json
|
|||||||
/*!
|
/*!
|
||||||
@brief parse string to floating point number
|
@brief parse string to floating point number
|
||||||
|
|
||||||
This function is a reimplementation of the strtold family without
|
This function is a partial reimplementation of the strtold in order to meet needs of JSON number
|
||||||
regard to locale
|
|
||||||
|
|
||||||
@tparam T a is_floating_point type
|
|
||||||
|
|
||||||
@param[in] str the string we will parse
|
@param[in] str the string we will parse
|
||||||
|
|
||||||
@return the floating point number
|
@return the floating point number
|
||||||
*/
|
*/
|
||||||
template <typename T, typename = typename std::enable_if<
|
long double strtojnum(const char *str) const
|
||||||
std::is_floating_point<T>::value>::type>
|
|
||||||
T strtox(const char *st) const
|
|
||||||
{
|
{
|
||||||
constexpr std::array<long double, 9> powerof10 {
|
long double result = 0;
|
||||||
{1.e1L, 1.e2L, 1.e4L, 1.e8L, 1.e16L, 1.e32L, 1.e64L, 1.e128L, 1.e256L}
|
|
||||||
};
|
|
||||||
|
|
||||||
T result = 0;
|
|
||||||
char cp = *str;
|
char cp = *str;
|
||||||
int exp = 0; // exponent
|
int exp = 0; // exponent
|
||||||
{
|
{
|
||||||
@ -8206,22 +8197,26 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// adjust number by powers of ten specified by format and exponent.
|
// adjust number by powers of ten specified by format and exponent.
|
||||||
if (result != 0.0)
|
if (result != 0.0L)
|
||||||
{
|
{
|
||||||
if (exp > std::numeric_limits<T>::max_exponent10)
|
constexpr std::array<long double, 9> powerof10 = {
|
||||||
|
{1.e1L, 1.e2L, 1.e4L, 1.e8L, 1.e16L, 1.e32L, 1.e64L, 1.e128L, 1.e256L}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (exp > std::numeric_limits<long double>::max_exponent10)
|
||||||
{
|
{
|
||||||
constexpr T inf = std::numeric_limits<T>::infinity();
|
constexpr long double inf = std::numeric_limits<long double>::infinity();
|
||||||
result = (result < 0) ? -inf : inf;
|
result = (result < 0) ? -inf : inf;
|
||||||
}
|
}
|
||||||
else if (exp < std::numeric_limits<T>::min_exponent10)
|
else if (exp < std::numeric_limits<long double>::min_exponent10)
|
||||||
{
|
{
|
||||||
result = 0.0;
|
result = 0.0L;
|
||||||
}
|
}
|
||||||
else if (exp < 0)
|
else if (exp < 0)
|
||||||
{
|
{
|
||||||
exp = -exp;
|
exp = -exp;
|
||||||
|
|
||||||
for (std::size_t count = 0; exp; count++, exp >>= 1)
|
for (std::size_t count = 0; exp; ++count, exp >>= 1)
|
||||||
{
|
{
|
||||||
if (exp & 1)
|
if (exp & 1)
|
||||||
{
|
{
|
||||||
@ -8231,7 +8226,7 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (std::size_t count = 0; exp; count++, exp >>= 1)
|
for (std::size_t count = 0; exp; ++count, exp >>= 1)
|
||||||
{
|
{
|
||||||
if (exp & 1)
|
if (exp & 1)
|
||||||
{
|
{
|
||||||
@ -8342,8 +8337,8 @@ skip_loop:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// parse with strtod
|
// convert string by json number format to floating point
|
||||||
result.m_value.number_float = strtox<number_float_t>(reinterpret_cast<typename string_t::const_pointer>(m_start));
|
result.m_value.number_float = strtojnum(reinterpret_cast<typename string_t::const_pointer>(m_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the type
|
// save the type
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user