🚧 clean up
This commit is contained in:
parent
6408402ad2
commit
513eb3ab5f
3 changed files with 62 additions and 86 deletions
71
src/json.hpp
71
src/json.hpp
|
@ -8226,15 +8226,10 @@ class basic_json
|
||||||
struct numtostr
|
struct numtostr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename NumberType>
|
||||||
numtostr(T value)
|
numtostr(NumberType value)
|
||||||
{
|
{
|
||||||
x_write(value, std::is_integral<T>());
|
x_write(value, std::is_integral<NumberType>());
|
||||||
}
|
|
||||||
|
|
||||||
operator const char* () const
|
|
||||||
{
|
|
||||||
return m_buf.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* c_str() const
|
const char* c_str() const
|
||||||
|
@ -8244,17 +8239,24 @@ class basic_json
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t s_capacity = 30;
|
static constexpr size_t s_capacity = 30;
|
||||||
std::array < char, s_capacity + 2 > m_buf{{}}; // +2 for leading '-'
|
/// added capacity for leading '-' and trailing '\0'
|
||||||
// and trailing '\0'
|
std::array < char, s_capacity + 2 > m_buf{{}};
|
||||||
template<typename T>
|
|
||||||
void x_write(T x, std::true_type)
|
template<typename NumberType>
|
||||||
|
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
||||||
{
|
{
|
||||||
static_assert(std::numeric_limits<T>::digits10 <= s_capacity, "");
|
if (x == 0)
|
||||||
|
{
|
||||||
|
m_buf[0] = '0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(std::numeric_limits<NumberType>::digits10 <= s_capacity, "");
|
||||||
|
|
||||||
const bool is_neg = x < 0;
|
const bool is_neg = x < 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
while (x and i < s_capacity)
|
while (x != 0 and i < s_capacity)
|
||||||
{
|
{
|
||||||
const auto digit = std::labs(static_cast<long>(x % 10));
|
const auto digit = std::labs(static_cast<long>(x % 10));
|
||||||
m_buf[i++] = static_cast<char>('0' + digit);
|
m_buf[i++] = static_cast<char>('0' + digit);
|
||||||
|
@ -8263,11 +8265,6 @@ class basic_json
|
||||||
|
|
||||||
assert(i < s_capacity);
|
assert(i < s_capacity);
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
m_buf[i++] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_neg)
|
if (is_neg)
|
||||||
{
|
{
|
||||||
m_buf[i++] = '-';
|
m_buf[i++] = '-';
|
||||||
|
@ -8276,18 +8273,16 @@ class basic_json
|
||||||
std::reverse(m_buf.begin(), m_buf.begin() + i);
|
std::reverse(m_buf.begin(), m_buf.begin() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename NumberType>
|
||||||
void x_write(T x, std::false_type)
|
void x_write(NumberType x, /*is_integral=*/std::false_type)
|
||||||
{
|
{
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
std::strcpy(m_buf.data(),
|
std::strcpy(m_buf.data(), std::signbit(x) ? "-0.0" : "0.0");
|
||||||
std::signbit(x) ? "-0.0" : "0.0");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto d =
|
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
||||||
std::numeric_limits<number_float_t>::digits10;
|
|
||||||
static_assert(d == 6 or d == 15 or d == 16 or d == 17, "");
|
static_assert(d == 6 or d == 15 or d == 16 or d == 17, "");
|
||||||
|
|
||||||
static constexpr auto fmt = d == 6 ? "%.7g"
|
static constexpr auto fmt = d == 6 ? "%.7g"
|
||||||
|
@ -8330,17 +8325,14 @@ class basic_json
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// erase thousands separator
|
// erase thousands separator
|
||||||
if (thousands_sep)
|
if (thousands_sep != '\0')
|
||||||
{
|
{
|
||||||
auto end = std::remove(m_buf.begin(),
|
const auto end = std::remove(m_buf.begin(), m_buf.end(), thousands_sep);
|
||||||
m_buf.end(),
|
|
||||||
thousands_sep);
|
|
||||||
|
|
||||||
std::fill(end, m_buf.end(), '\0');
|
std::fill(end, m_buf.end(), '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert decimal point to '.'
|
// convert decimal point to '.'
|
||||||
if (decimal_point and decimal_point != '.')
|
if (decimal_point != '\0' and decimal_point != '.')
|
||||||
{
|
{
|
||||||
for (auto& c : m_buf)
|
for (auto& c : m_buf)
|
||||||
{
|
{
|
||||||
|
@ -8352,20 +8344,16 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine if need to apperd ".0"
|
// determine if need to append ".0"
|
||||||
auto data_end = m_buf.begin() + strlen(m_buf.data());
|
const auto data_end = m_buf.begin() + strlen(m_buf.data());
|
||||||
|
|
||||||
const bool value_is_int_like =
|
const bool value_is_int_like =
|
||||||
std::find_if(m_buf.begin(), data_end,
|
std::none_of(m_buf.begin(), data_end, [](const char c)
|
||||||
[](const char c)
|
|
||||||
{
|
{
|
||||||
return c == '.'
|
return (c == '.' or c == 'e' or c == 'E');
|
||||||
or c == 'e'
|
});
|
||||||
or c == 'E';
|
|
||||||
})
|
|
||||||
== data_end;
|
|
||||||
|
|
||||||
assert(data_end + 2 < m_buf.end());
|
assert(data_end + 2 < m_buf.end());
|
||||||
|
|
||||||
if (value_is_int_like)
|
if (value_is_int_like)
|
||||||
{
|
{
|
||||||
strcat(m_buf.data(), ".0");
|
strcat(m_buf.data(), ".0");
|
||||||
|
@ -8374,7 +8362,6 @@ class basic_json
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief internal implementation of the serialization function
|
@brief internal implementation of the serialization function
|
||||||
|
|
||||||
|
|
|
@ -8226,15 +8226,10 @@ class basic_json
|
||||||
struct numtostr
|
struct numtostr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename NumberType>
|
||||||
numtostr(T value)
|
numtostr(NumberType value)
|
||||||
{
|
{
|
||||||
x_write(value, std::is_integral<T>());
|
x_write(value, std::is_integral<NumberType>());
|
||||||
}
|
|
||||||
|
|
||||||
operator const char* () const
|
|
||||||
{
|
|
||||||
return m_buf.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* c_str() const
|
const char* c_str() const
|
||||||
|
@ -8244,17 +8239,25 @@ class basic_json
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t s_capacity = 30;
|
static constexpr size_t s_capacity = 30;
|
||||||
std::array < char, s_capacity + 2 > m_buf{{}}; // +2 for leading '-'
|
/// added capacity for leading '-' and trailing '\0'
|
||||||
// and trailing '\0'
|
std::array < char, s_capacity + 2 > m_buf{{}};
|
||||||
template<typename T>
|
|
||||||
void x_write(T x, std::true_type)
|
template<typename NumberType>
|
||||||
|
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
||||||
{
|
{
|
||||||
static_assert(std::numeric_limits<T>::digits10 <= s_capacity, "");
|
if (x == 0)
|
||||||
|
{
|
||||||
|
m_buf[0] = '0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(std::numeric_limits<NumberType>::digits10 <= s_capacity,
|
||||||
|
"unexpected NumberType");
|
||||||
|
|
||||||
const bool is_neg = x < 0;
|
const bool is_neg = x < 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
while (x and i < s_capacity)
|
while (x != 0 and i < s_capacity)
|
||||||
{
|
{
|
||||||
const auto digit = std::labs(static_cast<long>(x % 10));
|
const auto digit = std::labs(static_cast<long>(x % 10));
|
||||||
m_buf[i++] = static_cast<char>('0' + digit);
|
m_buf[i++] = static_cast<char>('0' + digit);
|
||||||
|
@ -8263,11 +8266,6 @@ class basic_json
|
||||||
|
|
||||||
assert(i < s_capacity);
|
assert(i < s_capacity);
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
m_buf[i++] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_neg)
|
if (is_neg)
|
||||||
{
|
{
|
||||||
m_buf[i++] = '-';
|
m_buf[i++] = '-';
|
||||||
|
@ -8276,19 +8274,18 @@ class basic_json
|
||||||
std::reverse(m_buf.begin(), m_buf.begin() + i);
|
std::reverse(m_buf.begin(), m_buf.begin() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename NumberType>
|
||||||
void x_write(T x, std::false_type)
|
void x_write(NumberType x, /*is_integral=*/std::false_type)
|
||||||
{
|
{
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
std::strcpy(m_buf.data(),
|
std::strcpy(m_buf.data(), std::signbit(x) ? "-0.0" : "0.0");
|
||||||
std::signbit(x) ? "-0.0" : "0.0");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto d =
|
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
||||||
std::numeric_limits<number_float_t>::digits10;
|
static_assert(d == 6 or d == 15 or d == 16 or d == 17,
|
||||||
static_assert(d == 6 or d == 15 or d == 16 or d == 17, "");
|
"unexpected NumberType");
|
||||||
|
|
||||||
static constexpr auto fmt = d == 6 ? "%.7g"
|
static constexpr auto fmt = d == 6 ? "%.7g"
|
||||||
: d == 15 ? "%.16g"
|
: d == 15 ? "%.16g"
|
||||||
|
@ -8330,17 +8327,14 @@ class basic_json
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// erase thousands separator
|
// erase thousands separator
|
||||||
if (thousands_sep)
|
if (thousands_sep != '\0')
|
||||||
{
|
{
|
||||||
auto end = std::remove(m_buf.begin(),
|
const auto end = std::remove(m_buf.begin(), m_buf.end(), thousands_sep);
|
||||||
m_buf.end(),
|
|
||||||
thousands_sep);
|
|
||||||
|
|
||||||
std::fill(end, m_buf.end(), '\0');
|
std::fill(end, m_buf.end(), '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert decimal point to '.'
|
// convert decimal point to '.'
|
||||||
if (decimal_point and decimal_point != '.')
|
if (decimal_point != '\0' and decimal_point != '.')
|
||||||
{
|
{
|
||||||
for (auto& c : m_buf)
|
for (auto& c : m_buf)
|
||||||
{
|
{
|
||||||
|
@ -8352,20 +8346,16 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine if need to apperd ".0"
|
// determine if need to append ".0"
|
||||||
auto data_end = m_buf.begin() + strlen(m_buf.data());
|
const auto data_end = m_buf.begin() + strlen(m_buf.data());
|
||||||
|
|
||||||
const bool value_is_int_like =
|
const bool value_is_int_like =
|
||||||
std::find_if(m_buf.begin(), data_end,
|
std::none_of(m_buf.begin(), data_end, [](const char c)
|
||||||
[](const char c)
|
|
||||||
{
|
{
|
||||||
return c == '.'
|
return (c == '.' or c == 'e' or c == 'E');
|
||||||
or c == 'e'
|
});
|
||||||
or c == 'E';
|
|
||||||
})
|
|
||||||
== data_end;
|
|
||||||
|
|
||||||
assert(data_end + 2 < m_buf.end());
|
assert(data_end + 2 < m_buf.end());
|
||||||
|
|
||||||
if (value_is_int_like)
|
if (value_is_int_like)
|
||||||
{
|
{
|
||||||
strcat(m_buf.data(), ".0");
|
strcat(m_buf.data(), ".0");
|
||||||
|
@ -8374,7 +8364,6 @@ class basic_json
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief internal implementation of the serialization function
|
@brief internal implementation of the serialization function
|
||||||
|
|
||||||
|
|
|
@ -613,7 +613,7 @@ TEST_CASE("parser class")
|
||||||
|
|
||||||
// test case to make sure the callback is properly evaluated after reading a key
|
// test case to make sure the callback is properly evaluated after reading a key
|
||||||
{
|
{
|
||||||
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
|
json::parser_callback_t cb = [](int, json::parse_event_t event, json&)
|
||||||
{
|
{
|
||||||
if (event == json::parse_event_t::key)
|
if (event == json::parse_event_t::key)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue