mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 21:13:51 +07:00
Address the clang-tidy findings of values and JSON pointers
get_string() and number_token() return braced lists; the test compares floats by their bit patterns instead of with memcmp, uses std::any_of, and marks a fixed seed, a default member initializer (needed by GCC's -Weffc++), and a string search. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -532,7 +532,7 @@ class basic_json_view
|
|||||||
{
|
{
|
||||||
detail::view::throw_type_error(302, "type must be string, but is ", type_name());
|
detail::view::throw_type_error(302, "type must be string, but is ", type_name());
|
||||||
}
|
}
|
||||||
return string_view_t(m_doc->str(*m_node), m_node->len);
|
return {m_doc->str(*m_node), m_node->len};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the text of a number as it appears in the source (e.g. "1.50", "1E2",
|
/// the text of a number as it appears in the source (e.g. "1.50", "1E2",
|
||||||
@@ -544,7 +544,7 @@ class basic_json_view
|
|||||||
{
|
{
|
||||||
detail::view::throw_type_error(302, "type must be number, but is ", type_name());
|
detail::view::throw_type_error(302, "type must be number, but is ", type_name());
|
||||||
}
|
}
|
||||||
return string_view_t(m_doc->str(*m_node), detail::view::number_length(*m_node));
|
return {m_doc->str(*m_node), detail::view::number_length(*m_node)};
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|||||||
@@ -3262,7 +3262,7 @@ class basic_json_view
|
|||||||
{
|
{
|
||||||
detail::view::throw_type_error(302, "type must be string, but is ", type_name());
|
detail::view::throw_type_error(302, "type must be string, but is ", type_name());
|
||||||
}
|
}
|
||||||
return string_view_t(m_doc->str(*m_node), m_node->len);
|
return {m_doc->str(*m_node), m_node->len};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the text of a number as it appears in the source (e.g. "1.50", "1E2",
|
/// the text of a number as it appears in the source (e.g. "1.50", "1E2",
|
||||||
@@ -3274,7 +3274,7 @@ class basic_json_view
|
|||||||
{
|
{
|
||||||
detail::view::throw_type_error(302, "type must be number, but is ", type_name());
|
detail::view::throw_type_error(302, "type must be number, but is ", type_name());
|
||||||
}
|
}
|
||||||
return string_view_t(m_doc->str(*m_node), detail::view::number_length(*m_node));
|
return {m_doc->str(*m_node), detail::view::number_length(*m_node)};
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|||||||
@@ -676,20 +676,31 @@ std::string without_path(std::string msg)
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the bits of a float, to compare values bit for bit
|
||||||
|
std::uint64_t bits(double x)
|
||||||
|
{
|
||||||
|
std::uint64_t r = 0;
|
||||||
|
std::memcpy(&r, &x, sizeof(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t bits(float x)
|
||||||
|
{
|
||||||
|
std::uint32_t r = 0;
|
||||||
|
std::memcpy(&r, &x, sizeof(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
bool has_duplicate_keys(const ordered_json_view& v)
|
bool has_duplicate_keys(const ordered_json_view& v)
|
||||||
{
|
{
|
||||||
if (v.is_object() && v.size() != v.materialize().size())
|
if (v.is_object() && v.size() != v.materialize().size())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (const ordered_json_view e : v)
|
return std::any_of(v.begin(), v.end(), [](const ordered_json_view e)
|
||||||
{
|
{
|
||||||
if (e.is_structured() && has_duplicate_keys(e))
|
return e.is_structured() && has_duplicate_keys(e);
|
||||||
{
|
});
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compares the conversions of a view with those of ordered_json
|
// compares the conversions of a view with those of ordered_json
|
||||||
@@ -711,10 +722,8 @@ void check_values(const ordered_json_view& v, const ordered_json& j, const std::
|
|||||||
{
|
{
|
||||||
CHECK(v.get<std::int64_t>() == j.get<std::int64_t>());
|
CHECK(v.get<std::int64_t>() == j.get<std::int64_t>());
|
||||||
}
|
}
|
||||||
const double a = v.get<double>();
|
CHECK(bits(v.get<double>()) == bits(j.get<double>()));
|
||||||
const double b = j.get<double>();
|
if (std::abs(j.get<double>()) < 1e9)
|
||||||
CHECK(std::memcmp(&a, &b, sizeof(double)) == 0);
|
|
||||||
if (std::abs(b) < 1e9)
|
|
||||||
{
|
{
|
||||||
CHECK(v.get<int>() == j.get<int>());
|
CHECK(v.get<int>() == j.get<int>());
|
||||||
}
|
}
|
||||||
@@ -785,7 +794,7 @@ void check_values(const ordered_json_view& v, const ordered_json& j, const std::
|
|||||||
|
|
||||||
struct record
|
struct record
|
||||||
{
|
{
|
||||||
std::string name{};
|
std::string name{}; // NOLINT(readability-redundant-member-init)
|
||||||
int count = 0;
|
int count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -813,7 +822,7 @@ TEST_CASE("json_view values")
|
|||||||
|
|
||||||
SECTION("floats are converted as parse() converts them")
|
SECTION("floats are converted as parse() converts them")
|
||||||
{
|
{
|
||||||
std::mt19937_64 rng(5295);
|
std::mt19937_64 rng(5295); // NOLINT(cert-msc32-c,cert-msc51-cpp,bugprone-random-generator-seed)
|
||||||
std::vector<std::string> tokens = {"0.1", "-0.0", "1e308", "1.7976931348623157e308", "2.2250738585072011e-308", "4.9e-324", "5e-324",
|
std::vector<std::string> tokens = {"0.1", "-0.0", "1e308", "1.7976931348623157e308", "2.2250738585072011e-308", "4.9e-324", "5e-324",
|
||||||
"0.1000000000000000055511151231257827021181583404541015625", "123456789012345678901234567890",
|
"0.1000000000000000055511151231257827021181583404541015625", "123456789012345678901234567890",
|
||||||
"9007199254740993", "1.00000000000000011102230246251565404236316680908203125", "7.2057594037927933e16"
|
"9007199254740993", "1.00000000000000011102230246251565404236316680908203125", "7.2057594037927933e16"
|
||||||
@@ -853,14 +862,11 @@ TEST_CASE("json_view values")
|
|||||||
{
|
{
|
||||||
CAPTURE(token);
|
CAPTURE(token);
|
||||||
const std::string text = "[" + token + "]";
|
const std::string text = "[" + token + "]";
|
||||||
const double a = json_document::parse(text).root()[0].get<double>();
|
|
||||||
const double b = json::parse(text)[0].get<double>();
|
const double b = json::parse(text)[0].get<double>();
|
||||||
CHECK(std::memcmp(&a, &b, sizeof(double)) == 0);
|
CHECK(bits(json_document::parse(text).root()[0].get<double>()) == bits(b));
|
||||||
if (std::abs(b) < 1e38)
|
if (std::abs(b) < 1e38)
|
||||||
{
|
{
|
||||||
const float fa = nlohmann::basic_json_document<json_float>::parse(text).root()[0].get<float>();
|
CHECK(bits(nlohmann::basic_json_document<json_float>::parse(text).root()[0].get<float>()) == bits(json_float::parse(text)[0].get<float>()));
|
||||||
const float fb = json_float::parse(text)[0].get<float>();
|
|
||||||
CHECK(std::memcmp(&fa, &fb, sizeof(float)) == 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1002,7 +1008,7 @@ TEST_CASE("json_view JSON pointers")
|
|||||||
CHECK(v.at(p).materialize() == j.at(p));
|
CHECK(v.at(p).materialize() == j.at(p));
|
||||||
CHECK(v[p].materialize() == j[p]);
|
CHECK(v[p].materialize() == j[p]);
|
||||||
}
|
}
|
||||||
else if (at_error.find("out_of_range.401") != std::string::npos || at_error.find("out_of_range.403") != std::string::npos)
|
else if (at_error.find("out_of_range.401") != std::string::npos || at_error.find("out_of_range.403") != std::string::npos) // NOLINT(abseil-string-find-str-contains)
|
||||||
{
|
{
|
||||||
// undefined behavior for const basic_json::operator[]
|
// undefined behavior for const basic_json::operator[]
|
||||||
CHECK(!v[p]);
|
CHECK(!v[p]);
|
||||||
|
|||||||
Reference in New Issue
Block a user