🚧 overworked fix for #465
This commit is contained in:
parent
7d14f167b8
commit
967f9144d4
3 changed files with 43 additions and 33 deletions
10
doc/Makefile
10
doc/Makefile
|
@ -53,11 +53,11 @@ clean:
|
||||||
# create Doxygen documentation
|
# create Doxygen documentation
|
||||||
doxygen: create_output create_links
|
doxygen: create_output create_links
|
||||||
doxygen
|
doxygen
|
||||||
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
|
||||||
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g' html/*.html
|
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType JSONSerializer >@@g' html/*.html
|
||||||
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html
|
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
|
||||||
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html
|
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
|
||||||
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType >@@g' html/*.html
|
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType JSONSerializer >@@g' html/*.html
|
||||||
|
|
||||||
upload: clean doxygen check_output
|
upload: clean doxygen check_output
|
||||||
cd html ; ../scripts/git-update-ghpages nlohmann/json
|
cd html ; ../scripts/git-update-ghpages nlohmann/json
|
||||||
|
|
33
src/json.hpp
33
src/json.hpp
|
@ -8252,9 +8252,8 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t s_capacity = 30;
|
/// a (hopefully) large enough character buffer
|
||||||
/// added capacity for leading '-' and trailing '\0'
|
std::array < char, 64 > m_buf{{}};
|
||||||
std::array < char, s_capacity + 2 > m_buf{{}};
|
|
||||||
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
||||||
|
@ -8266,23 +8265,24 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(std::numeric_limits<NumberType>::digits10 <= s_capacity,
|
const bool is_negative = x < 0;
|
||||||
"unexpected NumberType");
|
|
||||||
|
|
||||||
const bool is_neg = x < 0;
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
while (x != 0 and i < s_capacity)
|
// spare 1 byte for '\0'
|
||||||
|
while (x != 0 and i < m_buf.size() - 1)
|
||||||
{
|
{
|
||||||
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);
|
||||||
x /= 10;
|
x /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(i < s_capacity);
|
// make sure the number has been processed completely
|
||||||
|
assert(x == 0);
|
||||||
|
|
||||||
if (is_neg)
|
if (is_negative)
|
||||||
{
|
{
|
||||||
|
// make sure there is capacity for the '-'
|
||||||
|
assert(i < m_buf.size() - 2);
|
||||||
m_buf[i++] = '-';
|
m_buf[i++] = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8306,11 +8306,16 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get number of digits for a text -> float -> text round-trip
|
||||||
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
||||||
static_assert(d == 6 or d == 15 or d == 16 or d == 17,
|
|
||||||
"unexpected NumberType");
|
|
||||||
|
|
||||||
snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
|
// the actual conversion
|
||||||
|
const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
|
||||||
|
|
||||||
|
// negative value indicates an error
|
||||||
|
assert(written_bytes > 0);
|
||||||
|
// check if buffer was large enough
|
||||||
|
assert(written_bytes < m_buf.size());
|
||||||
|
|
||||||
// read information from locale
|
// read information from locale
|
||||||
const auto loc = localeconv();
|
const auto loc = localeconv();
|
||||||
|
@ -8324,7 +8329,7 @@ class basic_json
|
||||||
// erase thousands separator
|
// erase thousands separator
|
||||||
if (thousands_sep != '\0')
|
if (thousands_sep != '\0')
|
||||||
{
|
{
|
||||||
const auto end = std::remove(m_buf.begin(), m_buf.end(), thousands_sep);
|
const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
|
||||||
std::fill(end, m_buf.end(), '\0');
|
std::fill(end, m_buf.end(), '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8252,9 +8252,8 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t s_capacity = 30;
|
/// a (hopefully) large enough character buffer
|
||||||
/// added capacity for leading '-' and trailing '\0'
|
std::array < char, 64 > m_buf{{}};
|
||||||
std::array < char, s_capacity + 2 > m_buf{{}};
|
|
||||||
|
|
||||||
template<typename NumberType>
|
template<typename NumberType>
|
||||||
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
void x_write(NumberType x, /*is_integral=*/std::true_type)
|
||||||
|
@ -8266,23 +8265,24 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(std::numeric_limits<NumberType>::digits10 <= s_capacity,
|
const bool is_negative = x < 0;
|
||||||
"unexpected NumberType");
|
|
||||||
|
|
||||||
const bool is_neg = x < 0;
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
while (x != 0 and i < s_capacity)
|
// spare 1 byte for '\0'
|
||||||
|
while (x != 0 and i < m_buf.size() - 1)
|
||||||
{
|
{
|
||||||
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);
|
||||||
x /= 10;
|
x /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(i < s_capacity);
|
// make sure the number has been processed completely
|
||||||
|
assert(x == 0);
|
||||||
|
|
||||||
if (is_neg)
|
if (is_negative)
|
||||||
{
|
{
|
||||||
|
// make sure there is capacity for the '-'
|
||||||
|
assert(i < m_buf.size() - 2);
|
||||||
m_buf[i++] = '-';
|
m_buf[i++] = '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8306,11 +8306,16 @@ class basic_json
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get number of digits for a text -> float -> text round-trip
|
||||||
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
static constexpr auto d = std::numeric_limits<NumberType>::digits10;
|
||||||
static_assert(d == 6 or d == 15 or d == 16 or d == 17,
|
|
||||||
"unexpected NumberType");
|
|
||||||
|
|
||||||
snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
|
// the actual conversion
|
||||||
|
const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
|
||||||
|
|
||||||
|
// negative value indicates an error
|
||||||
|
assert(written_bytes > 0);
|
||||||
|
// check if buffer was large enough
|
||||||
|
assert(written_bytes < m_buf.size());
|
||||||
|
|
||||||
// read information from locale
|
// read information from locale
|
||||||
const auto loc = localeconv();
|
const auto loc = localeconv();
|
||||||
|
@ -8324,7 +8329,7 @@ class basic_json
|
||||||
// erase thousands separator
|
// erase thousands separator
|
||||||
if (thousands_sep != '\0')
|
if (thousands_sep != '\0')
|
||||||
{
|
{
|
||||||
const auto end = std::remove(m_buf.begin(), m_buf.end(), thousands_sep);
|
const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
|
||||||
std::fill(end, m_buf.end(), '\0');
|
std::fill(end, m_buf.end(), '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue