mirror of
https://github.com/nlohmann/json.git
synced 2026-10-17 19:48:12 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77052ec0f2 | ||
|
|
22497c7128 |
No files matched your search
@@ -135,6 +135,9 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
|
||||
headers are included.
|
||||
- [x] On Windows, the library is compiled with `<Windows.h>` being included to detect and avoid common bugs (see
|
||||
[`unit-windows_h.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-windows_h.cpp)).
|
||||
- [x] The library is compiled with Qt's keyword macros (`slots`, `signals`, `emit`, `foreach`, `forever`) being defined
|
||||
to make sure it does not use them as identifiers (see
|
||||
[`unit-qt_keywords.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-qt_keywords.cpp)).
|
||||
- [x] The library is compiled with exceptions disabled to support alternative means of error handling.
|
||||
|
||||
## Stable public API
|
||||
|
||||
@@ -525,7 +525,7 @@ class json_pointer
|
||||
{}
|
||||
};
|
||||
|
||||
std::vector<slot> slots;
|
||||
std::vector<slot> table;
|
||||
std::size_t used = 0;
|
||||
|
||||
static std::size_t hash_of(std::size_t parent, const string_t& token) noexcept
|
||||
@@ -540,19 +540,19 @@ class json_pointer
|
||||
|
||||
void grow()
|
||||
{
|
||||
std::vector<slot> old(slots.size() * 2);
|
||||
old.swap(slots);
|
||||
const std::size_t mask = slots.size() - 1;
|
||||
std::vector<slot> old(table.size() * 2);
|
||||
old.swap(table);
|
||||
const std::size_t mask = table.size() - 1;
|
||||
for (const auto& s : old)
|
||||
{
|
||||
if (s.token != nullptr)
|
||||
{
|
||||
std::size_t i = s.hash & mask;
|
||||
while (slots[i].token != nullptr)
|
||||
while (table[i].token != nullptr)
|
||||
{
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
slots[i] = s;
|
||||
table[i] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -565,7 +565,7 @@ class json_pointer
|
||||
|
||||
// start with the empty prefix only
|
||||
prefix_tree()
|
||||
: slots(16)
|
||||
: table(16)
|
||||
, parent(1, 0)
|
||||
, is_array(1, false)
|
||||
{}
|
||||
@@ -575,20 +575,20 @@ class json_pointer
|
||||
std::size_t add_child(std::size_t id, const string_t& reference_token)
|
||||
{
|
||||
const std::size_t hash = hash_of(id, reference_token);
|
||||
const std::size_t mask = slots.size() - 1;
|
||||
const std::size_t mask = table.size() - 1;
|
||||
std::size_t i = hash & mask;
|
||||
while (slots[i].token != nullptr)
|
||||
while (table[i].token != nullptr)
|
||||
{
|
||||
if (slots[i].hash == hash && slots[i].parent == id && *slots[i].token == reference_token)
|
||||
if (table[i].hash == hash && table[i].parent == id && *table[i].token == reference_token)
|
||||
{
|
||||
return slots[i].id;
|
||||
return table[i].id;
|
||||
}
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
|
||||
// new prefix
|
||||
const std::size_t child = parent.size();
|
||||
slots[i] = slot(hash, id, &reference_token, child);
|
||||
table[i] = slot(hash, id, &reference_token, child);
|
||||
if (reference_token == "0")
|
||||
{
|
||||
is_array[id] = true;
|
||||
@@ -597,7 +597,7 @@ class json_pointer
|
||||
is_array.push_back(false);
|
||||
|
||||
// keep the load factor below 1/2
|
||||
if (++used * 2 > slots.size())
|
||||
if (++used * 2 > table.size())
|
||||
{
|
||||
grow();
|
||||
}
|
||||
|
||||
Generated
+13
-13
@@ -21497,7 +21497,7 @@ class json_pointer
|
||||
{}
|
||||
};
|
||||
|
||||
std::vector<slot> slots;
|
||||
std::vector<slot> table;
|
||||
std::size_t used = 0;
|
||||
|
||||
static std::size_t hash_of(std::size_t parent, const string_t& token) noexcept
|
||||
@@ -21512,19 +21512,19 @@ class json_pointer
|
||||
|
||||
void grow()
|
||||
{
|
||||
std::vector<slot> old(slots.size() * 2);
|
||||
old.swap(slots);
|
||||
const std::size_t mask = slots.size() - 1;
|
||||
std::vector<slot> old(table.size() * 2);
|
||||
old.swap(table);
|
||||
const std::size_t mask = table.size() - 1;
|
||||
for (const auto& s : old)
|
||||
{
|
||||
if (s.token != nullptr)
|
||||
{
|
||||
std::size_t i = s.hash & mask;
|
||||
while (slots[i].token != nullptr)
|
||||
while (table[i].token != nullptr)
|
||||
{
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
slots[i] = s;
|
||||
table[i] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21537,7 +21537,7 @@ class json_pointer
|
||||
|
||||
// start with the empty prefix only
|
||||
prefix_tree()
|
||||
: slots(16)
|
||||
: table(16)
|
||||
, parent(1, 0)
|
||||
, is_array(1, false)
|
||||
{}
|
||||
@@ -21547,20 +21547,20 @@ class json_pointer
|
||||
std::size_t add_child(std::size_t id, const string_t& reference_token)
|
||||
{
|
||||
const std::size_t hash = hash_of(id, reference_token);
|
||||
const std::size_t mask = slots.size() - 1;
|
||||
const std::size_t mask = table.size() - 1;
|
||||
std::size_t i = hash & mask;
|
||||
while (slots[i].token != nullptr)
|
||||
while (table[i].token != nullptr)
|
||||
{
|
||||
if (slots[i].hash == hash && slots[i].parent == id && *slots[i].token == reference_token)
|
||||
if (table[i].hash == hash && table[i].parent == id && *table[i].token == reference_token)
|
||||
{
|
||||
return slots[i].id;
|
||||
return table[i].id;
|
||||
}
|
||||
i = (i + 1) & mask;
|
||||
}
|
||||
|
||||
// new prefix
|
||||
const std::size_t child = parent.size();
|
||||
slots[i] = slot(hash, id, &reference_token, child);
|
||||
table[i] = slot(hash, id, &reference_token, child);
|
||||
if (reference_token == "0")
|
||||
{
|
||||
is_array[id] = true;
|
||||
@@ -21569,7 +21569,7 @@ class json_pointer
|
||||
is_array.push_back(false);
|
||||
|
||||
// keep the load factor below 1/2
|
||||
if (++used * 2 > slots.size())
|
||||
if (++used * 2 > table.size())
|
||||
{
|
||||
grow();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
// | | |__ | | | | | | version 3.12.0
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
// Qt defines its keywords as macros (see qtmetamacros.h and qforeach.h) unless
|
||||
// QT_NO_KEYWORDS is defined, and it is common to include Qt headers before this
|
||||
// library; it must therefore not use these words as identifiers (see #5865)
|
||||
#define slots
|
||||
#define signals public
|
||||
#define emit
|
||||
#define Q_FOREACH(variable, container) for (variable : container) // NOLINT(bugprone-macro-parentheses): variable is a declaration, as in Qt
|
||||
#define foreach Q_FOREACH
|
||||
#define forever for (;;)
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
TEST_CASE("Qt keyword macros")
|
||||
{
|
||||
SECTION("parse and dump")
|
||||
{
|
||||
const json j = json::parse(R"({"a": [1, 2.5, "x", null, true]})");
|
||||
CHECK(j.dump() == R"({"a":[1,2.5,"x",null,true]})");
|
||||
}
|
||||
|
||||
SECTION("flatten and unflatten")
|
||||
{
|
||||
const json j = {{"a", {{"b", {1, 2}}, {"c", "d"}}}, {"e", nullptr}};
|
||||
CHECK(j.flatten().unflatten() == j);
|
||||
}
|
||||
|
||||
SECTION("JSON pointer")
|
||||
{
|
||||
json j = {{"a", {{"b", {1, 2}}}}};
|
||||
CHECK(j.at(json::json_pointer("/a/b/1")) == 2);
|
||||
j[json::json_pointer("/a/c")] = 3;
|
||||
CHECK(j.contains(json::json_pointer("/a/c")));
|
||||
}
|
||||
|
||||
SECTION("binary formats")
|
||||
{
|
||||
const json j = {{"a", {1, 2, 3}}, {"b", "c"}};
|
||||
CHECK(json::from_cbor(json::to_cbor(j)) == j);
|
||||
CHECK(json::from_msgpack(json::to_msgpack(j)) == j);
|
||||
CHECK(json::from_ubjson(json::to_ubjson(j)) == j);
|
||||
CHECK(json::from_bjdata(json::to_bjdata(j)) == j);
|
||||
CHECK(json::from_bson(json::to_bson(j)) == j);
|
||||
}
|
||||
|
||||
SECTION("patch and diff")
|
||||
{
|
||||
const json source = {{"a", 1}, {"b", {1, 2}}};
|
||||
const json target = {{"a", 2}, {"c", "d"}};
|
||||
CHECK(source.patch(json::diff(source, target)) == target);
|
||||
}
|
||||
}
|
||||
|
||||
// testing for the macros also keeps -Wunused-macros from rejecting them
|
||||
#if !defined(slots) || !defined(signals) || !defined(emit) || !defined(Q_FOREACH) || !defined(foreach) || !defined(forever)
|
||||
#error "the Qt keyword macros must stay defined for the tests above"
|
||||
#endif
|
||||
Reference in new issue
Block a user