Compare commits

..
Author SHA1 Message Date
Niels Lohmann 15c8398b6e Run host-toolchain CI jobs on ubuntu-26.04
GitHub moves ubuntu-latest to Ubuntu 26.04 between 2026-10-19 and
2026-11-19 (actions/runner-images#14748). Run the jobs that use the
runner's own compilers and tools on ubuntu-26.04 now to find breakage
before the rollout. Container jobs are unaffected.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-17 14:20:31 +02:00
8 changed files with 35 additions and 105 deletions

No files matched your search

+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
path: pr/
check:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
env:
MAIN_DIR: ${{ github.workspace }}/main
INCLUDE_DIR: ${{ github.workspace }}/main/single_include/nlohmann
+1 -1
View File
@@ -21,7 +21,7 @@ permissions:
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
permissions:
security-events: write
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
name: Scan
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
+6 -6
View File
@@ -32,7 +32,7 @@ jobs:
run: cmake --build build --target ci_test_gcc
ci_meson_install:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
@@ -77,7 +77,7 @@ jobs:
cmake --build build-import-split
ci_infer:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
@@ -106,7 +106,7 @@ jobs:
if-no-files-found: ignore
ci_static_analysis_ubuntu:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
matrix:
target: [ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
@@ -175,7 +175,7 @@ jobs:
run: cmake --build build --target ${{ matrix.target }}
ci_test_coverage:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
@@ -430,7 +430,7 @@ jobs:
run: cmake --build build --target ci_nvhpc
ci_emscripten:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
@@ -450,7 +450,7 @@ jobs:
run: cmake --build build
ci_test_documentation:
runs-on: ubuntu-latest
runs-on: ubuntu-26.04
strategy:
matrix:
target: [ci_test_examples, ci_test_build_documentation, ci_test_documentation_mermaid]
@@ -135,9 +135,6 @@ 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
+13 -13
View File
@@ -525,7 +525,7 @@ class json_pointer
{}
};
std::vector<slot> table;
std::vector<slot> slots;
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(table.size() * 2);
old.swap(table);
const std::size_t mask = table.size() - 1;
std::vector<slot> old(slots.size() * 2);
old.swap(slots);
const std::size_t mask = slots.size() - 1;
for (const auto& s : old)
{
if (s.token != nullptr)
{
std::size_t i = s.hash & mask;
while (table[i].token != nullptr)
while (slots[i].token != nullptr)
{
i = (i + 1) & mask;
}
table[i] = s;
slots[i] = s;
}
}
}
@@ -565,7 +565,7 @@ class json_pointer
// start with the empty prefix only
prefix_tree()
: table(16)
: slots(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 = table.size() - 1;
const std::size_t mask = slots.size() - 1;
std::size_t i = hash & mask;
while (table[i].token != nullptr)
while (slots[i].token != nullptr)
{
if (table[i].hash == hash && table[i].parent == id && *table[i].token == reference_token)
if (slots[i].hash == hash && slots[i].parent == id && *slots[i].token == reference_token)
{
return table[i].id;
return slots[i].id;
}
i = (i + 1) & mask;
}
// new prefix
const std::size_t child = parent.size();
table[i] = slot(hash, id, &reference_token, child);
slots[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 > table.size())
if (++used * 2 > slots.size())
{
grow();
}
+13 -13
View File
@@ -21497,7 +21497,7 @@ class json_pointer
{}
};
std::vector<slot> table;
std::vector<slot> slots;
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(table.size() * 2);
old.swap(table);
const std::size_t mask = table.size() - 1;
std::vector<slot> old(slots.size() * 2);
old.swap(slots);
const std::size_t mask = slots.size() - 1;
for (const auto& s : old)
{
if (s.token != nullptr)
{
std::size_t i = s.hash & mask;
while (table[i].token != nullptr)
while (slots[i].token != nullptr)
{
i = (i + 1) & mask;
}
table[i] = s;
slots[i] = s;
}
}
}
@@ -21537,7 +21537,7 @@ class json_pointer
// start with the empty prefix only
prefix_tree()
: table(16)
: slots(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 = table.size() - 1;
const std::size_t mask = slots.size() - 1;
std::size_t i = hash & mask;
while (table[i].token != nullptr)
while (slots[i].token != nullptr)
{
if (table[i].hash == hash && table[i].parent == id && *table[i].token == reference_token)
if (slots[i].hash == hash && slots[i].parent == id && *slots[i].token == reference_token)
{
return table[i].id;
return slots[i].id;
}
i = (i + 1) & mask;
}
// new prefix
const std::size_t child = parent.size();
table[i] = slot(hash, id, &reference_token, child);
slots[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 > table.size())
if (++used * 2 > slots.size())
{
grow();
}
-67
View File
@@ -1,67 +0,0 @@
// __ _____ _____ _____
// __| | __| | | | 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