mirror of
https://github.com/nlohmann/json.git
synced 2026-10-23 06:18:56 +00:00
Fix the compiler and lint findings of json_view's read side and tests
- find() and contains() dispatch on Editable for the member lookup; for documents that cannot be edited both branches were the same call (GCC -Wduplicated-branches) - json_view.hpp includes <cstdio> for the FILE overload (cpplint) - the arena check macro of the builder is on one line (cpplint read it as an if body without braces) - tests: no nested conditional (also MSVC C4018), no useless cast, parentheses around mixed operators, raw string literals, += instead of temporary concatenations, and NOLINT for the fixed seeds and a find() != npos, as elsewhere in the tests Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
5 files changed
+71
-35
No files matched your search
@@ -283,14 +283,8 @@ class builder
|
||||
const std::size_t start = arena_used();
|
||||
char* w = m_arena_write;
|
||||
const char* w_end = m_arena_end;
|
||||
#define NLOHMANN_VIEW_ENSURE(n) \
|
||||
if (NLOHMANN_VIEW_UNLIKELY(static_cast<std::size_t>(w_end - w) < (n))) \
|
||||
{ \
|
||||
m_arena_write = w; \
|
||||
arena_grow(n); \
|
||||
w = m_arena_write; \
|
||||
w_end = m_arena_end; \
|
||||
}
|
||||
#define NLOHMANN_VIEW_ENSURE(n) \
|
||||
if (NLOHMANN_VIEW_UNLIKELY(static_cast<std::size_t>(w_end - w) < (n))) { m_arena_write = w; arena_grow(n); w = m_arena_write; w_end = m_arena_end; }
|
||||
{
|
||||
const auto n = static_cast<std::size_t>(p - s);
|
||||
if (n <= 16 && end - s >= 16)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <array> // array
|
||||
#include <cstddef> // nullptr_t, size_t // IWYU pragma: keep
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <cstdio> // FILE
|
||||
#include <cstring> // memcpy, strlen
|
||||
#include <istream> // istream // IWYU pragma: keep
|
||||
#include <iterator> // distance, input_iterator_tag, iterator_traits
|
||||
@@ -462,8 +463,7 @@ class basic_json_view
|
||||
{
|
||||
return end();
|
||||
}
|
||||
const node* const k = unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size())
|
||||
: detail::view::find_member<Editable>(*m_doc, m_node, key.data(), key.size());
|
||||
const node* const k = find_key(key);
|
||||
return k != nullptr ? iterator(m_doc, k, true) : end();
|
||||
}
|
||||
|
||||
@@ -480,8 +480,7 @@ class basic_json_view
|
||||
/// whether this is an object with a member with this key
|
||||
bool contains(string_view_t key) const
|
||||
{
|
||||
return is_object() && (unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size()) != nullptr
|
||||
: detail::view::find_member<Editable>(*m_doc, m_node, key.data(), key.size()) != nullptr);
|
||||
return is_object() && find_key(key) != nullptr;
|
||||
}
|
||||
|
||||
bool contains(const char* key) const
|
||||
@@ -822,6 +821,24 @@ class basic_json_view
|
||||
return !navigation::editable() || m_doc->edits == nullptr;
|
||||
}
|
||||
|
||||
/// the member of this object with @a key (the last one if the key occurs more than once), or nullptr
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key) const
|
||||
{
|
||||
return find_key(key, std::integral_constant<bool, Editable> {});
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key, std::true_type /*editable*/) const
|
||||
{
|
||||
// (an editable document without edits is looked up as one that cannot be edited)
|
||||
return unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size())
|
||||
: detail::view::find_member<true>(*m_doc, m_node, key.data(), key.size());
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key, std::false_type /*editable*/) const
|
||||
{
|
||||
return detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size());
|
||||
}
|
||||
|
||||
/// the element of an array at an index below its size
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE basic_json_view element(size_type idx) const
|
||||
{
|
||||
|
||||
Generated
+23
-12
@@ -30,6 +30,7 @@
|
||||
#include <array> // array
|
||||
#include <cstddef> // nullptr_t, size_t // IWYU pragma: keep
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <cstdio> // FILE
|
||||
#include <cstring> // memcpy, strlen
|
||||
#include <istream> // istream // IWYU pragma: keep
|
||||
#include <iterator> // distance, input_iterator_tag, iterator_traits
|
||||
@@ -1473,14 +1474,8 @@ class builder
|
||||
const std::size_t start = arena_used();
|
||||
char* w = m_arena_write;
|
||||
const char* w_end = m_arena_end;
|
||||
#define NLOHMANN_VIEW_ENSURE(n) \
|
||||
if (NLOHMANN_VIEW_UNLIKELY(static_cast<std::size_t>(w_end - w) < (n))) \
|
||||
{ \
|
||||
m_arena_write = w; \
|
||||
arena_grow(n); \
|
||||
w = m_arena_write; \
|
||||
w_end = m_arena_end; \
|
||||
}
|
||||
#define NLOHMANN_VIEW_ENSURE(n) \
|
||||
if (NLOHMANN_VIEW_UNLIKELY(static_cast<std::size_t>(w_end - w) < (n))) { m_arena_write = w; arena_grow(n); w = m_arena_write; w_end = m_arena_end; }
|
||||
{
|
||||
const auto n = static_cast<std::size_t>(p - s);
|
||||
if (n <= 16 && end - s >= 16)
|
||||
@@ -8042,8 +8037,7 @@ class basic_json_view
|
||||
{
|
||||
return end();
|
||||
}
|
||||
const node* const k = unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size())
|
||||
: detail::view::find_member<Editable>(*m_doc, m_node, key.data(), key.size());
|
||||
const node* const k = find_key(key);
|
||||
return k != nullptr ? iterator(m_doc, k, true) : end();
|
||||
}
|
||||
|
||||
@@ -8060,8 +8054,7 @@ class basic_json_view
|
||||
/// whether this is an object with a member with this key
|
||||
bool contains(string_view_t key) const
|
||||
{
|
||||
return is_object() && (unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size()) != nullptr
|
||||
: detail::view::find_member<Editable>(*m_doc, m_node, key.data(), key.size()) != nullptr);
|
||||
return is_object() && find_key(key) != nullptr;
|
||||
}
|
||||
|
||||
bool contains(const char* key) const
|
||||
@@ -8402,6 +8395,24 @@ class basic_json_view
|
||||
return !navigation::editable() || m_doc->edits == nullptr;
|
||||
}
|
||||
|
||||
/// the member of this object with @a key (the last one if the key occurs more than once), or nullptr
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key) const
|
||||
{
|
||||
return find_key(key, std::integral_constant<bool, Editable> {});
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key, std::true_type /*editable*/) const
|
||||
{
|
||||
// (an editable document without edits is looked up as one that cannot be edited)
|
||||
return unedited() ? detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size())
|
||||
: detail::view::find_member<true>(*m_doc, m_node, key.data(), key.size());
|
||||
}
|
||||
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE const node* find_key(string_view_t key, std::false_type /*editable*/) const
|
||||
{
|
||||
return detail::view::find_member<false>(*m_doc, m_node, key.data(), key.size());
|
||||
}
|
||||
|
||||
/// the element of an array at an index below its size
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE basic_json_view element(size_type idx) const
|
||||
{
|
||||
|
||||
@@ -187,7 +187,7 @@ TEST_CASE("json_view")
|
||||
CHECK(materialized<ordered_json_document>(R"({"a":1,"b":2,"a":3})").dump() == R"({"a":3,"b":2})");
|
||||
// scalars (made without the handler), and nesting around the depth up to which the stack of open containers is local
|
||||
for (const char* scalar :
|
||||
{"null", "true", "false", "0", "-7", "18446744073709551615", "1.5e300", "-0.0", "\"\"", "\"short\"", "\"a string that is longer than fifteen bytes\"", "\"\\u00e4\\n\""
|
||||
{"null", "true", "false", "0", "-7", "18446744073709551615", "1.5e300", "-0.0", "\"\"", "\"short\"", "\"a string that is longer than fifteen bytes\"", R"("\u00e4\n")"
|
||||
})
|
||||
{
|
||||
CAPTURE(scalar)
|
||||
@@ -203,9 +203,13 @@ TEST_CASE("json_view")
|
||||
})
|
||||
{
|
||||
CAPTURE(levels)
|
||||
const std::string nested = std::string(levels, '[') + "{\"k\":[1,{\"j\":2}]}" + std::string(levels, ']');
|
||||
const std::string nested = std::string(levels, '[') + R"({"k":[1,{"j":2}]})" + std::string(levels, ']');
|
||||
CHECK(materialized<json_document>(nested) == json::parse(nested));
|
||||
const std::string wide = "{\"a\":" + nested + ",\"b\":" + nested + "}";
|
||||
std::string wide = R"({"a":)";
|
||||
wide += nested;
|
||||
wide += R"(,"b":)";
|
||||
wide += nested;
|
||||
wide += "}";
|
||||
CHECK(materialized<json_document>(wide) == json::parse(wide));
|
||||
}
|
||||
// very deep nesting (iterative, as parse())
|
||||
@@ -444,7 +448,7 @@ TEST_CASE("json_view")
|
||||
if (long_file != nullptr)
|
||||
{
|
||||
std::string padded = text;
|
||||
padded.append((4096 - (padded.size() % 4096)) % 4096 + extra, ' ');
|
||||
padded.append(((4096 - (padded.size() % 4096)) % 4096) + extra, ' ');
|
||||
CHECK(std::fwrite(padded.data(), 1, padded.size(), long_file) == padded.size());
|
||||
CHECK(std::fseek(long_file, 0, SEEK_SET) == 0);
|
||||
const json_document from_long_file = json_document::parse(long_file);
|
||||
@@ -1061,7 +1065,7 @@ TEST_CASE("json_view element access and iteration")
|
||||
const std::vector<std::string> texts =
|
||||
{
|
||||
"[]", "[1]", "[1,2,3]", "[1,\"two\",3.5,true,null,-7,18446744073709551615]", "[[]]", "[{}]", "[1,[2],3]",
|
||||
"[1,2,{\"a\":3}]", "[[1,2],3,4]", "[1,2,3,[4,5,6,7,8],9,10,11,12]", "[{\"a\":[1]},2]", "[\"a\\u00e4\",\"b\"]"
|
||||
"[1,2,{\"a\":3}]", "[[1,2],3,4]", "[1,2,3,[4,5,6,7,8],9,10,11,12]", "[{\"a\":[1]},2]", R"(["a\u00e4","b"])"
|
||||
};
|
||||
for (const std::string& text : texts)
|
||||
{
|
||||
|
||||
@@ -617,7 +617,7 @@ TEST_CASE("json_view large objects")
|
||||
std::size_t farthest = 0;
|
||||
for (const std::string& key : keys)
|
||||
{
|
||||
std::size_t i = static_cast<std::size_t>(nlohmann::detail::view::key_hash(key.data(), key.size())) & (slots - 1);
|
||||
std::size_t i = nlohmann::detail::conditional_static_cast<std::size_t>(nlohmann::detail::view::key_hash(key.data(), key.size())) & (slots - 1);
|
||||
std::size_t distance = 0;
|
||||
while (used[i])
|
||||
{
|
||||
@@ -639,7 +639,7 @@ TEST_CASE("json_view large objects")
|
||||
std::size_t width = 0;
|
||||
while (pattern[conversion] >= '0' && pattern[conversion] <= '9')
|
||||
{
|
||||
width = width * 10 + static_cast<std::size_t>(pattern[conversion] - '0');
|
||||
width = (width * 10) + static_cast<std::size_t>(pattern[conversion] - '0');
|
||||
++conversion;
|
||||
}
|
||||
const bool hex = pattern[conversion] == 'x';
|
||||
@@ -659,10 +659,10 @@ TEST_CASE("json_view large objects")
|
||||
})
|
||||
{
|
||||
CAPTURE(format)
|
||||
CHECK(max_displacement(numbered(format, std::string(format).find("%02d") != std::string::npos ? 60 : 1000, 1)) < nlohmann::detail::view::index_max_displacement);
|
||||
CHECK(max_displacement(numbered(format, std::string(format).find("%02d") != std::string::npos ? 60 : 1000, 1)) < nlohmann::detail::view::index_max_displacement); // NOLINT(abseil-string-find-str-contains)
|
||||
CHECK(max_displacement(numbered(format, 600, 7)) < nlohmann::detail::view::index_max_displacement);
|
||||
}
|
||||
std::mt19937_64 rng(7);
|
||||
std::mt19937_64 rng(7); // NOLINT(cert-msc32-c,cert-msc51-cpp,bugprone-random-generator-seed)
|
||||
for (const std::size_t length :
|
||||
{
|
||||
std::size_t{1}, std::size_t{2}, std::size_t{3}, std::size_t{5}, std::size_t{7}, std::size_t{8}, std::size_t{9}, std::size_t{12}, std::size_t{16}, std::size_t{17}, std::size_t{33}
|
||||
@@ -670,7 +670,17 @@ TEST_CASE("json_view large objects")
|
||||
{
|
||||
CAPTURE(length)
|
||||
std::set<std::string> distinct;
|
||||
while (distinct.size() < (length == 1 ? 26 : (length == 2 ? 500 : 700))) // (there are 26 and 676 keys of one and two letters)
|
||||
// (there are 26 and 676 keys of one and two letters)
|
||||
std::size_t wanted = 700;
|
||||
if (length == 1)
|
||||
{
|
||||
wanted = 26;
|
||||
}
|
||||
else if (length == 2)
|
||||
{
|
||||
wanted = 500;
|
||||
}
|
||||
while (distinct.size() < wanted)
|
||||
{
|
||||
std::string key(length, 'a');
|
||||
for (char& c : key)
|
||||
@@ -688,7 +698,7 @@ TEST_CASE("json_view large objects")
|
||||
// In a large object, a key is found by comparing its bytes with those of the member the
|
||||
// table points to: up to 16 bytes as two overlapping words, longer ones with memcmp.
|
||||
// Keys of every length from 0 to 40, and keys that differ from them in one byte.
|
||||
std::mt19937_64 rng(2026);
|
||||
std::mt19937_64 rng(2026); // NOLINT(cert-msc32-c,cert-msc51-cpp,bugprone-random-generator-seed)
|
||||
std::vector<std::string> keys;
|
||||
std::set<std::string> distinct;
|
||||
for (std::size_t length = 0; length <= 40; ++length)
|
||||
|
||||
Reference in new issue
Block a user