diff --git a/src/json.hpp b/src/json.hpp index 143ae0b8..2d98db8c 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -10840,13 +10840,13 @@ basic_json_parser_66: /*! - @brief parse string into a built-in arithmetic type as if - the current locale is POSIX. + @brief parse string into a built-in arithmetic type as if the current + locale is POSIX. - note: in floating-point case strtod may parse - past the token's end - this is not an error. + @note in floating-point case strtod may parse past the token's end - + this is not an error - any leading blanks are not handled. + @note any leading blanks are not handled */ struct strtonum { @@ -10855,36 +10855,37 @@ basic_json_parser_66: : m_start(start), m_end(end) {} - /// return true iff parsed successfully as - /// number of type T. - /// - /// @val shall contain parsed value, or - /// undefined value if could not parse. - template::value>::type > + /*! + @return true iff parsed successfully as number of type T + + @param[in,out] val shall contain parsed value, or undefined value + if could not parse + */ + template::value>::type> bool to(T& val) const { return parse(val, std::is_integral()); } - /// return true iff token matches ^[+-]\d+$ - /// - /// this is a helper to determine whether to - /// parse the token into floating-point or - /// integral type. We wouldn't need it if - /// we had separate token types for integral - /// and floating-point cases. + /*! + This is a helper to determine whether to parse the token into + floating-point or integral type. + + @note We wouldn't need it if we had separate token types for + integral and floating-point cases. + + @return true iff token matches `^[+-]\d+$` + */ bool is_integral() const { const char* p = m_start; - if (!p) + if (p == nullptr) { return false; // LCOV_EXCL_LINE } - if (*p == '-' or * p == '+') + if ((*p == '-') or (*p == '+')) { ++p; } @@ -10894,39 +10895,31 @@ basic_json_parser_66: return false; // LCOV_EXCL_LINE } - while (p < m_end and* p >= '0' - and * p <= '9') + while ((p < m_end) and (*p >= '0') and (*p <= '9')) { ++p; } - return p == m_end; + return (p == m_end); } private: const char* const m_start = nullptr; - const char* const m_end = nullptr; + const char* const m_end = nullptr; // overloaded wrappers for strtod/strtof/strtold // that will be called from parse - - static void strtof(float& f, - const char* str, - char** endptr) + static void strtof(float& f, const char* str, char** endptr) { f = std::strtof(str, endptr); } - static void strtof(double& f, - const char* str, - char** endptr) + static void strtof(double& f, const char* str, char** endptr) { f = std::strtod(str, endptr); } - static void strtof(long double& f, - const char* str, - char** endptr) + static void strtof(long double& f, const char* str, char** endptr) { f = std::strtold(str, endptr); } @@ -10934,37 +10927,32 @@ basic_json_parser_66: template bool parse(T& value, /*is_integral=*/std::false_type) const { - // replace decimal separator with locale-specific - // version, when necessary; data will point to - // either the original string, or buf, or tempstr - // containing the fixed string. + // replace decimal separator with locale-specific version, + // when necessary; data will point to either the original + // string, or buf, or tempstr containing the fixed string. std::string tempstr; std::array buf; const size_t len = static_cast(m_end - m_start); - // Since dealing with strtod family of functions, - // we're getting the decimal point char from the - // C locale facilities instead of C++'s numpunct - // facet of the current std::locale; + // since dealing with strtod family of functions, we're + // getting the decimal point char from the C locale facilities + // instead of C++'s numpunct facet of the current std::locale const auto loc = localeconv(); assert(loc != nullptr); - const char decimal_point_char = !loc->decimal_point ? '.' - : loc->decimal_point[0]; + const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0]; const char* data = m_start; if (decimal_point_char != '.') { - const size_t ds_pos = static_cast( - std::find(m_start, m_end, '.') - m_start ); + const size_t ds_pos = static_cast(std::find(m_start, m_end, '.') - m_start); if (ds_pos != len) { - // copy the data into the local buffer or - // tempstr, if buffer is too small; - // replace decimal separator, and update - // data to point to the modified bytes - if (len + 1 < buf.size()) + // copy the data into the local buffer or tempstr, if + // buffer is too small; replace decimal separator, and + // update data to point to the modified bytes + if ((len + 1) < buf.size()) { std::copy(m_start, m_end, buf.data()); buf[len] = 0; @@ -10985,13 +10973,12 @@ basic_json_parser_66: // this calls appropriate overload depending on T strtof(value, data, &endptr); - // note that reading past the end is OK, the data may be, - // for example, "123.", where the parsed token only - // contains "123", but strtod will read the dot as well. - const bool ok = endptr >= data + len - and len > 0; + // note that reading past the end is OK, the data may be, for + // example, "123.", where the parsed token only contains + // "123", but strtod will read the dot as well. + const bool ok = (endptr >= (data + len)) and (len > 0); - if (ok and value == 0.0 and * data == '-') + if (ok and (value == 0.0) and (*data == '-')) { // some implementations forget to negate the zero value = -0.0; @@ -11000,16 +10987,12 @@ basic_json_parser_66: return ok; } - signed long long parse_integral( - char** endptr, - /*is_signed*/std::true_type) const + signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const { return std::strtoll(m_start, endptr, 10); } - unsigned long long parse_integral( - char** endptr, - /*is_signed*/std::false_type) const + unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const { return std::strtoull(m_start, endptr, 10); } @@ -11018,20 +11001,20 @@ basic_json_parser_66: bool parse(T& value, /*is_integral=*/std::true_type) const { char* endptr = nullptr; - errno = 0; // these are thread-local + errno = 0; // these are thread-local const auto x = parse_integral(&endptr, std::is_signed()); - static_assert(std::is_signed() // called right overload? - == std::is_signed(), ""); + // called right overload? + static_assert(std::is_signed() == std::is_signed(), ""); value = static_cast(x); - return x == static_cast(value) // x fits into destination T - and (x < 0) == (value < 0) // preserved sign - and (x != 0 or is_integral()) // strto[u]ll did nto fail - and errno == 0 // strto[u]ll did not overflow - and m_start < m_end // token was not empty - and endptr == m_end; // parsed entire token exactly + return (x == static_cast(value)) // x fits into destination T + and (x < 0) == (value < 0) // preserved sign + and ((x != 0) or is_integral()) // strto[u]ll did nto fail + and (errno == 0) // strto[u]ll did not overflow + and (m_start < m_end) // token was not empty + and (endptr == m_end); // parsed entire token exactly } }; @@ -11061,20 +11044,20 @@ basic_json_parser_66: strtonum num(reinterpret_cast(m_start), reinterpret_cast(m_cursor)); - const bool is_negative = *m_start == '-'; + const bool is_negative = (*m_start == '-'); result.m_type = value_t::discarded; if (not num.is_integral()) { - ; // will parse as float below + // will parse as float below } 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 = val; } } @@ -11089,14 +11072,13 @@ basic_json_parser_66: } number_float_t val{0}; - if (result.m_type != value_t::discarded - or !num.to(val)) + if (result.m_type != value_t::discarded or (not num.to(val))) { - return; // already have a value from above - // or couldn't parse as float_t + // already have a value from above or couldn't parse as float_t + return; } - result.m_type = value_t::number_float; + result.m_type = value_t::number_float; result.m_value = val; // replace infinity and NAN by null diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 698fbb3b..b3f7af8d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -9990,13 +9990,13 @@ class basic_json /*! - @brief parse string into a built-in arithmetic type as if - the current locale is POSIX. + @brief parse string into a built-in arithmetic type as if the current + locale is POSIX. - note: in floating-point case strtod may parse - past the token's end - this is not an error. + @note in floating-point case strtod may parse past the token's end - + this is not an error - any leading blanks are not handled. + @note any leading blanks are not handled */ struct strtonum { @@ -10005,36 +10005,37 @@ class basic_json : m_start(start), m_end(end) {} - /// return true iff parsed successfully as - /// number of type T. - /// - /// @val shall contain parsed value, or - /// undefined value if could not parse. - template::value>::type > + /*! + @return true iff parsed successfully as number of type T + + @param[in,out] val shall contain parsed value, or undefined value + if could not parse + */ + template::value>::type> bool to(T& val) const { return parse(val, std::is_integral()); } - /// return true iff token matches ^[+-]\d+$ - /// - /// this is a helper to determine whether to - /// parse the token into floating-point or - /// integral type. We wouldn't need it if - /// we had separate token types for integral - /// and floating-point cases. + /*! + This is a helper to determine whether to parse the token into + floating-point or integral type. + + @note We wouldn't need it if we had separate token types for + integral and floating-point cases. + + @return true iff token matches `^[+-]\d+$` + */ bool is_integral() const { const char* p = m_start; - if (!p) + if (p == nullptr) { return false; // LCOV_EXCL_LINE } - if (*p == '-' or * p == '+') + if ((*p == '-') or (*p == '+')) { ++p; } @@ -10044,39 +10045,31 @@ class basic_json return false; // LCOV_EXCL_LINE } - while (p < m_end and* p >= '0' - and * p <= '9') + while ((p < m_end) and (*p >= '0') and (*p <= '9')) { ++p; } - return p == m_end; + return (p == m_end); } private: const char* const m_start = nullptr; - const char* const m_end = nullptr; + const char* const m_end = nullptr; // overloaded wrappers for strtod/strtof/strtold // that will be called from parse - - static void strtof(float& f, - const char* str, - char** endptr) + static void strtof(float& f, const char* str, char** endptr) { f = std::strtof(str, endptr); } - static void strtof(double& f, - const char* str, - char** endptr) + static void strtof(double& f, const char* str, char** endptr) { f = std::strtod(str, endptr); } - static void strtof(long double& f, - const char* str, - char** endptr) + static void strtof(long double& f, const char* str, char** endptr) { f = std::strtold(str, endptr); } @@ -10084,37 +10077,32 @@ class basic_json template bool parse(T& value, /*is_integral=*/std::false_type) const { - // replace decimal separator with locale-specific - // version, when necessary; data will point to - // either the original string, or buf, or tempstr - // containing the fixed string. + // replace decimal separator with locale-specific version, + // when necessary; data will point to either the original + // string, or buf, or tempstr containing the fixed string. std::string tempstr; std::array buf; const size_t len = static_cast(m_end - m_start); - // Since dealing with strtod family of functions, - // we're getting the decimal point char from the - // C locale facilities instead of C++'s numpunct - // facet of the current std::locale; + // since dealing with strtod family of functions, we're + // getting the decimal point char from the C locale facilities + // instead of C++'s numpunct facet of the current std::locale const auto loc = localeconv(); assert(loc != nullptr); - const char decimal_point_char = !loc->decimal_point ? '.' - : loc->decimal_point[0]; + const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0]; const char* data = m_start; if (decimal_point_char != '.') { - const size_t ds_pos = static_cast( - std::find(m_start, m_end, '.') - m_start ); + const size_t ds_pos = static_cast(std::find(m_start, m_end, '.') - m_start); if (ds_pos != len) { - // copy the data into the local buffer or - // tempstr, if buffer is too small; - // replace decimal separator, and update - // data to point to the modified bytes - if (len + 1 < buf.size()) + // copy the data into the local buffer or tempstr, if + // buffer is too small; replace decimal separator, and + // update data to point to the modified bytes + if ((len + 1) < buf.size()) { std::copy(m_start, m_end, buf.data()); buf[len] = 0; @@ -10135,13 +10123,12 @@ class basic_json // this calls appropriate overload depending on T strtof(value, data, &endptr); - // note that reading past the end is OK, the data may be, - // for example, "123.", where the parsed token only - // contains "123", but strtod will read the dot as well. - const bool ok = endptr >= data + len - and len > 0; + // note that reading past the end is OK, the data may be, for + // example, "123.", where the parsed token only contains + // "123", but strtod will read the dot as well. + const bool ok = (endptr >= (data + len)) and (len > 0); - if (ok and value == 0.0 and * data == '-') + if (ok and (value == 0.0) and (*data == '-')) { // some implementations forget to negate the zero value = -0.0; @@ -10150,16 +10137,12 @@ class basic_json return ok; } - signed long long parse_integral( - char** endptr, - /*is_signed*/std::true_type) const + signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const { return std::strtoll(m_start, endptr, 10); } - unsigned long long parse_integral( - char** endptr, - /*is_signed*/std::false_type) const + unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const { return std::strtoull(m_start, endptr, 10); } @@ -10168,20 +10151,20 @@ class basic_json bool parse(T& value, /*is_integral=*/std::true_type) const { char* endptr = nullptr; - errno = 0; // these are thread-local + errno = 0; // these are thread-local const auto x = parse_integral(&endptr, std::is_signed()); - static_assert(std::is_signed() // called right overload? - == std::is_signed(), ""); + // called right overload? + static_assert(std::is_signed() == std::is_signed(), ""); value = static_cast(x); - return x == static_cast(value) // x fits into destination T - and (x < 0) == (value < 0) // preserved sign - and (x != 0 or is_integral()) // strto[u]ll did nto fail - and errno == 0 // strto[u]ll did not overflow - and m_start < m_end // token was not empty - and endptr == m_end; // parsed entire token exactly + return (x == static_cast(value)) // x fits into destination T + and (x < 0) == (value < 0) // preserved sign + and ((x != 0) or is_integral()) // strto[u]ll did nto fail + and (errno == 0) // strto[u]ll did not overflow + and (m_start < m_end) // token was not empty + and (endptr == m_end); // parsed entire token exactly } }; @@ -10211,20 +10194,20 @@ class basic_json strtonum num(reinterpret_cast(m_start), reinterpret_cast(m_cursor)); - const bool is_negative = *m_start == '-'; + const bool is_negative = (*m_start == '-'); result.m_type = value_t::discarded; if (not num.is_integral()) { - ; // will parse as float below + // will parse as float below } 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 = val; } } @@ -10239,14 +10222,13 @@ class basic_json } number_float_t val{0}; - if (result.m_type != value_t::discarded - or !num.to(val)) + if (result.m_type != value_t::discarded or (not num.to(val))) { - return; // already have a value from above - // or couldn't parse as float_t + // already have a value from above or couldn't parse as float_t + return; } - result.m_type = value_t::number_float; + result.m_type = value_t::number_float; result.m_value = val; // replace infinity and NAN by null