Compare commits

..

2 Commits

Author SHA1 Message Date
Niels Lohmann
55f93686c0 Merge branch 'release/3.12.0' 2025-04-11 10:42:28 +02:00
Niels Lohmann
34e46d76da 🔖 set version to 3.12.0
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2025-04-07 21:32:58 +02:00
25 changed files with 228 additions and 226 deletions

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
@@ -34,7 +34,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
@@ -36,14 +36,14 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
uses: github/codeql-action/init@fc7e4a0fa01c3cca5fd6a1fddec5c0740c977aa2 # v3.28.14
with:
languages: c-cpp
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
uses: github/codeql-action/autobuild@fc7e4a0fa01c3cca5fd6a1fddec5c0740c977aa2 # v3.28.14
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
uses: github/codeql-action/analyze@fc7e4a0fa01c3cca5fd6a1fddec5c0740c977aa2 # v3.28.14

View File

@@ -19,7 +19,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -36,7 +36,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
@@ -76,6 +76,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
uses: github/codeql-action/upload-sarif@fc7e4a0fa01c3cca5fd6a1fddec5c0740c977aa2 # v3.28.14
with:
sarif_file: results.sarif

View File

@@ -16,7 +16,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -23,7 +23,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -46,7 +46,7 @@ jobs:
target: [ci_test_amalgamation, ci_test_single_header, ci_cppcheck, ci_cpplint, ci_reproducible_tests, ci_non_git_tests, ci_offline_testdata, ci_reuse_compliance, ci_test_valgrind]
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
@@ -54,7 +54,7 @@ jobs:
run: sudo apt-get update ; sudo apt-get install -y valgrind
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -71,7 +71,7 @@ jobs:
run: apt-get update ; apt-get install -y git clang-tools iwyu unzip
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -88,7 +88,7 @@ jobs:
run: apt-get update ; apt-get install -y build-essential unzip wget git libssl-dev
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -98,7 +98,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
@@ -148,7 +148,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -165,7 +165,7 @@ jobs:
run: apt-get update ; apt-get install -y unzip git
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Set env FORCE_STDCPPFS_FLAG for clang 7 / 8 / 9 / 10
run: echo "JSON_FORCED_GLOBAL_COMPILE_OPTIONS=-DJSON_HAS_FILESYSTEM=0;-DJSON_HAS_EXPERIMENTAL_FILESYSTEM=0" >> "$GITHUB_ENV"
if: ${{ matrix.compiler == '7' || matrix.compiler == '8' || matrix.compiler == '9' || matrix.compiler == '10' }}
@@ -183,7 +183,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
@@ -201,7 +201,7 @@ jobs:
run: apt-get update ; apt-get install -y git unzip
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
uses: lukka/get-cmake@28983e0d3955dba2bb0a6810caae0c6cf268ec0c # v4.0.0
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build with libc++
@@ -233,24 +233,6 @@ jobs:
. /opt/intel/oneapi/setvars.sh
cmake --build build --target ci_icpc
ci_emscripten:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
- name: Install emscripten
uses: mymindstorm/setup-emsdk@v14
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get latest CMake and ninja
uses: lukka/get-cmake@57c20a23a6cac5b90f31864439996e5b206df9dc # v4.0.1
- name: Run CMake
run: cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -GNinja
- name: Build
run: cmake --build build
ci_test_documentation:
runs-on: ubuntu-latest
strategy:
@@ -258,7 +240,7 @@ jobs:
target: [ci_test_examples, ci_test_build_documentation]
steps:
- name: Harden Runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit

View File

@@ -37,48 +37,69 @@ jobs:
- name: Test
run: cd build ; ctest -j 10 -C Debug --output-on-failure
msvc:
msvc2019:
runs-on: windows-2019
strategy:
matrix:
runs_on: [windows-2019, windows-2022]
build_type: [Debug, Release]
architecture: [Win32, x64]
std_version: [default, latest]
runs-on: ${{ matrix.runs_on }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set generator
id: generator
run: |
if [ "${{ matrix.runs_on }}" = "windows-2019" ]; then
echo "generator=Visual Studio 16 2019" >> $GITHUB_ENV
else
echo "generator=Visual Studio 17 2022" >> $GITHUB_ENV
fi
shell: bash
- name: Set extra CXX_FLAGS for latest std_version
id: cxxflags
run: |
if [ "${{ matrix.std_version }}" = "latest" ]; then
echo "flags=/permissive- /std:c++latest /utf-8 /W4 /WX" >> $GITHUB_ENV
else
echo "flags=/W4 /WX" >> $GITHUB_ENV
fi
shell: bash
- name: Run CMake (Release)
run: cmake -S . -B build -G "$env:generator" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="$env:flags"
if: matrix.build_type == 'Release'
shell: pwsh
- name: Run CMake (Debug)
run: cmake -S . -B build -G "$env:generator" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="$env:flags"
if: matrix.build_type == 'Debug'
shell: pwsh
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Release'
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Debug'
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
msvc2019_latest:
runs-on: windows-2019
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 16 2019" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX"
- name: Build
run: cmake --build build --config Release --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C Release --output-on-failure
msvc2022:
runs-on: windows-2022
strategy:
matrix:
build_type: [Debug, Release]
architecture: [Win32, x64]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Release'
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 17 2022" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Debug'
- name: Build
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C ${{ matrix.build_type }} --output-on-failure
msvc2022_latest:
runs-on: windows-2022
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run CMake
run: cmake -S . -B build -G "Visual Studio 17 2022" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX"
- name: Build
run: cmake --build build --config Release --parallel 10
- name: Test
run: cd build ; ctest -j 10 -C Release --output-on-failure
clang:
runs-on: windows-2019
@@ -97,7 +118,7 @@ jobs:
- name: Test
run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure
clang-cl-12:
clang-cl-11:
runs-on: windows-2019
strategy:
matrix:

View File

@@ -1 +1 @@
cppcheck==1.5.1
cppcheck==1.5.0

View File

@@ -1 +1 @@
cpplint==2.0.2
cpplint==2.0.1

View File

@@ -57,7 +57,6 @@ violations will result in a failed build.
| Clang 19.1.7 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| Clang 20.1.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| Clang 21.0.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| Emscripten 4.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| GNU 4.8.5 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| GNU 4.9.3 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| GNU 5.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
@@ -76,7 +75,6 @@ violations will result in a failed build.
| GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub |
| GNU 14.2.0 | arm64 | Linux 6.1.100 | Cirrus CI |
| icpc (ICC) 2021.5.0 20211109 | x86_64 | Ubuntu 20.04.3 LTS | GitHub |
| MSVC 19.0.24241.7 | x86 | Windows 8.1 | AppVeyor |
| MSVC 19.16.27035.0 | x86 | Windows-10 (Build 14393) | AppVeyor |
| MSVC 19.29.30157.0 | x86 | Windows 10 (Build 17763) | GitHub |

View File

@@ -2,7 +2,7 @@ wheel==0.45.1
mkdocs==1.6.1 # documentation framework
mkdocs-git-revision-date-localized-plugin==1.4.5 # plugin "git-revision-date-localized"
mkdocs-material==9.6.12 # theme for mkdocs
mkdocs-material==9.6.11 # theme for mkdocs
mkdocs-material-extensions==1.3.1 # extensions
mkdocs-minify-plugin==0.8.0 # plugin "minify"
mkdocs-redirects==1.2.2 # plugin "redirects"

View File

@@ -13,6 +13,9 @@
#include <forward_list> // forward_list
#include <iterator> // inserter, front_inserter, end
#include <map> // map
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
#include <string> // string
#include <tuple> // tuple, make_tuple
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
@@ -29,11 +32,6 @@
#include <nlohmann/detail/string_concat.hpp>
#include <nlohmann/detail/value_t.hpp>
// include after macro_scope.hpp
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@@ -49,6 +47,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
}
#ifdef JSON_HAS_CPP_17
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
template<typename BasicJsonType, typename T>
void from_json(const BasicJsonType& j, std::optional<T>& opt)
{
@@ -61,6 +60,8 @@ void from_json(const BasicJsonType& j, std::optional<T>& opt)
opt.emplace(j.template get<T>());
}
}
#endif // JSON_USE_IMPLICIT_CONVERSIONS
#endif // JSON_HAS_CPP_17
// overloads for basic_json template parameters
@@ -539,10 +540,7 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
}
const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
// Checking for C++20 standard or later can be insufficient in case the
// library support for char8_t is either incomplete or was disabled
// altogether. Use the __cpp_lib_char8_t feature test instead.
#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
#ifdef JSON_HAS_CPP_20
p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
#else
p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20

View File

@@ -15,8 +15,7 @@
#include <algorithm> // copy
#include <iterator> // begin, end
#include <memory> // allocator_traits
#include <string> // basic_string, char_traits
#include <string> // string
#include <tuple> // tuple, get
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
#include <utility> // move, forward, declval, pair
@@ -268,7 +267,7 @@ struct external_constructor<value_t::object>
#ifdef JSON_HAS_CPP_17
template<typename BasicJsonType, typename T,
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
void to_json(BasicJsonType& j, const std::optional<T>& opt)
{
if (opt.has_value())
{
@@ -441,21 +440,15 @@ inline void to_json(BasicJsonType& j, const T& t)
}
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
#if defined(__cpp_lib_char8_t)
template<typename BasicJsonType, typename Tr, typename Allocator>
inline void to_json(BasicJsonType& j, const std::basic_string<char8_t, Tr, Allocator>& s)
{
using OtherAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<char>;
j = std::basic_string<char, std::char_traits<char>, OtherAllocator>(s.begin(), s.end(), s.get_allocator());
}
#endif
template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std_fs::path& p)
{
// Returns either a std::string or a std::u8string depending whether library
// support for char8_t is enabled.
j = p.u8string();
#ifdef JSON_HAS_CPP_20
const std::u8string s = p.u8string();
j = std::string(s.begin(), s.end());
#else
j = p.u8string(); // returns std::string in C++17
#endif
}
#endif

View File

@@ -2826,22 +2826,17 @@ class binary_reader
{
return;
}
else if constexpr(std::is_integral_v<NumberType>)
if constexpr(std::is_integral_v<NumberType>)
{
number = std::byteswap(number);
return;
}
else
#endif
auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
for (std::size_t i = 0; i < sz / 2; ++i)
{
#endif
auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
for (std::size_t i = 0; i < sz / 2; ++i)
{
std::swap(ptr[i], ptr[sz - i - 1]);
}
#ifdef __cpp_lib_byteswap
std::swap(ptr[i], ptr[sz - i - 1]);
}
#endif
}
/*

View File

@@ -973,9 +973,9 @@ class binary_writer
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
static_cast<void>(j);
}
static_cast<void>(j);
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
}

View File

@@ -17,7 +17,6 @@
#include <cstdint> // uint8_t
#include <cstdio> // snprintf
#include <limits> // numeric_limits
#include <sstream> // string_stream
#include <string> // string, char_traits
#include <iomanip> // setfill, setw
#include <type_traits> // is_same
@@ -763,7 +762,7 @@ class serializer
// jump to the end to generate the string from backward,
// so we later avoid reversing the result
buffer_ptr += static_cast<typename decltype(number_buffer)::difference_type>(n_chars);
buffer_ptr += n_chars;
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
@@ -828,13 +827,53 @@ class serializer
void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
{
std::ostringstream oss;
oss.precision(std::numeric_limits<number_float_t>::max_digits10);
oss.imbue(std::locale::classic());
oss << std::defaultfloat << x;
// get number of digits for a float -> text -> float round-trip
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
const auto s = oss.str();
o->write_characters(s.c_str(), s.size());
// the actual conversion
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
// negative value indicates an error
JSON_ASSERT(len > 0);
// check if buffer was large enough
JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
// erase thousands separator
if (thousands_sep != '\0')
{
// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
std::fill(end, number_buffer.end(), '\0');
JSON_ASSERT((end - number_buffer.begin()) <= len);
len = (end - number_buffer.begin());
}
// convert decimal point to '.'
if (decimal_point != '\0' && decimal_point != '.')
{
// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
if (dec_pos != number_buffer.end())
{
*dec_pos = '.';
}
}
o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
// determine if we need to append ".0"
const bool value_is_int_like =
std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
[](char c)
{
return c == '.' || c == 'e';
});
if (value_is_int_like)
{
o->write_characters(".0", 2);
}
}
/*!

View File

@@ -173,6 +173,9 @@
#include <forward_list> // forward_list
#include <iterator> // inserter, front_inserter, end
#include <map> // map
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
#include <string> // string
#include <tuple> // tuple, make_tuple
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
@@ -4814,11 +4817,6 @@ NLOHMANN_JSON_NAMESPACE_END
// #include <nlohmann/detail/value_t.hpp>
// include after macro_scope.hpp
#ifdef JSON_HAS_CPP_17
#include <optional> // optional
#endif
NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail
{
@@ -4834,6 +4832,7 @@ inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
}
#ifdef JSON_HAS_CPP_17
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
template<typename BasicJsonType, typename T>
void from_json(const BasicJsonType& j, std::optional<T>& opt)
{
@@ -4846,6 +4845,8 @@ void from_json(const BasicJsonType& j, std::optional<T>& opt)
opt.emplace(j.template get<T>());
}
}
#endif // JSON_USE_IMPLICIT_CONVERSIONS
#endif // JSON_HAS_CPP_17
// overloads for basic_json template parameters
@@ -5324,10 +5325,7 @@ inline void from_json(const BasicJsonType& j, std_fs::path& p)
JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
}
const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
// Checking for C++20 standard or later can be insufficient in case the
// library support for char8_t is either incomplete or was disabled
// altogether. Use the __cpp_lib_char8_t feature test instead.
#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
#ifdef JSON_HAS_CPP_20
p = std_fs::path(std::u8string_view(reinterpret_cast<const char8_t*>(s.data()), s.size()));
#else
p = std_fs::u8path(s); // accepts UTF-8 encoded std::string in C++17, deprecated in C++20
@@ -5382,8 +5380,7 @@ NLOHMANN_JSON_NAMESPACE_END
#include <algorithm> // copy
#include <iterator> // begin, end
#include <memory> // allocator_traits
#include <string> // basic_string, char_traits
#include <string> // string
#include <tuple> // tuple, get
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
#include <utility> // move, forward, declval, pair
@@ -5917,7 +5914,7 @@ struct external_constructor<value_t::object>
#ifdef JSON_HAS_CPP_17
template<typename BasicJsonType, typename T,
enable_if_t<std::is_constructible<BasicJsonType, T>::value, int> = 0>
void to_json(BasicJsonType& j, const std::optional<T>& opt) noexcept
void to_json(BasicJsonType& j, const std::optional<T>& opt)
{
if (opt.has_value())
{
@@ -6090,21 +6087,15 @@ inline void to_json(BasicJsonType& j, const T& t)
}
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
#if defined(__cpp_lib_char8_t)
template<typename BasicJsonType, typename Tr, typename Allocator>
inline void to_json(BasicJsonType& j, const std::basic_string<char8_t, Tr, Allocator>& s)
{
using OtherAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<char>;
j = std::basic_string<char, std::char_traits<char>, OtherAllocator>(s.begin(), s.end(), s.get_allocator());
}
#endif
template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std_fs::path& p)
{
// Returns either a std::string or a std::u8string depending whether library
// support for char8_t is enabled.
j = p.u8string();
#ifdef JSON_HAS_CPP_20
const std::u8string s = p.u8string();
j = std::string(s.begin(), s.end());
#else
j = p.u8string(); // returns std::string in C++17
#endif
}
#endif
@@ -12611,22 +12602,17 @@ class binary_reader
{
return;
}
else if constexpr(std::is_integral_v<NumberType>)
if constexpr(std::is_integral_v<NumberType>)
{
number = std::byteswap(number);
return;
}
else
#endif
auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
for (std::size_t i = 0; i < sz / 2; ++i)
{
#endif
auto* ptr = reinterpret_cast<std::uint8_t*>(&number);
for (std::size_t i = 0; i < sz / 2; ++i)
{
std::swap(ptr[i], ptr[sz - i - 1]);
}
#ifdef __cpp_lib_byteswap
std::swap(ptr[i], ptr[sz - i - 1]);
}
#endif
}
/*
@@ -16727,9 +16713,9 @@ class binary_writer
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
static_cast<void>(j);
}
static_cast<void>(j);
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
}
@@ -17625,7 +17611,6 @@ NLOHMANN_JSON_NAMESPACE_END
#include <cstdint> // uint8_t
#include <cstdio> // snprintf
#include <limits> // numeric_limits
#include <sstream> // string_stream
#include <string> // string, char_traits
#include <iomanip> // setfill, setw
#include <type_traits> // is_same
@@ -19498,7 +19483,7 @@ class serializer
// jump to the end to generate the string from backward,
// so we later avoid reversing the result
buffer_ptr += static_cast<typename decltype(number_buffer)::difference_type>(n_chars);
buffer_ptr += n_chars;
// Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
// See: https://www.youtube.com/watch?v=o4-CwDo2zpg
@@ -19563,13 +19548,53 @@ class serializer
void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
{
std::ostringstream oss;
oss.precision(std::numeric_limits<number_float_t>::max_digits10);
oss.imbue(std::locale::classic());
oss << std::defaultfloat << x;
// get number of digits for a float -> text -> float round-trip
static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
const auto s = oss.str();
o->write_characters(s.c_str(), s.size());
// the actual conversion
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
// negative value indicates an error
JSON_ASSERT(len > 0);
// check if buffer was large enough
JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
// erase thousands separator
if (thousands_sep != '\0')
{
// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
std::fill(end, number_buffer.end(), '\0');
JSON_ASSERT((end - number_buffer.begin()) <= len);
len = (end - number_buffer.begin());
}
// convert decimal point to '.'
if (decimal_point != '\0' && decimal_point != '.')
{
// NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
if (dec_pos != number_buffer.end())
{
*dec_pos = '.';
}
}
o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
// determine if we need to append ".0"
const bool value_is_int_like =
std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
[](char c)
{
return c == '.' || c == 'e';
});
if (value_is_int_like)
{
o->write_characters(".0", 2);
}
}
/*!

View File

@@ -1134,10 +1134,9 @@ TEST_CASE("deserialization")
}
}
// select the types to test - char8_t is only available since C++20 if and only
// if __cpp_char8_t is defined.
// select the types to test - char8_t is only available in C++20
#define TYPE_LIST(...) __VA_ARGS__
#if defined(__cpp_char8_t) && (__cpp_char8_t >= 201811L)
#ifdef JSON_HAS_CPP_20
#define ASCII_TYPES TYPE_LIST(char, wchar_t, char16_t, char32_t, char8_t)
#else
#define ASCII_TYPES TYPE_LIST(char, wchar_t, char16_t, char32_t)

View File

@@ -955,8 +955,7 @@ TEST_CASE("iterators 2")
};
json j_expected{"a_key", "b_key", "c_key"};
// NOLINTNEXTLINE(fuchsia-trailing-return)
auto transformed = j.items() | std::views::transform([](const auto & item) -> std::string_view
auto transformed = j.items() | std::views::transform([](const auto & item)
{
return item.key();
});

View File

@@ -36,14 +36,6 @@ using ordered_json = nlohmann::ordered_json;
#include <variant>
#endif
#ifdef JSON_HAS_CPP_17
#if __has_include(<optional>)
#include <optional>
#elif __has_include(<experimental/optional>)
#include <experimental/optional>
#endif
#endif
#ifdef JSON_HAS_CPP_20
#if __has_include(<span>)
#include <span>
@@ -398,19 +390,6 @@ struct Example_3810
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example_3810, bla); // NOLINT(misc-use-internal-linkage)
/////////////////////////////////////////////////////////////////////
// for #4740
/////////////////////////////////////////////////////////////////////
#ifdef JSON_HAS_CPP_17
struct Example_4740
{
std::optional<std::string> host = std::nullopt;
std::optional<int> port = std::nullopt;
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Example_4740, host, port)
};
#endif
TEST_CASE("regression tests 2")
{
SECTION("issue #1001 - Fix memory leak during parser callback")
@@ -566,7 +545,7 @@ TEST_CASE("regression tests 2")
const auto length = 300;
json dump_test;
dump_test["1"] = std::string(length, static_cast<std::string::value_type>(-1));
dump_test["1"] = std::string(length, -1);
std::string expected = R"({"1":")";
for (int i = 0; i < length; ++i)
@@ -583,7 +562,7 @@ TEST_CASE("regression tests 2")
const auto length = 500;
json dump_test;
dump_test["1"] = std::string(length, static_cast<std::string::value_type>(-2));
dump_test["1"] = std::string(length, -2);
std::string expected = R"({"1":")";
for (int i = 0; i < length; ++i)
@@ -1058,28 +1037,6 @@ TEST_CASE("regression tests 2")
oj["test"] = states;
CHECK(oj["test"].dump() == expected);
}
#ifdef JSON_HAS_CPP_17
SECTION("issue #4740 - build issue with std::optional")
{
const auto t1 = Example_4740();
const auto j1 = nlohmann::json(t1);
CHECK(j1.dump() == "{\"host\":null,\"port\":null}");
const auto t2 = j1.get<Example_4740>();
CHECK(!t2.host.has_value());
CHECK(!t2.port.has_value());
// improve coverage
auto t3 = Example_4740();
t3.port = 80;
t3.host = "example.com";
const auto j2 = nlohmann::json(t3);
CHECK(j2.dump() == "{\"host\":\"example.com\",\"port\":80}");
const auto t4 = j2.get<Example_4740>();
CHECK(t4.host.has_value());
CHECK(t4.port.has_value());
}
#endif
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP

View File

@@ -841,7 +841,7 @@ class Evil
public:
Evil() = default;
template <typename T>
Evil(const T& t) : m_i(sizeof(t))
Evil(T t) : m_i(sizeof(t))
{
static_cast<void>(t); // fix MSVC's C4100 warning
}
@@ -863,10 +863,6 @@ TEST_CASE("Issue #924")
// silence Wunused-template warnings
Evil e(1);
CHECK(e.m_i >= 0);
// suppress warning: function "<unnamed>::Evil::Evil(T) [with T=std::string]" was declared but never referenced [declared_but_not_referenced]
Evil e2(std::string("foo"));
CHECK(e2.m_i >= 0);
}
TEST_CASE("Issue #1237")