* Document clang-tidy exclusions and drop unneeded ones Re-enable every excluded check in a run of clang-tidy 22 over all tests and remove the seven that never fire (cert-err58-cpp, clang-analyzer-webkit.NoUncountedMemberChecker, cppcoreguidelines-virtual-class-destructor, google-readability-function-size, hicpp-function-size, hicpp-no-assembler, readability-function-size). Document the reason for every remaining exclusion at the top of the file. Exclude in advance the checks that only exist in clang-tidy 23 and are noise here (bugprone-signed-bitwise, *-explicit-constructor, readability-trailing-comma, modernize-use-string-view), plus modernize-use-integer-sign-comparison, which needs C++20 std::cmp_less and flags deliberate casts. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix clang-tidy findings in documentation examples and replace redundant aliases Apply clang-tidy fixes to the documentation examples: - performance-avoid-endl: std::endl -> '\n' - readability-qualified-auto: auto -> auto* / const auto* - performance-for-range-copy: copy -> const reference - google-readability-casting: C-style cast -> static_cast Replace redundant aliases (readability-redundant-qualified-alias) such as "using json = nlohmann::json;" with "using nlohmann::json;" in the documentation, README, examples, tests, and benchmarks. Aliases at class scope and aliases of other types (with_base_class_t etc.) are kept. No changes to the library or its public API. All changed examples were compiled and run; their output matches the stored .output files (except max_size and meta, which depend on the platform and compiler). Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Format doc examples with the pinned astyle Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
3.7 KiB
Object Order
The JSON standard defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys.
Default behavior: sort keys
The default type nlohmann::json uses a std::map to store JSON objects, and thus stores object keys sorted alphabetically.
??? example "Example: json sorts object keys"
```cpp
#include <iostream>
#include <nlohmann/json.hpp>
using nlohmann::json;
int main()
{
json j;
j["one"] = 1;
j["two"] = 2;
j["three"] = 3;
std::cout << j.dump(2) << '\n';
}
```
Output:
```json
{
"one": 1,
"three": 3,
"two": 2
}
```
Alternative behavior: preserve insertion order
If you do want to preserve the insertion order, you can use the type nlohmann::ordered_json.
??? example "Example: ordered_json preserves insertion order"
```cpp
--8<-- "examples/ordered_json.cpp"
```
Output:
```json
--8<-- "examples/ordered_json.output"
```
Alternatively, nlohmann::fifo_map also preserves the insertion order and, unlike ordered_map, keeps a lookup index, so it does not have the quadratic cost described below. It is used through a small adapter (integration).
If the order does not matter and you only want faster lookup, boost::unordered_flat_map, absl::flat_hash_map, absl::node_hash_map, and several other hash maps work through an adapter that restores the template argument order basic_json expects; see Template Parameter Requirements. Note these are unordered, not insertion-ordered.
tsl::ordered_map cannot be used: its iterators expose the mapped value as const, while basic_json needs to modify it in place.
The ordered_map behind nlohmann::ordered_json is deliberately minimal and has no lookup
index, so every key access is a linear scan and building an object of n keys costs O(n²). This is unnoticeable at
typical object sizes but becomes significant for objects with many thousands of keys; see
ordered_map complexity. The alternatives above keep a lookup index and do not
have this cost.
Notes on parsing
Note that you also need to call the right parse function when reading from a file.
Assume file input.json contains the JSON object above:
{
"one": 1,
"two": 2,
"three": 3
}
!!! success "Right way"
The following code correctly calls the `parse` function from `nlohmann::ordered_json`:
```cpp
std::ifstream i("input.json");
auto j = nlohmann::ordered_json::parse(i);
std::cout << j.dump(2) << std::endl;
```
The output will be:
```json
{
"one": 1,
"two": 2,
"three": 3
}
```
??? failure "Wrong way"
The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the
insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not
restore the order from the input file.
```cpp
std::ifstream i("input.json");
nlohmann::ordered_json j = nlohmann::json::parse(i);
std::cout << j.dump(2) << std::endl;
```
The output will be:
```json
{
"one": 1,
"three": 3,
"two": 2
}
```