diff --git a/3rdparty/json-schema-validator/.clang-format b/3rdparty/json-schema-validator/.clang-format new file mode 100644 index 0000000000..93126fbb9b --- /dev/null +++ b/3rdparty/json-schema-validator/.clang-format @@ -0,0 +1,14 @@ +BasedOnStyle: LLVM +#AlignConsecutiveAssignments: true +#AlignConsecutiveDeclarations: true +AllowShortFunctionsOnASingleLine: Inline +BreakBeforeBraces: Linux +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +IndentWidth: 4 +IndentPPDirectives: AfterHash +ObjCBlockIndentWidth: 0 +SpaceAfterCStyleCast: true +TabWidth: 4 +AccessModifierOffset: -4 +UseTab: ForIndentation diff --git a/3rdparty/json-schema-validator/.gitignore b/3rdparty/json-schema-validator/.gitignore new file mode 100644 index 0000000000..bc9dd9f9ba --- /dev/null +++ b/3rdparty/json-schema-validator/.gitignore @@ -0,0 +1,7 @@ +build*/ +*.sw? +cmake-build-* +venv +env +compile_commands.json +.vs/* diff --git a/3rdparty/json-schema-validator/.packit.yaml b/3rdparty/json-schema-validator/.packit.yaml new file mode 100644 index 0000000000..8ca7fdf6f0 --- /dev/null +++ b/3rdparty/json-schema-validator/.packit.yaml @@ -0,0 +1,68 @@ +files_to_sync: + - src: .distro/ + dest: ./ + delete: true + filters: + - "protect .git*" + - "protect sources" + - "protect changelog" + - "protect gating.yaml" + # Temporary workaround until + # https://github.com/packit/packit/pull/2573 + - "- json-schema-validator.spec" + - .packit.yaml + +upstream_package_name: json-schema-validator +specfile_path: .distro/json-schema-validator.spec +downstream_package_name: json-schema-validator +update_release: false + +targets: &targets + - fedora-all-x86_64 + # TODO: aarch64 is failing at test + # JSON-Suite::Optional::Format::idn-email + # - fedora-all-aarch64 + +_: + # Job templates + - &build-in-packit + job: copr_build + - &build-in-lecris + <<: *build-in-packit + owner: "@scikit-build" + - &tests + job: tests + fmf_path: .distro + identifier: downstream + +jobs: + # Upstream jobs + - <<: *build-in-lecris + trigger: release + project: release +# - <<: *tests +# trigger: release + - <<: *build-in-lecris + trigger: commit + branch: main + project: nightly +# - <<: *tests +# trigger: commit +# branch: main + - <<: *build-in-packit + trigger: pull_request +# - <<: *tests +# trigger: pull_request + # Downstream jobs + - job: propose_downstream + trigger: release + dist_git_branches: + - fedora-rawhide + - job: koji_build + trigger: commit + dist_git_branches: + - fedora-all + - job: bodhi_update + trigger: commit + dist_git_branches: + - fedora-branched diff --git a/3rdparty/json-schema-validator/.pre-commit-config.yaml b/3rdparty/json-schema-validator/.pre-commit-config.yaml new file mode 100644 index 0000000000..80dc756ee1 --- /dev/null +++ b/3rdparty/json-schema-validator/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +repos: + - repo: https://github.com/Takishima/cmake-pre-commit-hooks + rev: v1.9.6 + hooks: + - id: clang-format + args: + - '-i' + - id: clang-tidy + args: + # TODO: Remove when upstream issue is fixed + # https://gitlab.kitware.com/cmake/cmake/-/issues/24827 + # https://github.com/Takishima/cmake-pre-commit-hooks/issues/63 + - '-Bcmake-build-pre-commit' + - '--preset' + - 'pre-commit' + stages: [ manual ] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - repo: https://github.com/executablebooks/mdformat + rev: 0.7.22 + hooks: + - id: mdformat + additional_dependencies: + - mdformat-gfm + - mdformat-tables + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.34.0 + hooks: + - id: check-github-workflows diff --git a/3rdparty/json-schema-validator/CMakeLists.txt b/3rdparty/json-schema-validator/CMakeLists.txt new file mode 100644 index 0000000000..e9df8a20ff --- /dev/null +++ b/3rdparty/json-schema-validator/CMakeLists.txt @@ -0,0 +1,220 @@ +cmake_minimum_required(VERSION 3.14) +# CMake version compatibility +# TODO: Remove when bumping cmake >= 3.25 +if (POLICY CMP0140) + # Enables: return(PROPAGATE) + cmake_policy(SET CMP0140 NEW) +endif () + +#[==============================================================================================[ +# Basic project definition # +]==============================================================================================] + +# TODO: CMake >= 3.19 can use string(JSON VERSION GET "${METADATA}" "version") to load from JSON +set(PROJECT_VERSION 2.4.0) + +# TODO: Version 3, rename the project and namespace to something more compact +project(nlohmann_json_schema_validator + VERSION ${PROJECT_VERSION} + DESCRIPTION "Json validator for nlohmann::json library" + HOMEPAGE_URL "https://github.com/pboettch/json-schema-validator" + LANGUAGES CXX) +# TODO: Remove when bumping cmake >= 3.21 +if (NOT DEFINED nlohmann_json_schema_validator_IS_TOP_LEVEL) + if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + set(PROJECT_IS_TOP_LEVEL ON) + else () + set(PROJECT_IS_TOP_LEVEL OFF) + endif () +endif () + +#[==============================================================================================[ +# Options # +]==============================================================================================] + +option(JSON_VALIDATOR_INSTALL "JsonValidator: Install targets" ${PROJECT_IS_TOP_LEVEL}) +option(JSON_VALIDATOR_BUILD_TESTS "JsonValidator: Build tests" ${PROJECT_IS_TOP_LEVEL}) +option(JSON_VALIDATOR_BUILD_EXAMPLES "JsonValidator: Build examples" ${PROJECT_IS_TOP_LEVEL}) +option(JSON_VALIDATOR_SHARED_LIBS "JsonValidator: Build as shared library" ${PROJECT_IS_TOP_LEVEL}) +option(JSON_VALIDATOR_TEST_COVERAGE "JsonValidator: Build with test coverage" OFF) +mark_as_advanced(JSON_VALIDATOR_TEST_COVERAGE) +# Get a default JSON_FETCH_VERSION from environment variables to workaround the CI +if (DEFINED ENV{NLOHMANN_JSON_VERSION}) + set(JSON_FETCH_VERSION_DEFAULT $ENV{NLOHMANN_JSON_VERSION}) +else () + set(JSON_FETCH_VERSION_DEFAULT v3.12.0) +endif () +set(JSON_FETCH_VERSION ${JSON_FETCH_VERSION_DEFAULT} CACHE STRING "Fetch nlohmann::json version") + +#[==============================================================================================[ +# Project configuration # +]==============================================================================================] + +# Include cmake modules +include(FetchContent) +if (JSON_VALIDATOR_INSTALL) + include(GNUInstallDirs) + include(CMakePackageConfigHelpers) +endif () + +# Default to release build +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + +# Enable cmake's BUILD_SHARED_LIBS +set(BUILD_SHARED_LIBS ${nlohmann_json_schema_validator_SHARED_LIBS}) + +if (JSON_VALIDATOR_TEST_COVERAGE) + if (CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL GNU) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + else () + message(WARNING + "JsonValidator: Other toolchain coverage flags unknown.\n" + "Using --coverage as default") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + endif () +endif () + +#[==============================================================================================[ +# External packages # +]==============================================================================================] + +set(fetch_packages "") +if (NOT TARGET nlohmann_json) + # Fetch/Find nlohmann_json + # TODO: Remove when bumping cmake >= 3.24 + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare(nlohmann_json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG ${JSON_FETCH_VERSION} + FIND_PACKAGE_ARGS + ) + list(APPEND fetch_packages nlohmann_json) + else () + # Try to get system installed version + find_package(nlohmann_json QUIET) + if (NOT nlohmann_json_FOUND) + # If failed fetch the desired version + FetchContent_Declare(nlohmann_json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG ${JSON_FETCH_VERSION} + ) + list(APPEND fetch_packages nlohmann_json) + endif () + endif () +endif () + +# Handle configure flags +if (JSON_VALIDATOR_INSTALL) + # TODO: This is not ideal, this package should not be installing nlohmann::json + # Currently required in order to satisfy cmake exporter + set(JSON_Install ON CACHE BOOL "") +endif () + +# Get all dependencies +FetchContent_MakeAvailable(${fetch_packages}) +if (JSON_VALIDATOR_INSTALL AND NOT nlohmann_json_FOUND AND JSON_Install) + # TODO: This is not ideal + message(WARNING + "JsonValidator: No nlohmann::json found on the system and nlohmann_json_schema_validator will be installed\n" + "This will also install nlohmann::json in its typical installation path\n" + "This is not ideal because it might overwrite system installed") +endif () + +#[==============================================================================================[ +# Main definition # +]==============================================================================================] + +message(STATUS "JsonValidator: Configured for ${CMAKE_BUILD_TYPE}") +if (DEFINED nlohmann_json_VERSION) + message(STATUS "JsonValidator: Using nlohmann/json version: ${nlohmann_json_VERSION}") +else () + message(STATUS "JsonValidator: nlohmann_json_VERSION is not set. Possible value: ${JSON_FETCH_VERSION}") +endif () + +## Main targets +add_library(nlohmann_json_schema_validator) +add_library(nlohmann_json_schema_validator::validator ALIAS nlohmann_json_schema_validator) +set_target_properties(nlohmann_json_schema_validator PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + EXPORT_NAME validator + # TODO: Version 3, simplify the library name +# OUTPUT_NAME nlohmann_json_validator + ) + +# Main definitions in here +add_subdirectory(src) + +# Enable examples + +# Enable testings +if (JSON_VALIDATOR_BUILD_TESTS) + enable_testing() + add_subdirectory(test) +endif () + +if (JSON_VALIDATOR_BUILD_EXAMPLES) + add_subdirectory(example) +endif () + + +#[==============================================================================================[ +# Install or Export # +]==============================================================================================] + +if (JSON_VALIDATOR_INSTALL) + # Note other install targets found in subdirectories + # Here mostly the cmake boilerplate are set + write_basic_package_version_file(nlohmann_json_schema_validatorConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + configure_package_config_file(cmake/nlohmann_json_schema_validatorConfig.cmake.in + nlohmann_json_schema_validatorConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator + ) + + # Install Targets files + export(EXPORT nlohmann_json_schema_validatorTargets + NAMESPACE nlohmann_json_schema_validator:: + FILE nlohmann_json_schema_validatorTargets.cmake + ) + install(EXPORT nlohmann_json_schema_validatorTargets + FILE nlohmann_json_schema_validatorTargets.cmake + NAMESPACE nlohmann_json_schema_validator:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator + COMPONENT nlohmann_json_schema_validator_Development + ) + # Install cmake export files + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_schema_validatorConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/nlohmann_json_schema_validatorConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nlohmann_json_schema_validator + COMPONENT nlohmann_json_schema_validator_Development + ) +endif () + +# Handle the project being included externally (e.g. FetchContent) +if (NOT PROJECT_IS_TOP_LEVEL) + # Export variables set in nlohmann_json_schema_validatorConfig.cmake + # TODO: Remove when bumping cmake >= 3.25 + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.25) + return(PROPAGATE + nlohmann_json_schema_validator_VERSION + nlohmann_json_schema_validator_VERSION_MAJOR + nlohmann_json_schema_validator_VERSION_MINOR + nlohmann_json_schema_validator_VERSION_PATCH + nlohmann_json_schema_validator_VERSION_TWEAK + ) + else () + set(nlohmann_json_schema_validator_VERSION ${nlohmann_json_schema_validator_VERSION} PARENT_SCOPE) + set(nlohmann_json_schema_validator_VERSION_MAJOR ${nlohmann_json_schema_validator_VERSION_MAJOR} PARENT_SCOPE) + set(nlohmann_json_schema_validator_VERSION_MINOR ${nlohmann_json_schema_validator_VERSION_MINOR} PARENT_SCOPE) + set(nlohmann_json_schema_validator_VERSION_PATCH ${nlohmann_json_schema_validator_VERSION_PATCH} PARENT_SCOPE) + set(nlohmann_json_schema_validator_VERSION_TWEAK ${nlohmann_json_schema_validator_VERSION_TWEAK} PARENT_SCOPE) + endif () +endif () diff --git a/3rdparty/json-schema-validator/CMakePresets.json b/3rdparty/json-schema-validator/CMakePresets.json new file mode 100644 index 0000000000..51696d4eda --- /dev/null +++ b/3rdparty/json-schema-validator/CMakePresets.json @@ -0,0 +1,7 @@ +{ + "version": 6, + "include": [ + "cmake/CMakePresets-defaults.json", + "cmake/CMakePresets-CI.json" + ] +} diff --git a/3rdparty/json-schema-validator/ChangeLog.md b/3rdparty/json-schema-validator/ChangeLog.md new file mode 100644 index 0000000000..0acd8a0ce1 --- /dev/null +++ b/3rdparty/json-schema-validator/ChangeLog.md @@ -0,0 +1,13 @@ +## Release 2.4.0 + +- Added CI job to publish GitHub release by @JohanMabille in +- Maintenance to Fedora CI infrastructure by @LecrisUT and @JohanMabille in +- Reference validation using contains() result rather than exception handling by @BalrogOfHell in +- add support for $defs instead of definitions by rpatters1 in +- Apply clang-format / fix "test / Check pre-commit" failures by @serge-s in +- Adding verbose error messages for logical combinations by Csaba Imre Zempleni in +- fix: issue-311 by andrejlevkovitch +- Fix cmake install target on windows by @barts-of in +- error-messages: Numeric limit errors should show maximum precision by @pboettch +- Add Fedora packaging by @LecrisUT in +- Improve and fix bugs in Conanfile by Jacob Crabill diff --git a/3rdparty/json-schema-validator/LICENSE b/3rdparty/json-schema-validator/LICENSE new file mode 100644 index 0000000000..f660b34272 --- /dev/null +++ b/3rdparty/json-schema-validator/LICENSE @@ -0,0 +1,22 @@ +Modern C++ JSON schema validator is licensed under the MIT License +: + +Copyright (c) 2016 Patrick Boettcher + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/3rdparty/json-schema-validator/README.md b/3rdparty/json-schema-validator/README.md new file mode 100644 index 0000000000..93751e790b --- /dev/null +++ b/3rdparty/json-schema-validator/README.md @@ -0,0 +1,366 @@ +[![Build Status](https://travis-ci.org/pboettch/json-schema-validator.svg?branch=master)](https://travis-ci.org/pboettch/json-schema-validator) + +# JSON schema validator for JSON for Modern C++ + +# What is it? + +This is a C++ library for validating JSON documents based on a +[JSON Schema](http://json-schema.org/) which itself should validate with +[draft-7 of JSON Schema Validation](http://json-schema.org/schema). + +First a disclaimer: *It is work in progress and +contributions or hints or discussions are welcome.* + +Niels Lohmann et al develop a great JSON parser for C++ called [JSON for Modern +C++](https://github.com/nlohmann/json). This validator is based on this +library, hence the name. + +External documentation is missing as well. However the API of the validator +is rather simple. + +# New in version 2 + +Although significant changes have been done for the 2nd version +(a complete rewrite) the API is compatible with the 1.0.0 release. Except for +the namespace which is now `nlohmann::json_schema`. + +Version **2** supports JSON schema draft 7, whereas 1 was supporting draft 4 +only. Please update your schemas. + +The primary change in 2 is the way a schema is used. While in version 1 the schema was +kept as a JSON-document and used again and again during validation, in version 2 the schema +is parsed into compiled C++ objects which are then used during validation. There are surely +still optimizations to be done, but validation speed has improved by factor 100 +or more. + +# Design goals + +The main goal of this validator is to produce *human-comprehensible* error +messages if a JSON-document/instance does not comply to its schema. + +By default this is done with exceptions thrown at the users with a helpful +message telling what's wrong with the document while validating. + +Starting with **2.0.0** the user can pass a `json_schema::basic_error_handler`-derived +object along with the instance to validate to receive a callback each time +a validation error occurs and decide what to do (throwing, counting, collecting). + +Another goal was to use Niels Lohmann's JSON-library. This is why the validator +lives in his namespace. + +# Thread-safety + +Instance validation is thread-safe and the same validator-object can be used by +different threads: + +The validate method is `const` which indicates the object is not modified when +being called: + +```C++ + json json_validator::validate(const json &) const; +``` + +Validator-object creation however is not thread-safe. A validator has to be +created in one (main?) thread once. + +# Weaknesses + +Numerical validation uses nlohmann-json's integer, unsigned and floating point +types, depending on if the schema type is "integer" or "number". Bignum +(i.e. arbitrary precision and range) is not supported at this time. + +# Building + +This library is based on Niels Lohmann's JSON-library and thus has +a build-dependency to it. + +Currently at least version **3.8.0** of NLohmann's JSON library +is required. + +Various methods using CMake can be used to build this project. + +## Build out-of-source + +Do not run cmake inside the source-dir. Rather create a dedicated build-dir: + +```Bash +git clone https://github.com/pboettch/json-schema-validator.git +cd json-schema-validator +mkdir build +cd build +cmake [..] +make +make install # if needed +ctest # run unit, non-regression and test-suite tests +``` + +## Building as shared library + +By default a static library is built. Shared libraries can be generated by using +the `BUILD_SHARED_LIBS`-cmake variable: + +In your initial call to cmake simply add: + +```bash +cmake [..] -DBUILD_SHARED_LIBS=ON [..] +``` + +## nlohmann-json integration + +As nlohmann-json is a dependency, this library tries find it. + +The cmake-configuration first checks if nlohmann-json is available as a cmake-target. This may be the case, because it is used as a submodule in a super-project which already provides and uses nlohmann-json. +Otherwise, it calls `find_package` for nlohmann-json and requires nlohmann-json to be installed on the system. + +### Building with Hunter package manager + +To enable access to nlohmann json library, Hunter can be used. Just run with `JSON_VALIDATOR_HUNTER=ON` option. No further dependencies needed + +```bash +cmake [..] -DJSON_VALIDATOR_HUNTER=ON [..] +``` + +### Building as a CMake-subdirectory from within another project + +Adding this library as a subdirectory to a parent project is one way of +building it. + +If the parent project already used `find_package()` to find the CMake-package of nlohmann_json or includes it as a submodule likewise. + +### Building directly, finding a CMake-package. (short) + +When nlohmann-json has been installed, it provides files which allows +CMake's `find_package()` to be used. + +This library is using this mechanism if `nlohmann_json::nlohmann_json`-target +does not exist. + +### Install + +Since version 2.1.0 this library can be installed and CMake-package-files will be +created accordingly. If the installation of nlohmann-json and this library +is done into default unix-system-paths CMake will be able to find this +library by simply doing: + +```CMake +find_package(nlohmann_json_schema_validator REQUIRED) +``` + +and + +```CMake +target_link_libraries( [..] nlohmann_json_schema_validator) +``` + +to build and link. + +## Code + +See also `app/json-schema-validate.cpp`. + +```C++ +#include +#include + +#include + +using nlohmann::json; +using nlohmann::json_schema::json_validator; + +// The schema is defined based upon a string literal +static json person_schema = R"( +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A person", + "properties": { + "name": { + "description": "Name", + "type": "string" + }, + "age": { + "description": "Age of the person", + "type": "number", + "minimum": 2, + "maximum": 200 + } + }, + "required": [ + "name", + "age" + ], + "type": "object" +} + +)"_json; + +// The people are defined with brace initialization +static json bad_person = {{"age", 42}}; +static json good_person = {{"name", "Albert"}, {"age", 42}}; + +int main() +{ + /* json-parse the schema */ + + json_validator validator; // create validator + + try { + validator.set_root_schema(person_schema); // insert root-schema + } catch (const std::exception &e) { + std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n"; + return EXIT_FAILURE; + } + + /* json-parse the people - API of 1.0.0, default throwing error handler */ + + for (auto &person : {bad_person, good_person}) { + std::cout << "About to validate this person:\n" + << std::setw(2) << person << std::endl; + try { + validator.validate(person); // validate the document - uses the default throwing error-handler + std::cout << "Validation succeeded\n"; + } catch (const std::exception &e) { + std::cerr << "Validation failed, here is why: " << e.what() << "\n"; + } + } + + /* json-parse the people - with custom error handler */ + class custom_error_handler : public nlohmann::json_schema::basic_error_handler + { + void error(const nlohmann::json_pointer> &pointer, const json &instance, + const std::string &message) override + { + nlohmann::json_schema::basic_error_handler::error(pointer, instance, message); + std::cerr << "ERROR: '" << pointer << "' - '" << instance << "': " << message << "\n"; + } + }; + + + for (auto &person : {bad_person, good_person}) { + std::cout << "About to validate this person:\n" + << std::setw(2) << person << std::endl; + + custom_error_handler err; + validator.validate(person, err); // validate the document + + if (err) + std::cerr << "Validation failed\n"; + else + std::cout << "Validation succeeded\n"; + } + + return EXIT_SUCCESS; +} +``` + +# Compliance + +There is an application which can be used for testing the validator with the +[JSON-Schema-Test-Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite). +In order to simplify the testing, the test-suite is included in the repository. + +If you have cloned this repository providing a path the repository-root via the +cmake-variable `JSON_SCHEMA_TEST_SUITE_PATH` will enable the test-target(s). + +All required tests are **OK**. + +# Format + +Optionally JSON-schema-validator can validate predefined or user-defined formats. +Therefore a format-checker-function can be provided by the user which is called by +the validator when a format-check is required (ie. the schema contains a format-field). + +This is how the prototype looks like and how it can be passed to the validation-instance: + +```C++ +static void my_format_checker(const std::string &format, const std::string &value) +{ + if (format == "something") { + if (!check_value_for_something(value)) + throw std::invalid_argument("value is not a good something"); + } else + throw std::logic_error("Don't know how to validate " + format); +} + +// when creating the validator + +json_validator validator(nullptr, // or loader-callback + my_format_checker); // create validator +``` + +## Default Checker + +The library contains a default-checker, which does some checks. It needs to be +provided manually to the constructor of the validator: + +```C++ +json_validator validator(loader, // or nullptr for no loader + nlohmann::json_schema::default_string_format_check); +``` + +Supported formats: `date-time, date, time, email, hostname, ipv4, ipv6, uuid, regex` + +More formats can be added in `src/string-format-check.cpp`. Please contribute implementions for missing json schema draft formats. + +## Default value processing + +As a result of the validation, the library returns a json patch including the default values of the specified schema. + +```C++ +#include +#include + +using nlohmann::json; +using nlohmann::json_schema::json_validator; + +static const json rectangle_schema = R"( +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A rectangle", + "properties": { + "width": { + "$ref": "#/definitions/length", + "default": 20 + }, + "height": { + "$ref": "#/definitions/length" + } + }, + "definitions": { + "length": { + "type": "integer", + "minimum": 1, + "default": 10 + } + } +})"_json; + +int main() +{ + try { + json_validator validator{rectangle_schema}; + /* validate empty json -> will be expanded by the default values defined in the schema */ + json rectangle = "{}"_json; + const auto default_patch = validator.validate(rectangle); + rectangle = rectangle.patch(default_patch); + std::cout << rectangle.dump() << std::endl; // {"height":10,"width":20} + } catch (const std::exception &e) { + std::cerr << "Validation of schema failed: " << e.what() << "\n"; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} +``` + +The example above will output the specified default values `{"height":10,"width":20}` to stdout. + +> Note that the default value specified in a `$ref` may be overridden by the current instance location. Also note that this behavior will break draft-7, but it is compliant to newer drafts (e.g. `2019-09` or `2020-12`). + +# Contributing + +This project uses [`pre-commit`](https://pre-commit.com/) to enforce style-checks. Please install and run it before +creating commits and making pull requests. + +```console +$ pip install pre-commit +$ pre-commit install +``` diff --git a/3rdparty/json-schema-validator/cmake/CMakePresets-CI.json b/3rdparty/json-schema-validator/cmake/CMakePresets-CI.json new file mode 100644 index 0000000000..8173d222ae --- /dev/null +++ b/3rdparty/json-schema-validator/cmake/CMakePresets-CI.json @@ -0,0 +1,281 @@ +{ + "version": 6, + "include": [ + "CMakePresets-defaults.json" + ], + "configurePresets": [ + { + "name": "ci-base", + "hidden": true, + "generator": "Ninja", + "inherits": [ + "default" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": { + "type": "STRING", + "value": "Debug" + }, + "JSON_VALIDATOR_BUILD_TESTS": { + "type": "BOOL", + "value": true + }, + "JSON_VALIDATOR_INSTALL": { + "type": "BOOL", + "value": false + }, + "JSON_BuildTests": { + "type": "BOOL", + "value": false + } + }, + "errors": { + "deprecated": true + } + }, + { + "name": "gcc-ci", + "displayName": "Configure preset for GCC toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-gcc", + "cacheVariables": { + "CMAKE_CXX_COMPILER": { + "type": "FILEPATH", + "value": "g++" + }, + "CMAKE_LINKER": { + "type": "FILEPATH", + "value": "ld" + } + } + }, + { + "name": "intel-ci", + "displayName": "Configure preset for Intel toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-intel", + "cacheVariables": { + "CMAKE_CXX_COMPILER": { + "type": "FILEPATH", + "value": "icpx" + } + } + }, + { + "name": "llvm-ci", + "displayName": "Configure preset for LLVM toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-llvm", + "cacheVariables": { + "CMAKE_CXX_COMPILER": { + "type": "FILEPATH", + "value": "clang++" + }, + "CMAKE_LINKER": { + "type": "FILEPATH", + "value": "lld" + } + } + }, + { + "name": "ci-coverage", + "displayName": "Configure preset for test coverage", + "inherits": [ + "gcc-ci" + ], + "binaryDir": "cmake-build-ci-coverage", + "errors": { + "deprecated": false + }, + "cacheVariables": { + "JSON_VALIDATOR_TEST_COVERAGE": { + "type": "BOOL", + "value": true + } + } + }, + { + "name": "pre-commit", + "displayName": "Configure preset for pre-commit checks", + "inherits": [ + "default" + ], + "binaryDir": "cmake-build-pre-commit", + "cacheVariables": { + "JSON_VALIDATOR_TEST_COVERAGE": { + "type": "BOOL", + "value": true + }, + "JSON_VALIDATOR_INSTALL": { + "type": "BOOL", + "value": false + } + } + } + ], + "buildPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "cleanFirst": true + }, + { + "name": "ci-coverage", + "displayName": "Build preset for test coverage", + "inherits": [ + "ci-base" + ], + "configurePreset": "ci-coverage" + }, + { + "name": "gcc-ci", + "displayName": "Build preset for GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "intel-ci", + "displayName": "Build preset for Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + }, + { + "name": "llvm-ci", + "displayName": "Build preset for LLVM toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + } + ], + "testPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "output": { + "outputOnFailure": true + } + }, + { + "name": "ci-coverage", + "inherits": [ + "default" + ], + "configurePreset": "ci-coverage" + }, + { + "name": "gcc-ci", + "displayName": "Test preset for GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "intel-ci", + "displayName": "Test preset for Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + }, + { + "name": "llvm-ci", + "displayName": "Test preset for LLVM toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + } + ], + "workflowPresets": [ + { + "name": "gcc-ci", + "displayName": "CI test for GCC toolchain", + "steps": [ + { + "type": "configure", + "name": "gcc-ci" + }, + { + "type": "build", + "name": "gcc-ci" + }, + { + "type": "test", + "name": "gcc-ci" + } + ] + }, + { + "name": "intel-ci", + "displayName": "CI test for Intel toolchain", + "steps": [ + { + "type": "configure", + "name": "intel-ci" + }, + { + "type": "build", + "name": "intel-ci" + }, + { + "type": "test", + "name": "intel-ci" + } + ] + }, + { + "name": "llvm-ci", + "displayName": "CI test for LLVM toolchain", + "steps": [ + { + "type": "configure", + "name": "llvm-ci" + }, + { + "type": "build", + "name": "llvm-ci" + }, + { + "type": "test", + "name": "llvm-ci" + } + ] + }, + { + "name": "ci-coverage", + "displayName": "Coverage tests", + "steps": [ + { + "type": "configure", + "name": "ci-coverage" + }, + { + "type": "build", + "name": "ci-coverage" + }, + { + "type": "test", + "name": "ci-coverage" + } + ] + } + ] +} diff --git a/3rdparty/json-schema-validator/cmake/CMakePresets-defaults.json b/3rdparty/json-schema-validator/cmake/CMakePresets-defaults.json new file mode 100644 index 0000000000..bfc642cf14 --- /dev/null +++ b/3rdparty/json-schema-validator/cmake/CMakePresets-defaults.json @@ -0,0 +1,50 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "displayName": "Default configuration preset", + "binaryDir": "cmake-build-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": { + "type": "STRING", + "value": "Release" + } + } + } + ], + "buildPresets": [ + { + "name": "default", + "displayName": "Default build preset", + "configurePreset": "default" + } + ], + "testPresets": [ + { + "name": "default", + "displayName": "Default test preset", + "configurePreset": "default" + } + ], + "workflowPresets": [ + { + "name": "default", + "displayName": "Default workflow", + "steps": [ + { + "type": "configure", + "name": "default" + }, + { + "type": "build", + "name": "default" + }, + { + "type": "test", + "name": "default" + } + ] + } + ] +} diff --git a/3rdparty/json-schema-validator/cmake/nlohmann_json_schema_validatorConfig.cmake.in b/3rdparty/json-schema-validator/cmake/nlohmann_json_schema_validatorConfig.cmake.in new file mode 100644 index 0000000000..88960cceb7 --- /dev/null +++ b/3rdparty/json-schema-validator/cmake/nlohmann_json_schema_validatorConfig.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(nlohmann_json) + +include("${CMAKE_CURRENT_LIST_DIR}/nlohmann_json_schema_validatorTargets.cmake") +check_required_components( + "nlohmann_json_schema_validator" + ) diff --git a/3rdparty/json-schema-validator/conanfile.py b/3rdparty/json-schema-validator/conanfile.py new file mode 100644 index 0000000000..fb6c85e127 --- /dev/null +++ b/3rdparty/json-schema-validator/conanfile.py @@ -0,0 +1,93 @@ +import os +import re + +from conan import ConanFile +from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain +from conans.tools import load +from conans import tools as ctools + +def get_version(): + try: + version = os.getenv('PROJECT_VERSION', None) + if version: + return version + + content = load('CMakeLists.txt') + version = re.search('set\(PROJECT_VERSION (.*)\)', content).group(1) + return version.strip() + except: + return None + +class JsonSchemaValidatorConan(ConanFile): + name = 'JsonSchemaValidator' + version = get_version() + url = 'https://github.com/pboettch/json-schema-validator' + license = 'MIT' + + settings = 'os', 'compiler', 'build_type', 'arch' + + options = { + 'shared': [True, False], + 'fPIC': [True, False], + 'build_examples': [True, False], + 'build_tests': [True, False], + 'test_coverage': [True, False], + } + + default_options = { + 'shared': False, + 'fPIC': True, + 'build_examples': True, + 'build_tests': False, + 'test_coverage': False, + } + + generators = 'CMakeDeps', 'CMakeToolchain', 'VirtualBuildEnv', 'VirtualRunEnv' + + exports_sources = [ + 'CMakeLists.txt', + 'conanfile.py', + 'cmake/*', + 'src/*', + 'example/*', + 'test/*', + ] + + requires = [ + 'nlohmann_json/3.11.2' + ] + + def generate(self): + tc = CMakeToolchain(self) + tc.variables['JSON_VALIDATOR_BUILD_EXAMPLES'] = self.options.build_examples + tc.variables['JSON_VALIDATOR_BUILD_TESTS'] = self.options.build_tests + tc.variables['JSON_VALIDATOR_SHARED_LIBS '] = self.options.shared + tc.variables['JSON_VALIDATOR_TEST_COVERAGE '] = self.options.test_coverage + tc.generate() + + def layout(self): + cmake_layout(self) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.verbose = True + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + + def package_info(self): + includedir = os.path.join(self.package_folder, "include") + self.cpp_info.includedirs = [includedir] + + libdir = os.path.join(self.package_folder, "lib") + self.cpp_info.libdirs = [libdir] + self.cpp_info.libs += ctools.collect_libs(self, libdir) + + bindir = os.path.join(self.package_folder, "bin") + self.output.info("Appending PATH environment variable: {}".format(bindir)) + self.env_info.PATH.append(bindir) + + self.user_info.VERSION = self.version diff --git a/3rdparty/json-schema-validator/schema b/3rdparty/json-schema-validator/schema new file mode 100644 index 0000000000..5bee90ec14 --- /dev/null +++ b/3rdparty/json-schema-validator/schema @@ -0,0 +1,168 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://json-schema.org/draft-07/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [ + { "$ref": "#/definitions/nonNegativeInteger" }, + { "default": 0 } + ] + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "uniqueItems": true, + "default": [] + } + }, + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$comment": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "readOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, + "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { "$ref": "#" }, + "items": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } + ], + "default": true + }, + "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, + "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": { "$ref": "#" }, + "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, + "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { "$ref": "#" }, + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "propertyNames": { "format": "regex" }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } + }, + "propertyNames": { "$ref": "#" }, + "const": true, + "enum": { + "type": "array", + "items": true, + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": { "type": "string" }, + "contentMediaType": { "type": "string" }, + "contentEncoding": { "type": "string" }, + "if": {"$ref": "#"}, + "then": {"$ref": "#"}, + "else": {"$ref": "#"}, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "default": true +} diff --git a/3rdparty/json-schema-validator/src/CMakeLists.txt b/3rdparty/json-schema-validator/src/CMakeLists.txt new file mode 100644 index 0000000000..7848554ba2 --- /dev/null +++ b/3rdparty/json-schema-validator/src/CMakeLists.txt @@ -0,0 +1,64 @@ +target_sources(nlohmann_json_schema_validator PRIVATE + smtp-address-validator.cpp + json-schema-draft7.json.cpp + json-uri.cpp + json-validator.cpp + json-patch.cpp + string-format-check.cpp + ) +target_include_directories(nlohmann_json_schema_validator PUBLIC + $ + $ + ) + +set_target_properties(nlohmann_json_schema_validator PROPERTIES + PUBLIC_HEADER nlohmann/json-schema.hpp) + +# TODO: Why would this need to be if guarded? +if (JSON_VALIDATOR_SHARED_LIBS) + target_compile_definitions(nlohmann_json_schema_validator PRIVATE + -DJSON_SCHEMA_VALIDATOR_EXPORTS) +endif () + +# TODO: Consider setting minimum cxx standard instead +target_compile_features(nlohmann_json_schema_validator PUBLIC + cxx_range_for) # for C++11 - flags + +# TODO: This should be handled by the CI/presets, not the cmake +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + target_compile_options(nlohmann_json_schema_validator + PRIVATE + -Wall -Wextra -Wshadow) +endif () + +# TODO: gcc support for <4.9 should be removed +# regex with boost if gcc < 4.9 - default is std::regex +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0") + find_package(Boost COMPONENTS regex) + if (NOT Boost_FOUND) + message(STATUS "GCC less then 4.9 and boost-regex NOT found - no regex used") + target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_NO_REGEX) + else () + message(STATUS "GCC less then 4.9 and boost-regex FOUND - using boost::regex") + target_compile_definitions(nlohmann_json_schema_validator PRIVATE -DJSON_SCHEMA_BOOST_REGEX) + target_include_directories(nlohmann_json_schema_validator PRIVATE ${Boost_INCLUDE_DIRS}) + target_link_libraries(nlohmann_json_schema_validator PRIVATE ${Boost_LIBRARIES}) + endif () + endif () +endif () + +target_link_libraries(nlohmann_json_schema_validator PUBLIC + nlohmann_json::nlohmann_json) + +if (JSON_VALIDATOR_INSTALL) + # Normal installation target to system. When using scikit-build check python subdirectory + install(TARGETS nlohmann_json_schema_validator + EXPORT nlohmann_json_schema_validatorTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime + NAMELINK_COMPONENT nlohmann_json_schema_validator_Development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT nlohmann_json_schema_validator_Runtime) +endif () diff --git a/3rdparty/json-schema-validator/src/json-patch.cpp b/3rdparty/json-schema-validator/src/json-patch.cpp new file mode 100644 index 0000000000..3203543a94 --- /dev/null +++ b/3rdparty/json-schema-validator/src/json-patch.cpp @@ -0,0 +1,115 @@ +#include "json-patch.hpp" + +#include + +namespace +{ + +// originally from http://jsonpatch.com/, http://json.schemastore.org/json-patch +// with fixes +const nlohmann::json patch_schema = R"patch({ + "title": "JSON schema for JSONPatch files", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + + "items": { + "oneOf": [ + { + "additionalProperties": false, + "required": [ "value", "op", "path"], + "properties": { + "path" : { "$ref": "#/definitions/path" }, + "op": { + "description": "The operation to perform.", + "type": "string", + "enum": [ "add", "replace", "test" ] + }, + "value": { + "description": "The value to add, replace or test." + } + } + }, + { + "additionalProperties": false, + "required": [ "op", "path"], + "properties": { + "path" : { "$ref": "#/definitions/path" }, + "op": { + "description": "The operation to perform.", + "type": "string", + "enum": [ "remove" ] + } + } + }, + { + "additionalProperties": false, + "required": [ "from", "op", "path" ], + "properties": { + "path" : { "$ref": "#/definitions/path" }, + "op": { + "description": "The operation to perform.", + "type": "string", + "enum": [ "move", "copy" ] + }, + "from": { + "$ref": "#/definitions/path", + "description": "A JSON Pointer path pointing to the location to move/copy from." + } + } + } + ] + }, + "definitions": { + "path": { + "description": "A JSON Pointer path.", + "type": "string" + } + } +})patch"_json; +} // namespace + +namespace nlohmann +{ + +json_patch::json_patch(json &&patch) + : j_(std::move(patch)) +{ + validateJsonPatch(j_); +} + +json_patch::json_patch(const json &patch) + : j_(std::move(patch)) +{ + validateJsonPatch(j_); +} + +json_patch &json_patch::add(const json::json_pointer &ptr, json value) +{ + j_.push_back(json{{"op", "add"}, {"path", ptr.to_string()}, {"value", std::move(value)}}); + return *this; +} + +json_patch &json_patch::replace(const json::json_pointer &ptr, json value) +{ + j_.push_back(json{{"op", "replace"}, {"path", ptr.to_string()}, {"value", std::move(value)}}); + return *this; +} + +json_patch &json_patch::remove(const json::json_pointer &ptr) +{ + j_.push_back(json{{"op", "remove"}, {"path", ptr.to_string()}}); + return *this; +} + +void json_patch::validateJsonPatch(json const &patch) +{ + // static put here to have it created at the first usage of validateJsonPatch + static nlohmann::json_schema::json_validator patch_validator(patch_schema); + + patch_validator.validate(patch); + + for (auto const &op : patch) + json::json_pointer(op["path"].get()); +} + +} // namespace nlohmann diff --git a/3rdparty/json-schema-validator/src/json-patch.hpp b/3rdparty/json-schema-validator/src/json-patch.hpp new file mode 100644 index 0000000000..39a579b162 --- /dev/null +++ b/3rdparty/json-schema-validator/src/json-patch.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +namespace nlohmann +{ +class JsonPatchFormatException : public std::exception +{ +public: + explicit JsonPatchFormatException(std::string msg) + : ex_{std::move(msg)} {} + + inline const char *what() const noexcept override final { return ex_.c_str(); } + +private: + std::string ex_; +}; + +class json_patch +{ +public: + json_patch() = default; + json_patch(json &&patch); + json_patch(const json &patch); + + json_patch &add(const json::json_pointer &, json value); + json_patch &replace(const json::json_pointer &, json value); + json_patch &remove(const json::json_pointer &); + + json &get_json() { return j_; } + const json &get_json() const { return j_; } + + operator json() const { return j_; } + +private: + json j_ = nlohmann::json::array(); + + static void validateJsonPatch(json const &patch); +}; +} // namespace nlohmann diff --git a/3rdparty/json-schema-validator/src/json-schema-draft7.json.cpp b/3rdparty/json-schema-validator/src/json-schema-draft7.json.cpp new file mode 100644 index 0000000000..b680e2c2d2 --- /dev/null +++ b/3rdparty/json-schema-validator/src/json-schema-draft7.json.cpp @@ -0,0 +1,185 @@ +/* + * JSON schema validator for JSON for modern C++ + * + * Copyright (c) 2016-2019 Patrick Boettcher . + * + * SPDX-License-Identifier: MIT + * + */ +#include + +namespace nlohmann +{ +namespace json_schema +{ + +json draft7_schema_builtin = R"( { + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://json-schema.org/draft-07/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [ + { "$ref": "#/definitions/nonNegativeInteger" }, + { "default": 0 } + ] + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "uniqueItems": true, + "default": [] + } + }, + "type": ["object", "boolean"], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$comment": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "readOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, + "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { "$ref": "#" }, + "items": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } + ], + "default": true + }, + "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, + "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": { "$ref": "#" }, + "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, + "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { "$ref": "#" }, + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "propertyNames": { "format": "regex" }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } + }, + "propertyNames": { "$ref": "#" }, + "const": true, + "enum": { + "type": "array", + "items": true, + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": { "type": "string" }, + "contentMediaType": { "type": "string" }, + "contentEncoding": { "type": "string" }, + "if": { "$ref": "#" }, + "then": { "$ref": "#" }, + "else": { "$ref": "#" }, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "default": true +} )"_json; +} +} // namespace nlohmann diff --git a/3rdparty/json-schema-validator/src/json-uri.cpp b/3rdparty/json-schema-validator/src/json-uri.cpp new file mode 100644 index 0000000000..260255613c --- /dev/null +++ b/3rdparty/json-schema-validator/src/json-uri.cpp @@ -0,0 +1,159 @@ +/* + * JSON schema validator for JSON for modern C++ + * + * Copyright (c) 2016-2019 Patrick Boettcher . + * + * SPDX-License-Identifier: MIT + * + */ +#include + +#include + +namespace nlohmann +{ + +void json_uri::update(const std::string &uri) +{ + std::string pointer = ""; // default pointer is document-root + + // first split the URI into location and pointer + auto pointer_separator = uri.find('#'); + if (pointer_separator != std::string::npos) { // and extract the pointer-string if found + pointer = uri.substr(pointer_separator + 1); // remove # + + // unescape %-values IOW, decode JSON-URI-formatted JSON-pointer + std::size_t pos = pointer.size() - 1; + do { + pos = pointer.rfind('%', pos); + if (pos == std::string::npos) + break; + + if (pos >= pointer.size() - 2) { + pos--; + continue; + } + + std::string hex = pointer.substr(pos + 1, 2); + char ascii = static_cast(std::strtoul(hex.c_str(), nullptr, 16)); + pointer.replace(pos, 3, 1, ascii); + + pos--; + } while (1); + } + + auto location = uri.substr(0, pointer_separator); + + if (location.size()) { // a location part has been found + + // if it is an URN take it as it is + if (location.find("urn:") == 0) { + urn_ = location; + + // and clear URL members + scheme_ = ""; + authority_ = ""; + path_ = ""; + + } else { // it is an URL + + // split URL in protocol, hostname and path + std::size_t pos = 0; + auto proto = location.find("://", pos); + if (proto != std::string::npos) { // extract the protocol + + urn_ = ""; // clear URN-member if URL is parsed + + scheme_ = location.substr(pos, proto - pos); + pos = 3 + proto; // 3 == "://" + + auto authority = location.find("/", pos); + if (authority != std::string::npos) { // and the hostname (no proto without hostname) + authority_ = location.substr(pos, authority - pos); + pos = authority; + } + } + + auto path = location.substr(pos); + + // URNs cannot of have paths + if (urn_.size() && path.size()) + throw std::invalid_argument("Cannot add a path (" + path + ") to an URN URI (" + urn_ + ")"); + + if (path[0] == '/') // if it starts with a / it is root-path + path_ = path; + else if (pos == 0) { // the URL contained only a path and the current path has no / at the end, strip last element until / and append + auto last_slash = path_.rfind('/'); + path_ = path_.substr(0, last_slash) + '/' + path; + } else // otherwise it is a subfolder + path_.append(path); + } + } + + pointer_ = ""_json_pointer; + identifier_ = ""; + + if (pointer[0] == '/') + pointer_ = json::json_pointer(pointer); + else + identifier_ = pointer; +} + +std::string json_uri::location() const +{ + if (urn_.size()) + return urn_; + + std::stringstream s; + + if (scheme_.size() > 0) + s << scheme_ << "://"; + + s << authority_ + << path_; + + return s.str(); +} + +std::string json_uri::to_string() const +{ + std::stringstream s; + + s << location() << " # "; + + if (identifier_ == "") + s << pointer_.to_string(); + else + s << identifier_; + + return s.str(); +} + +std::ostream &operator<<(std::ostream &os, const json_uri &u) +{ + return os << u.to_string(); +} + +std::string json_uri::escape(const std::string &src) +{ + std::vector> chars = { + {"~", "~0"}, + {"/", "~1"}}; + + std::string l = src; + + for (const auto &c : chars) { + std::size_t pos = 0; + do { + pos = l.find(c.first, pos); + if (pos == std::string::npos) + break; + l.replace(pos, 1, c.second); + pos += c.second.size(); + } while (1); + } + + return l; +} + +} // namespace nlohmann diff --git a/3rdparty/json-schema-validator/src/json-validator.cpp b/3rdparty/json-schema-validator/src/json-validator.cpp new file mode 100644 index 0000000000..62ce97ce26 --- /dev/null +++ b/3rdparty/json-schema-validator/src/json-validator.cpp @@ -0,0 +1,1520 @@ +/* + * JSON schema validator for JSON for modern C++ + * + * Copyright (c) 2016-2019 Patrick Boettcher . + * + * SPDX-License-Identifier: MIT + * + */ +#include + +#include "json-patch.hpp" + +#include +#include +#include +#include +#include + +using nlohmann::json; +using nlohmann::json_patch; +using nlohmann::json_uri; +using nlohmann::json_schema::root_schema; +using namespace nlohmann::json_schema; + +#ifdef JSON_SCHEMA_BOOST_REGEX +# include +# define REGEX_NAMESPACE boost +#elif defined(JSON_SCHEMA_NO_REGEX) +# define NO_STD_REGEX +#else +# include +# define REGEX_NAMESPACE std +#endif + +namespace +{ + +class schema +{ +protected: + root_schema *root_; + json default_value_ = nullptr; + +protected: + virtual std::shared_ptr make_for_default_( + std::shared_ptr<::schema> & /* sch */, + root_schema * /* root */, + std::vector & /* uris */, + nlohmann::json & /* default_value */) const + { + return nullptr; + }; + +public: + virtual ~schema() = default; + + schema(root_schema *root) + : root_(root) {} + + virtual void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const = 0; + + virtual const json &default_value(const json::json_pointer &, const json &, error_handler &) const + { + return default_value_; + } + + void set_default_value(const json &v) { default_value_ = v; } + + static std::shared_ptr make(json &schema, + root_schema *root, + const std::vector &key, + std::vector uris); +}; + +class schema_ref : public schema +{ + const std::string id_; + std::weak_ptr target_; + std::shared_ptr target_strong_; // for references to references keep also the shared_ptr because + // no one else might use it after resolving + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final + { + auto target = target_.lock(); + + if (target) + target->validate(ptr, instance, patch, e); + else + e.error(ptr, instance, "unresolved or freed schema-reference " + id_); + } + + const json &default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override final + { + if (!default_value_.is_null()) + return default_value_; + + auto target = target_.lock(); + if (target) + return target->default_value(ptr, instance, e); + + e.error(ptr, instance, "unresolved or freed schema-reference " + id_); + + return default_value_; + } + +protected: + virtual std::shared_ptr make_for_default_( + std::shared_ptr<::schema> &sch, + root_schema *root, + std::vector &uris, + nlohmann::json &default_value) const override + { + // create a new reference schema using the original reference (which will be resolved later) + // to store this overloaded default value #209 + auto result = std::make_shared(uris[0].to_string(), root); + result->set_target(sch, true); + result->set_default_value(default_value); + return result; + }; + +public: + schema_ref(const std::string &id, root_schema *root) + : schema(root), id_(id) {} + + const std::string &id() const { return id_; } + + void set_target(const std::shared_ptr &target, bool strong = false) + { + target_ = target; + if (strong) + target_strong_ = target; + } +}; + +} // namespace + +namespace nlohmann +{ +namespace json_schema +{ + +class root_schema +{ + schema_loader loader_; + format_checker format_check_; + content_checker content_check_; + + std::shared_ptr root_; + + struct schema_file { + std::map> schemas; + std::map> unresolved; // contains all unresolved references from any other file seen during parsing + json unknown_keywords; + }; + + // location as key + std::map files_; + + schema_file &get_or_create_file(const std::string &loc) + { + auto file = files_.lower_bound(loc); + if (file != files_.end() && !(files_.key_comp()(loc, file->first))) + return file->second; + else + return files_.insert(file, {loc, {}})->second; + } + +public: + root_schema(schema_loader &&loader, + format_checker &&format, + content_checker &&content) + + : loader_(std::move(loader)), + format_check_(std::move(format)), + content_check_(std::move(content)) + { + } + + format_checker &format_check() { return format_check_; } + content_checker &content_check() { return content_check_; } + + void insert(const json_uri &uri, const std::shared_ptr &s) + { + auto &file = get_or_create_file(uri.location()); + auto sch = file.schemas.lower_bound(uri.fragment()); + if (sch != file.schemas.end() && !(file.schemas.key_comp()(uri.fragment(), sch->first))) { + throw std::invalid_argument("schema with " + uri.to_string() + " already inserted"); + return; + } + + file.schemas.insert({uri.fragment(), s}); + + // was someone referencing this newly inserted schema? + auto unresolved = file.unresolved.find(uri.fragment()); + if (unresolved != file.unresolved.end()) { + unresolved->second->set_target(s); + file.unresolved.erase(unresolved); + } + } + + void insert_unknown_keyword(const json_uri &uri, const std::string &key, json &value) + { + auto &file = get_or_create_file(uri.location()); + auto new_uri = uri.append(key); + auto fragment = new_uri.pointer(); + + // is there a reference looking for this unknown-keyword, which is thus no longer a unknown keyword but a schema + auto unresolved = file.unresolved.find(fragment.to_string()); + if (unresolved != file.unresolved.end()) + schema::make(value, this, {}, {{new_uri}}); + else { // no, nothing ref'd it, keep for later + + // need to create an object for each reference-token in the + // JSON-Pointer When not existing, a stringified integer reference + // token (e.g. "123") in the middle of the pointer will be + // interpreted a an array-index and an array will be created. + + // json_pointer's reference_tokens is private - get them + std::deque ref_tokens; + auto uri_pointer = uri.pointer(); + while (!uri_pointer.empty()) { + ref_tokens.push_front(uri_pointer.back()); + uri_pointer.pop_back(); + } + + // for each token create an object, if not already existing + auto unk_kw = &file.unknown_keywords; + for (auto &rt : ref_tokens) { + // create a json_pointer from rt as rt can be an stringified integer doing find on an array won't work + json::json_pointer rt_ptr{"/" + rt}; + if (unk_kw->contains(rt_ptr) == false) + (*unk_kw)[rt] = json::object(); + unk_kw = &(*unk_kw)[rt_ptr]; + } + (*unk_kw)[key] = value; + } + + // recursively add possible subschemas of unknown keywords + if (value.type() == json::value_t::object) + for (auto &subsch : value.items()) + insert_unknown_keyword(new_uri, subsch.key(), subsch.value()); + } + + std::shared_ptr get_or_create_ref(const json_uri &uri) + { + auto &file = get_or_create_file(uri.location()); + + // existing schema + auto sch = file.schemas.find(uri.fragment()); + if (sch != file.schemas.end()) + return sch->second; + + // referencing an unknown keyword, turn it into schema + // + // an unknown keyword can only be referenced by a json-pointer, + // not by a plain name fragment + if (!uri.pointer().to_string().empty()) { + bool contains_pointer = file.unknown_keywords.contains(uri.pointer()); + if (contains_pointer) { + auto &subschema = file.unknown_keywords.at(uri.pointer()); + auto s = schema::make(subschema, this, {}, {{uri}}); + if (s) { // if schema is valid (non-null) + file.unknown_keywords.erase(uri.fragment()); + return s; + } + } + } + + // get or create a schema_ref + auto r = file.unresolved.lower_bound(uri.fragment()); + if (r != file.unresolved.end() && !(file.unresolved.key_comp()(uri.fragment(), r->first))) { + return r->second; // unresolved, already seen previously - use existing reference + } else { + return file.unresolved.insert(r, + {uri.fragment(), std::make_shared(uri.to_string(), this)}) + ->second; // unresolved, create reference + } + } + + void set_root_schema(json sch) + { + files_.clear(); + root_ = schema::make(sch, this, {}, {{"#"}}); + + // load all files which have not yet been loaded + do { + bool new_schema_loaded = false; + + // files_ is modified during parsing, iterators are invalidated + std::vector locations; + for (auto &file : files_) + locations.push_back(file.first); + + for (auto &loc : locations) { + if (files_[loc].schemas.size() == 0) { // nothing has been loaded for this file + if (loader_) { + json loaded_schema; + + loader_(loc, loaded_schema); + + schema::make(loaded_schema, this, {}, {{loc}}); + new_schema_loaded = true; + } else { + throw std::invalid_argument("external schema reference '" + loc + "' needs loading, but no loader callback given"); + } + } + } + + if (!new_schema_loaded) // if no new schema loaded, no need to try again + break; + } while (1); + + for (const auto &file : files_) { + if (file.second.unresolved.size() != 0) { + // Build a representation of the undefined + // references as a list of comma-separated strings. + auto n_urefs = file.second.unresolved.size(); + std::string urefs = "["; + + decltype(n_urefs) counter = 0; + for (const auto &p : file.second.unresolved) { + urefs += p.first; + + if (counter != n_urefs - 1u) { + urefs += ", "; + } + + ++counter; + } + + urefs += "]"; + + throw std::invalid_argument("after all files have been parsed, '" + + (file.first == "" ? "" : file.first) + + "' has still the following undefined references: " + urefs); + } + } + } + + void validate(const json::json_pointer &ptr, + const json &instance, + json_patch &patch, + error_handler &e, + const json_uri &initial) const + { + if (!root_) { + e.error(ptr, "", "no root schema has yet been set for validating an instance"); + return; + } + + auto file_entry = files_.find(initial.location()); + if (file_entry == files_.end()) { + e.error(ptr, "", "no file found serving requested root-URI. " + initial.location()); + return; + } + + auto &file = file_entry->second; + auto sch = file.schemas.find(initial.fragment()); + if (sch == file.schemas.end()) { + e.error(ptr, "", "no schema find for request initial URI: " + initial.to_string()); + return; + } + + sch->second->validate(ptr, instance, patch, e); + } +}; + +} // namespace json_schema +} // namespace nlohmann + +namespace +{ + +class first_error_handler : public error_handler +{ +public: + bool error_{false}; + json::json_pointer ptr_; + json instance_; + std::string message_; + + void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override + { + if (*this) + return; + error_ = true; + ptr_ = ptr; + instance_ = instance; + message_ = message; + } + + operator bool() const { return error_; } +}; + +class logical_not : public schema +{ + std::shared_ptr subschema_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final + { + first_error_handler esub; + subschema_->validate(ptr, instance, patch, esub); + + if (!esub) + e.error(ptr, instance, "the subschema has succeeded, but it is required to not validate"); + } + + const json &default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override + { + return subschema_->default_value(ptr, instance, e); + } + +public: + logical_not(json &sch, + root_schema *root, + const std::vector &uris) + : schema(root) + { + subschema_ = schema::make(sch, root, {"not"}, uris); + } +}; + +enum logical_combination_types { + allOf, + anyOf, + oneOf +}; + +class logical_combination_error_handler : public error_handler +{ +public: + struct error_entry { + json::json_pointer ptr_; + json instance_; + std::string message_; + }; + + std::vector error_entry_list_; + + void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override + { + error_entry_list_.push_back(error_entry{ptr, instance, message}); + } + + void propagate(error_handler &e, const std::string &prefix) const + { + for (const error_entry &entry : error_entry_list_) + e.error(entry.ptr_, entry.instance_, prefix + entry.message_); + } + + operator bool() const { return !error_entry_list_.empty(); } +}; + +template +class logical_combination : public schema +{ + std::vector> subschemata_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final + { + size_t count = 0; + logical_combination_error_handler error_summary; + + for (std::size_t index = 0; index < subschemata_.size(); ++index) { + const std::shared_ptr &s = subschemata_[index]; + logical_combination_error_handler esub; + auto oldPatchSize = patch.get_json().size(); + s->validate(ptr, instance, patch, esub); + if (!esub) + count++; + else { + patch.get_json().get_ref().resize(oldPatchSize); + esub.propagate(error_summary, "case#" + std::to_string(index) + "] "); + } + + if (is_validate_complete(instance, ptr, e, esub, count, index)) + return; + } + + if (count == 0) { + e.error(ptr, instance, "no subschema has succeeded, but one of them is required to validate. Type: " + key + ", number of failed subschemas: " + std::to_string(subschemata_.size())); + error_summary.propagate(e, "[combination: " + key + " / "); + } + } + + // specialized for each of the logical_combination_types + static const std::string key; + static bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t, size_t); + +public: + logical_combination(json &sch, + root_schema *root, + const std::vector &uris) + : schema(root) + { + size_t c = 0; + for (auto &subschema : sch) + subschemata_.push_back(schema::make(subschema, root, {key, std::to_string(c++)}, uris)); + + // value of allOf, anyOf, and oneOf "MUST be a non-empty array" + // TODO error/throw? when subschemata_.empty() + } +}; + +template <> +const std::string logical_combination::key = "allOf"; +template <> +const std::string logical_combination::key = "anyOf"; +template <> +const std::string logical_combination::key = "oneOf"; + +template <> +bool logical_combination::is_validate_complete(const json &, const json::json_pointer &, error_handler &e, const logical_combination_error_handler &esub, size_t, size_t current_schema_index) +{ + if (esub) { + e.error(esub.error_entry_list_.front().ptr_, esub.error_entry_list_.front().instance_, "at least one subschema has failed, but all of them are required to validate - " + esub.error_entry_list_.front().message_); + esub.propagate(e, "[combination: allOf / case#" + std::to_string(current_schema_index) + "] "); + } + return esub; +} + +template <> +bool logical_combination::is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t count, size_t) +{ + return count == 1; +} + +template <> +bool logical_combination::is_validate_complete(const json &instance, const json::json_pointer &ptr, error_handler &e, const logical_combination_error_handler &, size_t count, size_t) +{ + if (count > 1) + e.error(ptr, instance, "more than one subschema has succeeded, but exactly one of them is required to validate"); + return count > 1; +} + +class type_schema : public schema +{ + std::vector> type_; + std::pair enum_, const_; + std::vector> logic_; + + static std::shared_ptr make(json &schema, + json::value_t type, + root_schema *, + const std::vector &, + std::set &); + + std::shared_ptr if_, then_, else_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override final + { + // depending on the type of instance run the type specific validator - if present + auto type = type_[static_cast(instance.type())]; + + if (type) + type->validate(ptr, instance, patch, e); + else + e.error(ptr, instance, "unexpected instance type"); + + if (enum_.first) { + bool seen_in_enum = false; + for (auto &v : enum_.second) + if (instance == v) { + seen_in_enum = true; + break; + } + + if (!seen_in_enum) + e.error(ptr, instance, "instance not found in required enum"); + } + + if (const_.first && + const_.second != instance) + e.error(ptr, instance, "instance not const"); + + for (auto l : logic_) + l->validate(ptr, instance, patch, e); + + if (if_) { + first_error_handler err; + + if_->validate(ptr, instance, patch, err); + if (!err) { + if (then_) + then_->validate(ptr, instance, patch, e); + } else { + if (else_) + else_->validate(ptr, instance, patch, e); + } + } + if (instance.is_null()) { + patch.add(nlohmann::json::json_pointer{}, default_value_); + } + } + +protected: + virtual std::shared_ptr make_for_default_( + std::shared_ptr<::schema> & /* sch */, + root_schema * /* root */, + std::vector & /* uris */, + nlohmann::json &default_value) const override + { + auto result = std::make_shared(*this); + result->set_default_value(default_value); + return result; + }; + +public: + type_schema(json &sch, + root_schema *root, + const std::vector &uris) + : schema(root), type_(static_cast(json::value_t::discarded) + 1) + { + // association between JSON-schema-type and NLohmann-types + static const std::vector> schema_types = { + {"null", json::value_t::null}, + {"object", json::value_t::object}, + {"array", json::value_t::array}, + {"string", json::value_t::string}, + {"boolean", json::value_t::boolean}, + {"integer", json::value_t::number_integer}, + {"number", json::value_t::number_float}, + }; + + std::set known_keywords; + + auto attr = sch.find("type"); + if (attr == sch.end()) // no type field means all sub-types possible + for (auto &t : schema_types) + type_[static_cast(t.second)] = type_schema::make(sch, t.second, root, uris, known_keywords); + else { + switch (attr.value().type()) { // "type": "type" + + case json::value_t::string: { + auto schema_type = attr.value().get(); + for (auto &t : schema_types) + if (t.first == schema_type) + type_[static_cast(t.second)] = type_schema::make(sch, t.second, root, uris, known_keywords); + } break; + + case json::value_t::array: // "type": ["type1", "type2"] + for (auto &array_value : attr.value()) { + auto schema_type = array_value.get(); + for (auto &t : schema_types) + if (t.first == schema_type) + type_[static_cast(t.second)] = type_schema::make(sch, t.second, root, uris, known_keywords); + } + break; + + default: + break; + } + + sch.erase(attr); + } + + attr = sch.find("default"); + if (attr != sch.end()) { + set_default_value(attr.value()); + sch.erase(attr); + } + + for (auto &key : known_keywords) + sch.erase(key); + + // with nlohmann::json float instance (but number in schema-definition) can be seen as unsigned or integer - + // reuse the number-validator for integer values as well, if they have not been specified explicitly + if (type_[static_cast(json::value_t::number_float)] && !type_[static_cast(json::value_t::number_integer)]) + type_[static_cast(json::value_t::number_integer)] = type_[static_cast(json::value_t::number_float)]; + + // #54: JSON-schema does not differentiate between unsigned and signed integer - nlohmann::json does + // we stick with JSON-schema: use the integer-validator if instance-value is unsigned + type_[static_cast(json::value_t::number_unsigned)] = type_[static_cast(json::value_t::number_integer)]; + + // special for binary types + if (type_[static_cast(json::value_t::string)]) { + type_[static_cast(json::value_t::binary)] = type_[static_cast(json::value_t::string)]; + } + + attr = sch.find("enum"); + if (attr != sch.end()) { + enum_ = {true, attr.value()}; + sch.erase(attr); + } + + attr = sch.find("const"); + if (attr != sch.end()) { + const_ = {true, attr.value()}; + sch.erase(attr); + } + + attr = sch.find("not"); + if (attr != sch.end()) { + logic_.push_back(std::make_shared(attr.value(), root, uris)); + sch.erase(attr); + } + + attr = sch.find("allOf"); + if (attr != sch.end()) { + logic_.push_back(std::make_shared>(attr.value(), root, uris)); + sch.erase(attr); + } + + attr = sch.find("anyOf"); + if (attr != sch.end()) { + logic_.push_back(std::make_shared>(attr.value(), root, uris)); + sch.erase(attr); + } + + attr = sch.find("oneOf"); + if (attr != sch.end()) { + logic_.push_back(std::make_shared>(attr.value(), root, uris)); + sch.erase(attr); + } + + attr = sch.find("if"); + if (attr != sch.end()) { + auto attr_then = sch.find("then"); + auto attr_else = sch.find("else"); + + if (attr_then != sch.end() || attr_else != sch.end()) { + if_ = schema::make(attr.value(), root, {"if"}, uris); + + if (attr_then != sch.end()) { + then_ = schema::make(attr_then.value(), root, {"then"}, uris); + sch.erase(attr_then); + } + + if (attr_else != sch.end()) { + else_ = schema::make(attr_else.value(), root, {"else"}, uris); + sch.erase(attr_else); + } + } + sch.erase(attr); + } + } +}; + +class string : public schema +{ + std::pair maxLength_{false, 0}; + std::pair minLength_{false, 0}; + +#ifndef NO_STD_REGEX + std::pair pattern_{false, REGEX_NAMESPACE::regex()}; + std::string patternString_; +#endif + + std::pair format_; + std::tuple content_{false, "", ""}; + + std::size_t utf8_length(const std::string &s) const + { + size_t len = 0; + for (auto c : s) + if ((c & 0xc0) != 0x80) + len++; + return len; + } + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override + { + if (minLength_.first) { + if (utf8_length(instance.get()) < minLength_.second) { + std::ostringstream s; + s << "instance is too short as per minLength:" << minLength_.second; + e.error(ptr, instance, s.str()); + } + } + + if (maxLength_.first) { + if (utf8_length(instance.get()) > maxLength_.second) { + std::ostringstream s; + s << "instance is too long as per maxLength: " << maxLength_.second; + e.error(ptr, instance, s.str()); + } + } + + if (std::get<0>(content_)) { + if (root_->content_check() == nullptr) + e.error(ptr, instance, std::string("a content checker was not provided but a contentEncoding or contentMediaType for this string have been present: '") + std::get<1>(content_) + "' '" + std::get<2>(content_) + "'"); + else { + try { + root_->content_check()(std::get<1>(content_), std::get<2>(content_), instance); + } catch (const std::exception &ex) { + e.error(ptr, instance, std::string("content-checking failed: ") + ex.what()); + } + } + } else if (instance.type() == json::value_t::binary) { + e.error(ptr, instance, "expected string, but get binary data"); + } + + if (instance.type() != json::value_t::string) { + return; // next checks only for strings + } + +#ifndef NO_STD_REGEX + if (pattern_.first && + !REGEX_NAMESPACE::regex_search(instance.get(), pattern_.second)) + e.error(ptr, instance, "instance does not match regex pattern: " + patternString_); +#endif + + if (format_.first) { + if (root_->format_check() == nullptr) + e.error(ptr, instance, std::string("a format checker was not provided but a format keyword for this string is present: ") + format_.second); + else { + try { + root_->format_check()(format_.second, instance.get()); + } catch (const std::exception &ex) { + e.error(ptr, instance, std::string("format-checking failed: ") + ex.what()); + } + } + } + } + +public: + string(json &sch, root_schema *root) + : schema(root) + { + auto attr = sch.find("maxLength"); + if (attr != sch.end()) { + maxLength_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("minLength"); + if (attr != sch.end()) { + minLength_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("contentEncoding"); + if (attr != sch.end()) { + std::get<0>(content_) = true; + std::get<1>(content_) = attr.value().get(); + + // special case for nlohmann::json-binary-types + // + // https://github.com/pboettch/json-schema-validator/pull/114 + // + // We cannot use explicitly in a schema: {"type": "binary"} or + // "type": ["binary", "number"] we have to be implicit. For a + // schema where "contentEncoding" is set to "binary", an instance + // of type json::value_t::binary is accepted. If a + // contentEncoding-callback has to be provided and is called + // accordingly. For encoding=binary, no other type validations are done + + sch.erase(attr); + } + + attr = sch.find("contentMediaType"); + if (attr != sch.end()) { + std::get<0>(content_) = true; + std::get<2>(content_) = attr.value().get(); + + sch.erase(attr); + } + + if (std::get<0>(content_) == true && root_->content_check() == nullptr) { + throw std::invalid_argument{"schema contains contentEncoding/contentMediaType but content checker was not set"}; + } + +#ifndef NO_STD_REGEX + attr = sch.find("pattern"); + if (attr != sch.end()) { + patternString_ = attr.value().get(); + pattern_ = {true, REGEX_NAMESPACE::regex(attr.value().get(), + REGEX_NAMESPACE::regex::ECMAScript)}; + sch.erase(attr); + } +#endif + + attr = sch.find("format"); + if (attr != sch.end()) { + if (root_->format_check() == nullptr) + throw std::invalid_argument{"a format checker was not provided but a format keyword for this string is present: " + format_.second}; + + format_ = {true, attr.value().get()}; + sch.erase(attr); + } + } +}; + +template +class numeric : public schema +{ + std::pair maximum_{false, 0}; + std::pair minimum_{false, 0}; + + bool exclusiveMaximum_ = false; + bool exclusiveMinimum_ = false; + + std::pair multipleOf_{false, 0}; + + // multipleOf - if the remainder of the division is 0 -> OK + bool violates_multiple_of(T x) const + { + double res = std::remainder(x, multipleOf_.second); + double multiple = std::fabs(x / multipleOf_.second); + if (multiple > 1) { + res = res / multiple; + } + double eps = std::nextafter(x, 0) - static_cast(x); + + return std::fabs(res) > std::fabs(eps); + } + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override + { + T value = instance; // conversion of json to value_type + + std::ostringstream oss; + + if (multipleOf_.first && value != 0) // zero is multiple of everything + if (violates_multiple_of(value)) + oss << "instance is not a multiple of " << json(multipleOf_.second); + + if (maximum_.first) { + if (exclusiveMaximum_ && value >= maximum_.second) + oss << "instance exceeds or equals maximum of " << json(maximum_.second); + else if (value > maximum_.second) + oss << "instance exceeds maximum of " << json(maximum_.second); + } + + if (minimum_.first) { + if (exclusiveMinimum_ && value <= minimum_.second) + oss << "instance is below or equals minimum of " << json(minimum_.second); + else if (value < minimum_.second) + oss << "instance is below minimum of " << json(minimum_.second); + } + + oss.seekp(0, std::ios::end); + auto size = oss.tellp(); + if (size != 0) { + oss.seekp(0, std::ios::beg); + e.error(ptr, instance, oss.str()); + } + } + +public: + numeric(const json &sch, root_schema *root, std::set &kw) + : schema(root) + { + auto attr = sch.find("maximum"); + if (attr != sch.end()) { + maximum_ = {true, attr.value().get()}; + kw.insert("maximum"); + } + + attr = sch.find("minimum"); + if (attr != sch.end()) { + minimum_ = {true, attr.value().get()}; + kw.insert("minimum"); + } + + attr = sch.find("exclusiveMaximum"); + if (attr != sch.end()) { + exclusiveMaximum_ = true; + maximum_ = {true, attr.value().get()}; + kw.insert("exclusiveMaximum"); + } + + attr = sch.find("exclusiveMinimum"); + if (attr != sch.end()) { + exclusiveMinimum_ = true; + minimum_ = {true, attr.value().get()}; + kw.insert("exclusiveMinimum"); + } + + attr = sch.find("multipleOf"); + if (attr != sch.end()) { + multipleOf_ = {true, attr.value().get()}; + kw.insert("multipleOf"); + } + } +}; + +class null : public schema +{ + void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override + { + if (!instance.is_null()) + e.error(ptr, instance, "expected to be null"); + } + +public: + null(json &, root_schema *root) + : schema(root) {} +}; + +class boolean_type : public schema +{ + void validate(const json::json_pointer &, const json &, json_patch &, error_handler &) const override {} + +public: + boolean_type(json &, root_schema *root) + : schema(root) {} +}; + +class boolean : public schema +{ + bool true_; + void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override + { + if (!true_) { // false schema + // empty array + // switch (instance.type()) { + // case json::value_t::array: + // if (instance.size() != 0) // valid false-schema + // e.error(ptr, instance, "false-schema required empty array"); + // return; + //} + + e.error(ptr, instance, "instance invalid as per false-schema"); + } + } + +public: + boolean(json &sch, root_schema *root) + : schema(root), true_(sch) {} +}; + +class required : public schema +{ + const std::vector required_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override final + { + for (auto &r : required_) + if (instance.find(r) == instance.end()) + e.error(ptr, instance, "required property '" + r + "' not found in object as a dependency"); + } + +public: + required(const std::vector &r, root_schema *root) + : schema(root), required_(r) {} +}; + +class object : public schema +{ + std::pair maxProperties_{false, 0}; + std::pair minProperties_{false, 0}; + std::vector required_; + + std::map> properties_; +#ifndef NO_STD_REGEX + std::vector>> patternProperties_; +#endif + std::shared_ptr additionalProperties_; + + std::map> dependencies_; + + std::shared_ptr propertyNames_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override + { + if (maxProperties_.first && instance.size() > maxProperties_.second) + e.error(ptr, instance, "too many properties"); + + if (minProperties_.first && instance.size() < minProperties_.second) + e.error(ptr, instance, "too few properties"); + + for (auto &r : required_) + if (instance.find(r) == instance.end()) + e.error(ptr, instance, "required property '" + r + "' not found in object"); + + // for each property in instance + for (auto &p : instance.items()) { + if (propertyNames_) + propertyNames_->validate(ptr, p.key(), patch, e); + + bool a_prop_or_pattern_matched = false; + auto schema_p = properties_.find(p.key()); + // check if it is in "properties" + if (schema_p != properties_.end()) { + a_prop_or_pattern_matched = true; + schema_p->second->validate(ptr / p.key(), p.value(), patch, e); + } + +#ifndef NO_STD_REGEX + // check all matching patternProperties + for (auto &schema_pp : patternProperties_) + if (REGEX_NAMESPACE::regex_search(p.key(), schema_pp.first)) { + a_prop_or_pattern_matched = true; + schema_pp.second->validate(ptr / p.key(), p.value(), patch, e); + } +#endif + + // check additionalProperties as a last resort + if (!a_prop_or_pattern_matched && additionalProperties_) { + first_error_handler additional_prop_err; + additionalProperties_->validate(ptr / p.key(), p.value(), patch, additional_prop_err); + if (additional_prop_err) + e.error(ptr, instance, "validation failed for additional property '" + p.key() + "': " + additional_prop_err.message_); + } + } + + // reverse search + for (auto const &prop : properties_) { + const auto finding = instance.find(prop.first); + if (instance.end() == finding) { // if the prop is not in the instance + const auto &default_value = prop.second->default_value(ptr, instance, e); + if (!default_value.is_null()) { // if default value is available + patch.add((ptr / prop.first), default_value); + } + } + } + + for (auto &dep : dependencies_) { + auto prop = instance.find(dep.first); + if (prop != instance.end()) // if dependency-property is present in instance + dep.second->validate(ptr / dep.first, instance, patch, e); // validate + } + } + +public: + object(json &sch, + root_schema *root, + const std::vector &uris) + : schema(root) + { + auto attr = sch.find("maxProperties"); + if (attr != sch.end()) { + maxProperties_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("minProperties"); + if (attr != sch.end()) { + minProperties_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("required"); + if (attr != sch.end()) { + required_ = attr.value().get>(); + sch.erase(attr); + } + + attr = sch.find("properties"); + if (attr != sch.end()) { + for (auto prop : attr.value().items()) + properties_.insert( + std::make_pair( + prop.key(), + schema::make(prop.value(), root, {"properties", prop.key()}, uris))); + sch.erase(attr); + } + +#ifndef NO_STD_REGEX + attr = sch.find("patternProperties"); + if (attr != sch.end()) { + for (auto prop : attr.value().items()) + patternProperties_.push_back( + std::make_pair( + REGEX_NAMESPACE::regex(prop.key(), REGEX_NAMESPACE::regex::ECMAScript), + schema::make(prop.value(), root, {prop.key()}, uris))); + sch.erase(attr); + } +#endif + + attr = sch.find("additionalProperties"); + if (attr != sch.end()) { + additionalProperties_ = schema::make(attr.value(), root, {"additionalProperties"}, uris); + sch.erase(attr); + } + + attr = sch.find("dependencies"); + if (attr != sch.end()) { + for (auto &dep : attr.value().items()) + switch (dep.value().type()) { + case json::value_t::array: + dependencies_.emplace(dep.key(), + std::make_shared( + dep.value().get>(), root)); + break; + + default: + dependencies_.emplace(dep.key(), + schema::make(dep.value(), root, {"dependencies", dep.key()}, uris)); + break; + } + sch.erase(attr); + } + + attr = sch.find("propertyNames"); + if (attr != sch.end()) { + propertyNames_ = schema::make(attr.value(), root, {"propertyNames"}, uris); + sch.erase(attr); + } + + attr = sch.find("default"); + if (attr != sch.end()) { + set_default_value(*attr); + } + } +}; + +class array : public schema +{ + std::pair maxItems_{false, 0}; + std::pair minItems_{false, 0}; + bool uniqueItems_ = false; + + std::shared_ptr items_schema_; + + std::vector> items_; + std::shared_ptr additionalItems_; + + std::shared_ptr contains_; + + void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override + { + if (maxItems_.first && instance.size() > maxItems_.second) + e.error(ptr, instance, "array has too many items"); + + if (minItems_.first && instance.size() < minItems_.second) + e.error(ptr, instance, "array has too few items"); + + if (uniqueItems_) { + for (auto it = instance.cbegin(); it != instance.cend(); ++it) { + auto v = std::find(it + 1, instance.end(), *it); + if (v != instance.end()) + e.error(ptr, instance, "items have to be unique for this array"); + } + } + + size_t index = 0; + if (items_schema_) + for (auto &i : instance) { + items_schema_->validate(ptr / index, i, patch, e); + index++; + } + else { + auto item = items_.cbegin(); + for (auto &i : instance) { + std::shared_ptr item_validator; + if (item == items_.cend()) + item_validator = additionalItems_; + else { + item_validator = *item; + item++; + } + + if (!item_validator) + break; + + item_validator->validate(ptr / index, i, patch, e); + } + } + + if (contains_) { + bool contained = false; + for (auto &item : instance) { + first_error_handler local_e; + contains_->validate(ptr, item, patch, local_e); + if (!local_e) { + contained = true; + break; + } + } + if (!contained) + e.error(ptr, instance, "array does not contain required element as per 'contains'"); + } + } + +public: + array(json &sch, root_schema *root, const std::vector &uris) + : schema(root) + { + auto attr = sch.find("maxItems"); + if (attr != sch.end()) { + maxItems_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("minItems"); + if (attr != sch.end()) { + minItems_ = {true, attr.value().get()}; + sch.erase(attr); + } + + attr = sch.find("uniqueItems"); + if (attr != sch.end()) { + uniqueItems_ = attr.value().get(); + sch.erase(attr); + } + + attr = sch.find("items"); + if (attr != sch.end()) { + + if (attr.value().type() == json::value_t::array) { + size_t c = 0; + for (auto &subsch : attr.value()) + items_.push_back(schema::make(subsch, root, {"items", std::to_string(c++)}, uris)); + + auto attr_add = sch.find("additionalItems"); + if (attr_add != sch.end()) { + additionalItems_ = schema::make(attr_add.value(), root, {"additionalItems"}, uris); + sch.erase(attr_add); + } + + } else if (attr.value().type() == json::value_t::object || + attr.value().type() == json::value_t::boolean) + items_schema_ = schema::make(attr.value(), root, {"items"}, uris); + + sch.erase(attr); + } + + attr = sch.find("contains"); + if (attr != sch.end()) { + contains_ = schema::make(attr.value(), root, {"contains"}, uris); + sch.erase(attr); + } + } +}; + +std::shared_ptr type_schema::make(json &schema, + json::value_t type, + root_schema *root, + const std::vector &uris, + std::set &kw) +{ + switch (type) { + case json::value_t::null: + return std::make_shared(schema, root); + + case json::value_t::number_unsigned: + case json::value_t::number_integer: + return std::make_shared>(schema, root, kw); + case json::value_t::number_float: + return std::make_shared>(schema, root, kw); + case json::value_t::string: + return std::make_shared(schema, root); + case json::value_t::boolean: + return std::make_shared(schema, root); + case json::value_t::object: + return std::make_shared(schema, root, uris); + case json::value_t::array: + return std::make_shared(schema, root, uris); + + case json::value_t::discarded: // not a real type - silence please + break; + + case json::value_t::binary: + break; + } + return nullptr; +} +} // namespace + +namespace +{ + +std::shared_ptr schema::make(json &schema, + root_schema *root, + const std::vector &keys, + std::vector uris) +{ + // remove URIs which contain plain name identifiers, as sub-schemas cannot be referenced + for (auto uri = uris.begin(); uri != uris.end();) + if (uri->identifier() != "") + uri = uris.erase(uri); + else + uri++; + + // append to all URIs the keys for this sub-schema + for (auto &key : keys) + for (auto &uri : uris) + uri = uri.append(key); + + std::shared_ptr<::schema> sch; + + // boolean schema + if (schema.type() == json::value_t::boolean) + sch = std::make_shared(schema, root); + else if (schema.type() == json::value_t::object) { + + auto attr = schema.find("$id"); // if $id is present, this schema can be referenced by this ID + // as an additional URI + if (attr != schema.end()) { + if (std::find(uris.begin(), + uris.end(), + attr.value().get()) == uris.end()) + uris.push_back(uris.back().derive(attr.value().get())); // so add it to the list if it is not there already + schema.erase(attr); + } + + auto findDefinitions = [&](const std::string &defs) -> bool { + attr = schema.find(defs); + if (attr != schema.end()) { + for (auto &def : attr.value().items()) + schema::make(def.value(), root, {defs, def.key()}, uris); + schema.erase(attr); + return true; + } + return false; + }; + if (!findDefinitions("$defs")) { + findDefinitions("definitions"); + } + + attr = schema.find("$ref"); + if (attr != schema.end()) { // this schema is a reference + // the last one on the uri-stack is the last id seen before coming here, + // so this is the origial URI for this reference, the $ref-value has thus be resolved from it + auto id = uris.back().derive(attr.value().get()); + sch = root->get_or_create_ref(id); + + schema.erase(attr); + + // special case where we break draft-7 and allow overriding of properties when a $ref is used + attr = schema.find("default"); + if (attr != schema.end()) { + // copy the referenced schema depending on the underlying type and modify the default value + if (auto new_sch = sch->make_for_default_(sch, root, uris, attr.value())) { + sch = new_sch; + } + schema.erase(attr); + } + } else { + sch = std::make_shared(schema, root, uris); + } + + schema.erase("$schema"); + schema.erase("title"); + schema.erase("description"); + } else { + throw std::invalid_argument("invalid JSON-type for a schema for " + uris[0].to_string() + ", expected: boolean or object"); + } + + for (auto &uri : uris) { // for all URIs this schema is referenced by + root->insert(uri, sch); + + if (schema.type() == json::value_t::object) + for (auto &u : schema.items()) + root->insert_unknown_keyword(uri, u.key(), u.value()); // insert unknown keywords for later reference + } + return sch; +} + +class throwing_error_handler : public error_handler +{ + void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override + { + throw std::invalid_argument(std::string("At ") + ptr.to_string() + " of " + instance.dump() + " - " + message + "\n"); + } +}; + +} // namespace + +namespace nlohmann +{ +namespace json_schema +{ + +json_validator::json_validator(schema_loader loader, + format_checker format, + content_checker content) + : root_(std::unique_ptr(new root_schema(std::move(loader), + std::move(format), + std::move(content)))) +{ +} + +json_validator::json_validator(const json &schema, + schema_loader loader, + format_checker format, + content_checker content) + : json_validator(std::move(loader), + std::move(format), + std::move(content)) +{ + set_root_schema(schema); +} + +json_validator::json_validator(json &&schema, + schema_loader loader, + format_checker format, + content_checker content) + + : json_validator(std::move(loader), + std::move(format), + std::move(content)) +{ + set_root_schema(std::move(schema)); +} + +// move constructor, destructor and move assignment operator can be defaulted here +// where root_schema is a complete type +json_validator::json_validator(json_validator &&) = default; +json_validator::~json_validator() = default; +json_validator &json_validator::operator=(json_validator &&) = default; + +void json_validator::set_root_schema(const json &schema) +{ + root_->set_root_schema(schema); +} + +void json_validator::set_root_schema(json &&schema) +{ + root_->set_root_schema(std::move(schema)); +} + +json json_validator::validate(const json &instance) const +{ + throwing_error_handler err; + return validate(instance, err); +} + +json json_validator::validate(const json &instance, error_handler &err, const json_uri &initial_uri) const +{ + json::json_pointer ptr; + json_patch patch; + root_->validate(ptr, instance, patch, err, initial_uri); + return patch; +} + +} // namespace json_schema +} // namespace nlohmann diff --git a/3rdparty/json-schema-validator/src/nlohmann/json-schema.hpp b/3rdparty/json-schema-validator/src/nlohmann/json-schema.hpp new file mode 100644 index 0000000000..07befd3472 --- /dev/null +++ b/3rdparty/json-schema-validator/src/nlohmann/json-schema.hpp @@ -0,0 +1,198 @@ +/* + * JSON schema validator for JSON for modern C++ + * + * Copyright (c) 2016-2019 Patrick Boettcher . + * + * SPDX-License-Identifier: MIT + * + */ +#ifndef NLOHMANN_JSON_SCHEMA_HPP__ +#define NLOHMANN_JSON_SCHEMA_HPP__ + +#ifdef _WIN32 +# if defined(JSON_SCHEMA_VALIDATOR_EXPORTS) +# define JSON_SCHEMA_VALIDATOR_API __declspec(dllexport) +# elif defined(JSON_SCHEMA_VALIDATOR_IMPORTS) +# define JSON_SCHEMA_VALIDATOR_API __declspec(dllimport) +# else +# define JSON_SCHEMA_VALIDATOR_API +# endif +#else +# define JSON_SCHEMA_VALIDATOR_API +#endif + +#include + +#ifdef NLOHMANN_JSON_VERSION_MAJOR +# if (NLOHMANN_JSON_VERSION_MAJOR * 10000 + NLOHMANN_JSON_VERSION_MINOR * 100 + NLOHMANN_JSON_VERSION_PATCH) < 30800 +# error "Please use this library with NLohmann's JSON version 3.8.0 or higher" +# endif +#else +# error "expected existing NLOHMANN_JSON_VERSION_MAJOR preproc variable, please update to NLohmann's JSON 3.8.0" +#endif + +// make yourself a home - welcome to nlohmann's namespace +namespace nlohmann +{ + +// A class representing a JSON-URI for schemas derived from +// section 8 of JSON Schema: A Media Type for Describing JSON Documents +// draft-wright-json-schema-00 +// +// New URIs can be derived from it using the derive()-method. +// This is useful for resolving refs or subschema-IDs in json-schemas. +// +// This is done implement the requirements described in section 8.2. +// +class JSON_SCHEMA_VALIDATOR_API json_uri +{ + std::string urn_; + + std::string scheme_; + std::string authority_; + std::string path_; + + json::json_pointer pointer_; // fragment part if JSON-Pointer + std::string identifier_; // fragment part if Locatation Independent ID + +protected: + // decodes a JSON uri and replaces all or part of the currently stored values + void update(const std::string &uri); + + std::tuple as_tuple() const + { + return std::make_tuple(urn_, scheme_, authority_, path_, identifier_ != "" ? identifier_ : pointer_.to_string()); + } + +public: + json_uri(const std::string &uri) + { + update(uri); + } + + const std::string &scheme() const { return scheme_; } + const std::string &authority() const { return authority_; } + const std::string &path() const { return path_; } + + const json::json_pointer &pointer() const { return pointer_; } + const std::string &identifier() const { return identifier_; } + + std::string fragment() const + { + if (identifier_ == "") + return pointer_.to_string(); + else + return identifier_; + } + + std::string url() const { return location(); } + std::string location() const; + + static std::string escape(const std::string &); + + // create a new json_uri based in this one and the given uri + // resolves relative changes (pathes or pointers) and resets part if proto or hostname changes + json_uri derive(const std::string &uri) const + { + json_uri u = *this; + u.update(uri); + return u; + } + + // append a pointer-field to the pointer-part of this uri + json_uri append(const std::string &field) const + { + if (identifier_ != "") + return *this; + + json_uri u = *this; + u.pointer_ /= field; + return u; + } + + std::string to_string() const; + + friend bool operator<(const json_uri &l, const json_uri &r) + { + return l.as_tuple() < r.as_tuple(); + } + + friend bool operator==(const json_uri &l, const json_uri &r) + { + return l.as_tuple() == r.as_tuple(); + } + + friend std::ostream &operator<<(std::ostream &os, const json_uri &u); +}; + +namespace json_schema +{ + +extern json draft7_schema_builtin; + +typedef std::function schema_loader; +typedef std::function format_checker; +typedef std::function content_checker; + +// Interface for validation error handlers +class JSON_SCHEMA_VALIDATOR_API error_handler +{ +public: + virtual ~error_handler() {} + virtual void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) = 0; +}; + +class JSON_SCHEMA_VALIDATOR_API basic_error_handler : public error_handler +{ + bool error_{false}; + +public: + void error(const json::json_pointer & /*ptr*/, const json & /*instance*/, const std::string & /*message*/) override + { + error_ = true; + } + + virtual void reset() { error_ = false; } + operator bool() const { return error_; } +}; + +/** + * Checks validity of JSON schema built-in string format specifiers like 'date-time', 'ipv4', ... + */ +void JSON_SCHEMA_VALIDATOR_API default_string_format_check(const std::string &format, const std::string &value); + +class root_schema; + +class JSON_SCHEMA_VALIDATOR_API json_validator +{ + std::unique_ptr root_; + +public: + json_validator(schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr); + + json_validator(const json &, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr); + json_validator(json &&, schema_loader = nullptr, format_checker = nullptr, content_checker = nullptr); + + json_validator(json_validator &&); + json_validator &operator=(json_validator &&); + + json_validator(json_validator const &) = delete; + json_validator &operator=(json_validator const &) = delete; + + ~json_validator(); + + // insert and set the root-schema + void set_root_schema(const json &); + void set_root_schema(json &&); + + // validate a json-document based on the root-schema + json validate(const json &) const; + + // validate a json-document based on the root-schema with a custom error-handler + json validate(const json &, error_handler &, const json_uri &initial_uri = json_uri("#")) const; +}; + +} // namespace json_schema +} // namespace nlohmann + +#endif /* NLOHMANN_JSON_SCHEMA_HPP__ */ diff --git a/3rdparty/json-schema-validator/src/smtp-address-validator.cpp b/3rdparty/json-schema-validator/src/smtp-address-validator.cpp new file mode 100644 index 0000000000..3b4a461268 --- /dev/null +++ b/3rdparty/json-schema-validator/src/smtp-address-validator.cpp @@ -0,0 +1,792 @@ +/* + +Snarfed from + +: + +Copyright (c) 2021 Gene Hightower + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#include "smtp-address-validator.hpp" + +static const signed char _address_actions[] = { + 0, 1, 0, 1, 1, 0}; + +static const short _address_key_offsets[] = { + 0, 0, 24, 26, 50, 52, 54, 56, + 58, 60, 62, 86, 103, 105, 107, 109, + 111, 113, 115, 117, 134, 150, 161, 168, + 176, 180, 181, 190, 195, 196, 201, 202, + 207, 210, 213, 219, 222, 225, 228, 234, + 237, 240, 243, 249, 252, 261, 270, 282, + 293, 302, 311, 320, 328, 345, 353, 360, + 367, 368, 375, 382, 389, 396, 397, 404, + 411, 418, 425, 426, 433, 440, 447, 454, + 455, 462, 469, 476, 483, 484, 491, 498, + 505, 512, 513, 523, 531, 538, 545, 546, + 552, 559, 566, 573, 581, 589, 597, 608, + 618, 626, 634, 641, 649, 657, 665, 667, + 673, 681, 689, 697, 699, 705, 713, 721, + 729, 731, 737, 745, 753, 761, 763, 769, + 777, 785, 793, 795, 802, 812, 821, 829, + 837, 839, 848, 857, 865, 873, 875, 884, + 893, 901, 909, 911, 920, 929, 937, 945, + 947, 956, 965, 974, 983, 992, 1004, 1015, + 1024, 1033, 1042, 1051, 1060, 1072, 1083, 1092, + 1101, 1109, 1118, 1127, 1136, 1148, 1159, 1168, + 1177, 1185, 1194, 1203, 1212, 1224, 1235, 1244, + 1253, 1261, 1270, 1279, 1288, 1300, 1311, 1320, + 1329, 1337, 1339, 1353, 1355, 1357, 1359, 1361, + 1363, 1365, 1367, 1368, 1370, 1388, 0}; + +static const signed char _address_trans_keys[] = { + -32, -19, -16, -12, 34, 45, 61, 63, + -62, -33, -31, -17, -15, -13, 33, 39, + 42, 43, 47, 57, 65, 90, 94, 126, + -128, -65, -32, -19, -16, -12, 33, 46, + 61, 64, -62, -33, -31, -17, -15, -13, + 35, 39, 42, 43, 45, 57, 63, 90, + 94, 126, -96, -65, -128, -65, -128, -97, + -112, -65, -128, -65, -128, -113, -32, -19, + -16, -12, 33, 45, 61, 63, -62, -33, + -31, -17, -15, -13, 35, 39, 42, 43, + 47, 57, 65, 90, 94, 126, -32, -19, + -16, -12, 91, -62, -33, -31, -17, -15, + -13, 48, 57, 65, 90, 97, 122, -128, + -65, -96, -65, -128, -65, -128, -97, -112, + -65, -128, -65, -128, -113, -32, -19, -16, + -12, 45, -62, -33, -31, -17, -15, -13, + 48, 57, 65, 90, 97, 122, -32, -19, + -16, -12, -62, -33, -31, -17, -15, -13, + 48, 57, 65, 90, 97, 122, 45, 48, + 49, 50, 73, 51, 57, 65, 90, 97, + 122, 45, 48, 57, 65, 90, 97, 122, + 45, 58, 48, 57, 65, 90, 97, 122, + 33, 90, 94, 126, 93, 45, 46, 58, + 48, 57, 65, 90, 97, 122, 48, 49, + 50, 51, 57, 46, 48, 49, 50, 51, + 57, 46, 48, 49, 50, 51, 57, 93, + 48, 57, 93, 48, 57, 53, 93, 48, + 52, 54, 57, 93, 48, 53, 46, 48, + 57, 46, 48, 57, 46, 53, 48, 52, + 54, 57, 46, 48, 53, 46, 48, 57, + 46, 48, 57, 46, 53, 48, 52, 54, + 57, 46, 48, 53, 45, 46, 58, 48, + 57, 65, 90, 97, 122, 45, 46, 58, + 48, 57, 65, 90, 97, 122, 45, 46, + 53, 58, 48, 52, 54, 57, 65, 90, + 97, 122, 45, 46, 58, 48, 53, 54, + 57, 65, 90, 97, 122, 45, 58, 80, + 48, 57, 65, 90, 97, 122, 45, 58, + 118, 48, 57, 65, 90, 97, 122, 45, + 54, 58, 48, 57, 65, 90, 97, 122, + 45, 58, 48, 57, 65, 90, 97, 122, + 58, 33, 47, 48, 57, 59, 64, 65, + 70, 71, 90, 94, 96, 97, 102, 103, + 126, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 48, 57, 65, 70, 97, 102, + 58, 48, 57, 65, 70, 97, 102, 58, + 58, 48, 57, 65, 70, 97, 102, 58, + 48, 57, 65, 70, 97, 102, 58, 48, + 57, 65, 70, 97, 102, 58, 48, 57, + 65, 70, 97, 102, 58, 58, 48, 57, + 65, 70, 97, 102, 58, 48, 57, 65, + 70, 97, 102, 58, 48, 57, 65, 70, + 97, 102, 58, 48, 57, 65, 70, 97, + 102, 58, 58, 48, 57, 65, 70, 97, + 102, 58, 48, 57, 65, 70, 97, 102, + 58, 48, 57, 65, 70, 97, 102, 58, + 48, 57, 65, 70, 97, 102, 58, 58, + 48, 57, 65, 70, 97, 102, 58, 48, + 57, 65, 70, 97, 102, 58, 48, 57, + 65, 70, 97, 102, 58, 48, 57, 65, + 70, 97, 102, 58, 58, 48, 57, 65, + 70, 97, 102, 58, 48, 57, 65, 70, + 97, 102, 58, 48, 57, 65, 70, 97, + 102, 58, 48, 57, 65, 70, 97, 102, + 58, 48, 49, 50, 58, 51, 57, 65, + 70, 97, 102, 46, 58, 48, 57, 65, + 70, 97, 102, 58, 48, 57, 65, 70, + 97, 102, 58, 48, 57, 65, 70, 97, + 102, 58, 48, 57, 65, 70, 97, 102, + 93, 48, 57, 65, 70, 97, 102, 93, + 48, 57, 65, 70, 97, 102, 93, 48, + 57, 65, 70, 97, 102, 46, 58, 48, + 57, 65, 70, 97, 102, 46, 58, 48, + 57, 65, 70, 97, 102, 46, 58, 48, + 57, 65, 70, 97, 102, 46, 53, 58, + 48, 52, 54, 57, 65, 70, 97, 102, + 46, 58, 48, 53, 54, 57, 65, 70, + 97, 102, 46, 58, 48, 57, 65, 70, + 97, 102, 46, 58, 48, 57, 65, 70, + 97, 102, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 58, 48, 57, 65, 70, + 97, 102, 48, 49, 50, 93, 51, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 49, 50, 51, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 49, 50, 51, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 49, 50, 51, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 49, 50, 51, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 57, 65, 70, 97, 102, 46, 58, 93, + 48, 57, 65, 70, 97, 102, 46, 58, + 93, 48, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 53, 58, 93, 48, 52, 54, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 53, 54, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 57, 65, 70, 97, + 102, 46, 58, 93, 48, 57, 65, 70, + 97, 102, 46, 58, 93, 48, 57, 65, + 70, 97, 102, 46, 58, 93, 48, 57, + 65, 70, 97, 102, 46, 53, 58, 93, + 48, 52, 54, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 53, 54, 57, 65, + 70, 97, 102, 46, 58, 93, 48, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 46, 58, 93, + 48, 57, 65, 70, 97, 102, 46, 58, + 93, 48, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 53, 58, 93, 48, 52, 54, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 53, 54, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 46, 58, 93, 48, 57, 65, 70, + 97, 102, 46, 58, 93, 48, 57, 65, + 70, 97, 102, 46, 58, 93, 48, 57, + 65, 70, 97, 102, 46, 53, 58, 93, + 48, 52, 54, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 53, 54, 57, 65, + 70, 97, 102, 46, 58, 93, 48, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 57, 65, 70, 97, 102, 58, 93, 48, + 57, 65, 70, 97, 102, 46, 58, 93, + 48, 57, 65, 70, 97, 102, 46, 58, + 93, 48, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 53, 58, 93, 48, 52, 54, 57, + 65, 70, 97, 102, 46, 58, 93, 48, + 53, 54, 57, 65, 70, 97, 102, 46, + 58, 93, 48, 57, 65, 70, 97, 102, + 46, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, 48, 57, 65, 70, 97, + 102, 58, 93, -32, -19, -16, -12, 34, + 92, -62, -33, -31, -17, -15, -13, 32, + 126, -128, -65, -96, -65, -128, -65, -128, + -97, -112, -65, -128, -65, -128, -113, 64, + 32, 126, -32, -19, -16, -12, 45, 46, + -62, -33, -31, -17, -15, -13, 48, 57, + 65, 90, 97, 122, 0}; + +static const signed char _address_single_lengths[] = { + 0, 8, 0, 8, 0, 0, 0, 0, + 0, 0, 8, 5, 0, 0, 0, 0, + 0, 0, 0, 5, 4, 5, 1, 2, + 0, 1, 3, 3, 1, 3, 1, 3, + 1, 1, 2, 1, 1, 1, 2, 1, + 1, 1, 2, 1, 3, 3, 4, 3, + 3, 3, 3, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 2, 1, 1, 1, 0, + 1, 1, 1, 2, 2, 2, 3, 2, + 2, 2, 1, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 0, 2, 2, 2, + 2, 0, 2, 2, 2, 2, 0, 2, + 2, 2, 2, 1, 4, 3, 2, 2, + 2, 3, 3, 2, 2, 2, 3, 3, + 2, 2, 2, 3, 3, 2, 2, 2, + 3, 3, 3, 3, 3, 4, 3, 3, + 3, 3, 3, 3, 4, 3, 3, 3, + 2, 3, 3, 3, 4, 3, 3, 3, + 2, 3, 3, 3, 4, 3, 3, 3, + 2, 3, 3, 3, 4, 3, 3, 3, + 2, 2, 6, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 6, 0, 0}; + +static const signed char _address_range_lengths[] = { + 0, 8, 1, 8, 1, 1, 1, 1, + 1, 1, 8, 6, 1, 1, 1, 1, + 1, 1, 1, 6, 6, 3, 3, 3, + 2, 0, 3, 1, 0, 1, 0, 1, + 1, 1, 2, 1, 1, 1, 2, 1, + 1, 1, 2, 1, 3, 3, 4, 4, + 3, 3, 3, 3, 8, 3, 3, 3, + 0, 3, 3, 3, 3, 0, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 0, + 3, 3, 3, 3, 0, 3, 3, 3, + 3, 0, 3, 3, 3, 3, 0, 3, + 3, 3, 3, 3, 3, 3, 4, 4, + 3, 3, 3, 3, 3, 3, 0, 3, + 3, 3, 3, 0, 3, 3, 3, 3, + 0, 3, 3, 3, 3, 0, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, + 0, 3, 3, 3, 3, 0, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 0, + 3, 3, 3, 3, 3, 4, 4, 3, + 3, 3, 3, 3, 4, 4, 3, 3, + 3, 3, 3, 3, 4, 4, 3, 3, + 3, 3, 3, 3, 4, 4, 3, 3, + 3, 3, 3, 3, 4, 4, 3, 3, + 3, 0, 4, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 6, 0, 0}; + +static const short _address_index_offsets[] = { + 0, 0, 17, 19, 36, 38, 40, 42, + 44, 46, 48, 65, 77, 79, 81, 83, + 85, 87, 89, 91, 103, 114, 123, 128, + 134, 137, 139, 146, 151, 153, 158, 160, + 165, 168, 171, 176, 179, 182, 185, 190, + 193, 196, 199, 204, 207, 214, 221, 230, + 238, 245, 252, 259, 265, 275, 281, 286, + 291, 293, 298, 303, 308, 313, 315, 320, + 325, 330, 335, 337, 342, 347, 352, 357, + 359, 364, 369, 374, 379, 381, 386, 391, + 396, 401, 403, 411, 417, 422, 427, 429, + 433, 438, 443, 448, 454, 460, 466, 474, + 481, 487, 493, 498, 504, 510, 516, 519, + 523, 529, 535, 541, 544, 548, 554, 560, + 566, 569, 573, 579, 585, 591, 594, 598, + 604, 610, 616, 619, 624, 632, 639, 645, + 651, 654, 661, 668, 674, 680, 683, 690, + 697, 703, 709, 712, 719, 726, 732, 738, + 741, 748, 755, 762, 769, 776, 785, 793, + 800, 807, 814, 821, 828, 837, 845, 852, + 859, 865, 872, 879, 886, 895, 903, 910, + 917, 923, 930, 937, 944, 953, 961, 968, + 975, 981, 988, 995, 1002, 1011, 1019, 1026, + 1033, 1039, 1042, 1053, 1055, 1057, 1059, 1061, + 1063, 1065, 1067, 1069, 1071, 1084, 0}; + +static const short _address_cond_targs[] = { + 4, 6, 7, 9, 186, 3, 3, 3, + 2, 5, 8, 3, 3, 3, 3, 3, + 0, 3, 0, 4, 6, 7, 9, 3, + 10, 3, 11, 2, 5, 8, 3, 3, + 3, 3, 3, 0, 2, 0, 2, 0, + 2, 0, 5, 0, 5, 0, 5, 0, + 4, 6, 7, 9, 3, 3, 3, 3, + 2, 5, 8, 3, 3, 3, 3, 3, + 0, 13, 15, 16, 18, 21, 12, 14, + 17, 196, 196, 196, 0, 196, 0, 12, + 0, 12, 0, 12, 0, 14, 0, 14, + 0, 14, 0, 13, 15, 16, 18, 19, + 12, 14, 17, 196, 196, 196, 0, 13, + 15, 16, 18, 12, 14, 17, 196, 196, + 196, 0, 22, 26, 44, 46, 48, 45, + 23, 23, 0, 22, 23, 23, 23, 0, + 22, 24, 23, 23, 23, 0, 25, 25, + 0, 197, 0, 22, 27, 24, 23, 23, + 23, 0, 28, 40, 42, 41, 0, 29, + 0, 30, 36, 38, 37, 0, 31, 0, + 25, 32, 34, 33, 0, 197, 33, 0, + 197, 25, 0, 35, 197, 33, 25, 0, + 197, 25, 0, 31, 37, 0, 31, 30, + 0, 31, 39, 37, 30, 0, 31, 30, + 0, 29, 41, 0, 29, 28, 0, 29, + 43, 41, 28, 0, 29, 28, 0, 22, + 27, 24, 45, 23, 23, 0, 22, 27, + 24, 26, 23, 23, 0, 22, 27, 47, + 24, 45, 26, 23, 23, 0, 22, 27, + 24, 26, 23, 23, 23, 0, 22, 24, + 49, 23, 23, 23, 0, 22, 24, 50, + 23, 23, 23, 0, 22, 51, 24, 23, + 23, 23, 0, 22, 52, 23, 23, 23, + 0, 185, 25, 53, 25, 53, 25, 25, + 53, 25, 0, 57, 197, 54, 54, 54, + 0, 57, 55, 55, 55, 0, 57, 56, + 56, 56, 0, 57, 0, 124, 58, 58, + 58, 0, 62, 59, 59, 59, 0, 62, + 60, 60, 60, 0, 62, 61, 61, 61, + 0, 62, 0, 124, 63, 63, 63, 0, + 67, 64, 64, 64, 0, 67, 65, 65, + 65, 0, 67, 66, 66, 66, 0, 67, + 0, 124, 68, 68, 68, 0, 72, 69, + 69, 69, 0, 72, 70, 70, 70, 0, + 72, 71, 71, 71, 0, 72, 0, 124, + 73, 73, 73, 0, 77, 74, 74, 74, + 0, 77, 75, 75, 75, 0, 77, 76, + 76, 76, 0, 77, 0, 98, 78, 78, + 78, 0, 82, 79, 79, 79, 0, 82, + 80, 80, 80, 0, 82, 81, 81, 81, + 0, 82, 0, 83, 91, 94, 98, 97, + 123, 123, 0, 27, 87, 84, 84, 84, + 0, 87, 85, 85, 85, 0, 87, 86, + 86, 86, 0, 87, 0, 88, 88, 88, + 0, 197, 89, 89, 89, 0, 197, 90, + 90, 90, 0, 197, 25, 25, 25, 0, + 27, 87, 92, 84, 84, 0, 27, 87, + 93, 85, 85, 0, 27, 87, 86, 86, + 86, 0, 27, 95, 87, 92, 96, 84, + 84, 0, 27, 87, 93, 85, 85, 85, + 0, 27, 87, 85, 85, 85, 0, 27, + 87, 96, 84, 84, 0, 197, 99, 99, + 99, 0, 103, 197, 100, 100, 100, 0, + 103, 197, 101, 101, 101, 0, 103, 197, + 102, 102, 102, 0, 103, 197, 0, 104, + 104, 104, 0, 108, 197, 105, 105, 105, + 0, 108, 197, 106, 106, 106, 0, 108, + 197, 107, 107, 107, 0, 108, 197, 0, + 109, 109, 109, 0, 113, 197, 110, 110, + 110, 0, 113, 197, 111, 111, 111, 0, + 113, 197, 112, 112, 112, 0, 113, 197, + 0, 114, 114, 114, 0, 118, 197, 115, + 115, 115, 0, 118, 197, 116, 116, 116, + 0, 118, 197, 117, 117, 117, 0, 118, + 197, 0, 119, 119, 119, 0, 87, 197, + 120, 120, 120, 0, 87, 197, 121, 121, + 121, 0, 87, 197, 122, 122, 122, 0, + 87, 197, 0, 87, 84, 84, 84, 0, + 125, 177, 180, 197, 183, 184, 184, 0, + 27, 129, 197, 126, 126, 126, 0, 129, + 197, 127, 127, 127, 0, 129, 197, 128, + 128, 128, 0, 129, 197, 0, 130, 169, + 172, 175, 176, 176, 0, 27, 134, 197, + 131, 131, 131, 0, 134, 197, 132, 132, + 132, 0, 134, 197, 133, 133, 133, 0, + 134, 197, 0, 135, 161, 164, 167, 168, + 168, 0, 27, 139, 197, 136, 136, 136, + 0, 139, 197, 137, 137, 137, 0, 139, + 197, 138, 138, 138, 0, 139, 197, 0, + 140, 153, 156, 159, 160, 160, 0, 27, + 144, 197, 141, 141, 141, 0, 144, 197, + 142, 142, 142, 0, 144, 197, 143, 143, + 143, 0, 144, 197, 0, 145, 146, 149, + 152, 119, 119, 0, 27, 87, 197, 120, + 120, 120, 0, 27, 87, 197, 147, 120, + 120, 0, 27, 87, 197, 148, 121, 121, + 0, 27, 87, 197, 122, 122, 122, 0, + 27, 150, 87, 197, 147, 151, 120, 120, + 0, 27, 87, 197, 148, 121, 121, 121, + 0, 27, 87, 197, 121, 121, 121, 0, + 27, 87, 197, 151, 120, 120, 0, 27, + 144, 197, 154, 141, 141, 0, 27, 144, + 197, 155, 142, 142, 0, 27, 144, 197, + 143, 143, 143, 0, 27, 157, 144, 197, + 154, 158, 141, 141, 0, 27, 144, 197, + 155, 142, 142, 142, 0, 27, 144, 197, + 142, 142, 142, 0, 27, 144, 197, 158, + 141, 141, 0, 144, 197, 141, 141, 141, + 0, 27, 139, 197, 162, 136, 136, 0, + 27, 139, 197, 163, 137, 137, 0, 27, + 139, 197, 138, 138, 138, 0, 27, 165, + 139, 197, 162, 166, 136, 136, 0, 27, + 139, 197, 163, 137, 137, 137, 0, 27, + 139, 197, 137, 137, 137, 0, 27, 139, + 197, 166, 136, 136, 0, 139, 197, 136, + 136, 136, 0, 27, 134, 197, 170, 131, + 131, 0, 27, 134, 197, 171, 132, 132, + 0, 27, 134, 197, 133, 133, 133, 0, + 27, 173, 134, 197, 170, 174, 131, 131, + 0, 27, 134, 197, 171, 132, 132, 132, + 0, 27, 134, 197, 132, 132, 132, 0, + 27, 134, 197, 174, 131, 131, 0, 134, + 197, 131, 131, 131, 0, 27, 129, 197, + 178, 126, 126, 0, 27, 129, 197, 179, + 127, 127, 0, 27, 129, 197, 128, 128, + 128, 0, 27, 181, 129, 197, 178, 182, + 126, 126, 0, 27, 129, 197, 179, 127, + 127, 127, 0, 27, 129, 197, 127, 127, + 127, 0, 27, 129, 197, 182, 126, 126, + 0, 129, 197, 126, 126, 126, 0, 124, + 197, 0, 188, 190, 191, 193, 194, 195, + 187, 189, 192, 186, 0, 186, 0, 187, + 0, 187, 0, 187, 0, 189, 0, 189, + 0, 189, 0, 11, 0, 186, 0, 13, + 15, 16, 18, 19, 20, 12, 14, 17, + 196, 196, 196, 0, 0, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 0}; + +static const signed char _address_cond_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 3, 0, 3, + 0, 3, 0, 3, 0, 3, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 3, 1, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 3, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 3, 0, 0, + 3, 1, 3, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 3, 0, + 3, 0, 0, 0, 0, 3, 0, 3, + 0, 0, 0, 0, 3, 1, 0, 3, + 1, 0, 3, 0, 1, 0, 0, 3, + 1, 0, 3, 0, 0, 3, 0, 0, + 3, 0, 0, 0, 0, 3, 0, 0, + 3, 0, 0, 3, 0, 0, 3, 0, + 0, 0, 0, 3, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 3, 0, 3, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 3, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 3, 0, + 3, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 3, 0, 3, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 3, 0, 3, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 3, 0, 3, 0, 0, 0, + 3, 1, 0, 0, 0, 3, 1, 0, + 0, 0, 3, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 3, 1, 0, 0, + 0, 3, 0, 1, 0, 0, 0, 3, + 0, 1, 0, 0, 0, 3, 0, 1, + 0, 0, 0, 3, 0, 1, 3, 0, + 0, 0, 3, 0, 1, 0, 0, 0, + 3, 0, 1, 0, 0, 0, 3, 0, + 1, 0, 0, 0, 3, 0, 1, 3, + 0, 0, 0, 3, 0, 1, 0, 0, + 0, 3, 0, 1, 0, 0, 0, 3, + 0, 1, 0, 0, 0, 3, 0, 1, + 3, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 3, 0, 1, 0, 0, 0, + 3, 0, 1, 0, 0, 0, 3, 0, + 1, 3, 0, 0, 0, 3, 0, 1, + 0, 0, 0, 3, 0, 1, 0, 0, + 0, 3, 0, 1, 0, 0, 0, 3, + 0, 1, 3, 0, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 1, 0, 0, 0, 3, 0, + 1, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 3, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 1, + 0, 0, 0, 3, 0, 1, 0, 0, + 0, 3, 0, 1, 0, 0, 0, 3, + 0, 1, 3, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 1, 0, 0, 0, + 3, 0, 1, 0, 0, 0, 3, 0, + 1, 0, 0, 0, 3, 0, 1, 3, + 0, 0, 0, 0, 0, 0, 3, 0, + 0, 1, 0, 0, 0, 3, 0, 1, + 0, 0, 0, 3, 0, 1, 0, 0, + 0, 3, 0, 1, 3, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 1, 0, 0, 0, 3, 0, + 0, 1, 0, 0, 0, 3, 0, 0, + 1, 0, 0, 0, 3, 0, 0, 1, + 0, 0, 0, 3, 0, 0, 0, 1, + 0, 0, 0, 0, 3, 0, 0, 1, + 0, 0, 0, 0, 3, 0, 0, 1, + 0, 0, 0, 3, 0, 0, 1, 0, + 0, 0, 3, 0, 1, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 1, 0, 0, 0, 3, 0, + 0, 1, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 0, 3, 0, + 0, 1, 0, 0, 0, 0, 3, 0, + 0, 1, 0, 0, 0, 3, 0, 0, + 1, 0, 0, 0, 3, 0, 1, 0, + 0, 0, 3, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 1, 0, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 0, + 3, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 1, 0, 0, 0, 3, 0, + 1, 0, 0, 0, 3, 0, 0, 1, + 0, 0, 0, 3, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 0, 1, 0, 0, + 0, 0, 3, 0, 0, 1, 0, 0, + 0, 0, 3, 0, 0, 1, 0, 0, + 0, 3, 0, 0, 1, 0, 0, 0, + 3, 0, 1, 0, 0, 0, 3, 0, + 1, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 3, 3, 0, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 0, 0}; + +static const short _address_eof_trans[] = { + 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, + 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, + 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, + 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, + 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, + 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, + 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, + 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, + 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, + 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, + 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, + 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, + 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, + 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, + 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, + 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, + 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, + 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, + 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, + 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, + 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, + 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, + 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, + 1278, 1279, 1280, 1281, 1282, 1283, 0}; + +static const int address_start = 1; + +bool is_address(const char *p, const char *pe) +{ + int cs = 0; + + const char *eof = pe; + + bool result = false; + + { + cs = (int) address_start; + } + { + int _klen; + unsigned int _trans = 0; + const signed char *_keys; + const signed char *_acts; + unsigned int _nacts; + _resume: { + } + if (p == pe && p != eof) + goto _out; + if (p == eof) { + if (_address_eof_trans[cs] > 0) { + _trans = (unsigned int) _address_eof_trans[cs] - 1; + } + } else { + _keys = (_address_trans_keys + (_address_key_offsets[cs])); + _trans = (unsigned int) _address_index_offsets[cs]; + + _klen = (int) _address_single_lengths[cs]; + if (_klen > 0) { + const signed char *_lower = _keys; + const signed char *_upper = _keys + _klen - 1; + const signed char *_mid; + while (1) { + if (_upper < _lower) { + _keys += _klen; + _trans += (unsigned int) _klen; + break; + } + + _mid = _lower + ((_upper - _lower) >> 1); + if (((*(p))) < (*(_mid))) + _upper = _mid - 1; + else if (((*(p))) > (*(_mid))) + _lower = _mid + 1; + else { + _trans += (unsigned int) (_mid - _keys); + goto _match; + } + } + } + + _klen = (int) _address_range_lengths[cs]; + if (_klen > 0) { + const signed char *_lower = _keys; + const signed char *_upper = _keys + (_klen << 1) - 2; + const signed char *_mid; + while (1) { + if (_upper < _lower) { + _trans += (unsigned int) _klen; + break; + } + + _mid = _lower + (((_upper - _lower) >> 1) & ~1); + if (((*(p))) < (*(_mid))) + _upper = _mid - 2; + else if (((*(p))) > (*(_mid + 1))) + _lower = _mid + 2; + else { + _trans += (unsigned int) ((_mid - _keys) >> 1); + break; + } + } + } + + _match: { + } + } + cs = (int) _address_cond_targs[_trans]; + + if (_address_cond_actions[_trans] != 0) { + + _acts = (_address_actions + (_address_cond_actions[_trans])); + _nacts = (unsigned int) (*(_acts)); + _acts += 1; + while (_nacts > 0) { + switch ((*(_acts))) { + case 0: { + { + result = true; + } + break; + } + case 1: { + { + result = false; + } + break; + } + } + _nacts -= 1; + _acts += 1; + } + } + + if (p == eof) { + if (cs >= 196) + goto _out; + } else { + if (cs != 0) { + p += 1; + goto _resume; + } + } + _out: { + } + } + return result; +} diff --git a/3rdparty/json-schema-validator/src/smtp-address-validator.hpp b/3rdparty/json-schema-validator/src/smtp-address-validator.hpp new file mode 100644 index 0000000000..8d3c12bc98 --- /dev/null +++ b/3rdparty/json-schema-validator/src/smtp-address-validator.hpp @@ -0,0 +1,34 @@ +#ifndef SMTP_ADDRESS_PARSER_HPP_INCLUDED +#define SMTP_ADDRESS_PARSER_HPP_INCLUDED + +/* + +Snarfed from + +: + +Copyright (c) 2021 Gene Hightower + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +bool is_address(const char *p, const char *pe); + +#endif // SMTP_ADDRESS_PARSER_HPP_INCLUDED diff --git a/3rdparty/json-schema-validator/src/string-format-check.cpp b/3rdparty/json-schema-validator/src/string-format-check.cpp new file mode 100644 index 0000000000..ecc428f383 --- /dev/null +++ b/3rdparty/json-schema-validator/src/string-format-check.cpp @@ -0,0 +1,414 @@ +#include + +#include "smtp-address-validator.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef JSON_SCHEMA_BOOST_REGEX +# include +# define REGEX_NAMESPACE boost +#elif defined(JSON_SCHEMA_NO_REGEX) +# define NO_STD_REGEX +#else +# include +# define REGEX_NAMESPACE std +#endif + +/** + * Many of the RegExes are from @see http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + */ + +namespace +{ +template +void range_check(const T value, const T min, const T max) +{ + if (!((value >= min) && (value <= max))) { + std::stringstream out; + out << "Value " << value << " should be in interval [" << min << "," << max << "] but is not!"; + throw std::invalid_argument(out.str()); + } +} + +/** @see date_time_check */ +void rfc3339_date_check(const std::string &value) +{ + const static REGEX_NAMESPACE::regex dateRegex{R"(^([0-9]{4})\-([0-9]{2})\-([0-9]{2})$)"}; + + REGEX_NAMESPACE::smatch matches; + if (!REGEX_NAMESPACE::regex_match(value, matches, dateRegex)) { + throw std::invalid_argument(value + " is not a date string according to RFC 3339."); + } + + const auto year = std::stoi(matches[1].str()); + const auto month = std::stoi(matches[2].str()); + const auto mday = std::stoi(matches[3].str()); + + const auto isLeapYear = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); + + range_check(month, 1, 12); + if (month == 2) { + range_check(mday, 1, isLeapYear ? 29 : 28); + } else if (month <= 7) { + range_check(mday, 1, month % 2 == 0 ? 30 : 31); + } else { + range_check(mday, 1, month % 2 == 0 ? 31 : 30); + } +} + +/** @see date_time_check */ +void rfc3339_time_check(const std::string &value) +{ + const static REGEX_NAMESPACE::regex timeRegex{R"(^([0-9]{2})\:([0-9]{2})\:([0-9]{2})(\.[0-9]+)?(?:[Zz]|((?:\+|\-)[0-9]{2})\:([0-9]{2}))$)"}; + + REGEX_NAMESPACE::smatch matches; + if (!REGEX_NAMESPACE::regex_match(value, matches, timeRegex)) { + throw std::invalid_argument(value + " is not a time string according to RFC 3339."); + } + + auto hour = std::stoi(matches[1].str()); + auto minute = std::stoi(matches[2].str()); + auto second = std::stoi(matches[3].str()); + // const auto secfrac = std::stof( matches[4].str() ); + + range_check(hour, 0, 23); + range_check(minute, 0, 59); + + int offsetHour = 0, + offsetMinute = 0; + + /* don't check the numerical offset if time zone is specified as 'Z' */ + if (!matches[5].str().empty()) { + offsetHour = std::stoi(matches[5].str()); + offsetMinute = std::stoi(matches[6].str()); + + range_check(offsetHour, -23, 23); + range_check(offsetMinute, 0, 59); + if (offsetHour < 0) + offsetMinute *= -1; + } + + /** + * @todo Could be made more exact by querying a leap second database and choosing the + * correct maximum in {58,59,60}. This current solution might match some invalid dates + * but it won't lead to false negatives. This only works if we know the full date, however + */ + + auto day_minutes = hour * 60 + minute - (offsetHour * 60 + offsetMinute); + if (day_minutes < 0) + day_minutes += 60 * 24; + hour = day_minutes % 24; + minute = day_minutes / 24; + + if (hour == 23 && minute == 59) + range_check(second, 0, 60); // possible leap-second + else + range_check(second, 0, 59); +} + +/** + * @see https://tools.ietf.org/html/rfc3339#section-5.6 + * + * @verbatim + * date-fullyear = 4DIGIT + * date-month = 2DIGIT ; 01-12 + * date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on + * ; month/year + * time-hour = 2DIGIT ; 00-23 + * time-minute = 2DIGIT ; 00-59 + * time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second + * ; rules + * time-secfrac = "." 1*DIGIT + * time-numoffset = ("+" / "-") time-hour ":" time-minute + * time-offset = "Z" / time-numoffset + * + * partial-time = time-hour ":" time-minute ":" time-second + * [time-secfrac] + * full-date = date-fullyear "-" date-month "-" date-mday + * full-time = partial-time time-offset + * + * date-time = full-date "T" full-time + * @endverbatim + * NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this + * syntax may alternatively be lower case "t" or "z" respectively. + */ +void rfc3339_date_time_check(const std::string &value) +{ + const static REGEX_NAMESPACE::regex dateTimeRegex{R"(^([0-9]{4}\-[0-9]{2}\-[0-9]{2})[Tt]([0-9]{2}\:[0-9]{2}\:[0-9]{2}(?:\.[0-9]+)?(?:[Zz]|(?:\+|\-)[0-9]{2}\:[0-9]{2}))$)"}; + + REGEX_NAMESPACE::smatch matches; + if (!REGEX_NAMESPACE::regex_match(value, matches, dateTimeRegex)) { + throw std::invalid_argument(value + " is not a date-time string according to RFC 3339."); + } + + rfc3339_date_check(matches[1].str()); + rfc3339_time_check(matches[2].str()); +} + +const std::string decOctet{R"((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))"}; // matches numbers 0-255 +const std::string ipv4Address{"(?:" + decOctet + R"(\.){3})" + decOctet}; +const std::string h16{R"([0-9A-Fa-f]{1,4})"}; +const std::string h16Left{"(?:" + h16 + ":)"}; +const std::string ipv6Address{ + "(?:" + "(?:" + + h16Left + "{6}" + "|::" + + h16Left + "{5}" + "|(?:" + + h16 + ")?::" + h16Left + "{4}" + "|(?:" + + h16Left + "{0,1}" + h16 + ")?::" + h16Left + "{3}" + "|(?:" + + h16Left + "{0,2}" + h16 + ")?::" + h16Left + "{2}" + "|(?:" + + h16Left + "{0,3}" + h16 + ")?::" + h16Left + + "|(?:" + h16Left + "{0,4}" + h16 + ")?::" + ")(?:" + + h16Left + h16 + "|" + ipv4Address + ")" + "|(?:" + + h16Left + "{0,5}" + h16 + ")?::" + h16 + + "|(?:" + h16Left + "{0,6}" + h16 + ")?::" + ")"}; +const std::string ipvFuture{R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)"}; +const std::string regName{R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*)"}; +const std::string host{ + "(?:" + R"(\[(?:)" + + ipv6Address + "|" + ipvFuture + R"()\])" + + "|" + ipv4Address + + "|" + regName + + ")"}; + +const std::string uuid{R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"}; + +// from http://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address +const std::string hostname{R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"}; + +bool is_ascii(std::string const &value) +{ + for (auto ch : value) { + if (ch & 0x80) { + return false; + } + } + return true; +} + +/** + * @see + * + * @verbatim + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + * + * hier-part = "//" authority path-abempty + * / path-absolute + * / path-rootless + * / path-empty + * + * URI-reference = URI / relative-ref + * + * absolute-URI = scheme ":" hier-part [ "?" query ] + * + * relative-ref = relative-part [ "?" query ] [ "#" fragment ] + * + * relative-part = "//" authority path-abempty + * / path-absolute + * / path-noscheme + * / path-empty + * + * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + * + * authority = [ userinfo "@" ] host [ ":" port ] + * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + * host = IP-literal / IPv4address / reg-name + * port = *DIGIT + * + * IP-literal = "[" ( IPv6address / IPvFuture ) "]" + * + * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + * + * IPv6address = 6( h16 ":" ) ls32 + * / "::" 5( h16 ":" ) ls32 + * / [ h16 ] "::" 4( h16 ":" ) ls32 + * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + * / [ *4( h16 ":" ) h16 ] "::" ls32 + * / [ *5( h16 ":" ) h16 ] "::" h16 + * / [ *6( h16 ":" ) h16 ] "::" + * + * h16 = 1*4HEXDIG + * ls32 = ( h16 ":" h16 ) / IPv4address + * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + * dec-octet = DIGIT ; 0-9 + * / %x31-39 DIGIT ; 10-99 + * / "1" 2DIGIT ; 100-199 + * / "2" %x30-34 DIGIT ; 200-249 + * / "25" %x30-35 ; 250-255 + * + * reg-name = *( unreserved / pct-encoded / sub-delims ) + * + * path = path-abempty ; begins with "/" or is empty + * / path-absolute ; begins with "/" but not "//" + * / path-noscheme ; begins with a non-colon segment + * / path-rootless ; begins with a segment + * / path-empty ; zero characters + * + * path-abempty = *( "/" segment ) + * path-absolute = "/" [ segment-nz *( "/" segment ) ] + * path-noscheme = segment-nz-nc *( "/" segment ) + * path-rootless = segment-nz *( "/" segment ) + * path-empty = 0 + * + * segment = *pchar + * segment-nz = 1*pchar + * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) + * ; non-zero-length segment without any colon ":" + * + * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + * + * query = *( pchar / "/" / "?" ) + * + * fragment = *( pchar / "/" / "?" ) + * + * pct-encoded = "%" HEXDIG HEXDIG + * + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * reserved = gen-delims / sub-delims + * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + * + * @endverbatim + * @see adapted from: https://github.com/jhermsmeier/uri.regex/blob/master/uri.regex + * + */ +void rfc3986_uri_check(const std::string &value) +{ + const static std::string scheme{R"(([A-Za-z][A-Za-z0-9+\-.]*):)"}; + const static std::string hierPart{ + R"((?:(\/\/)(?:((?:[A-Za-z0-9\-._~!$&'()*+,;=:]|)" + R"(%[0-9A-Fa-f]{2})*)@)?((?:\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|)" + R"(::(?:[0-9A-Fa-f]{1,4}:){5}|)" + R"((?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|)" + R"((?:(?:25[0-5]|2[0-4][0-9]|)" + R"([01]?[0-9][0-9]?)\.){3}(?:25[0-5]|)" + R"(2[0-4][0-9]|)" + R"([01]?[0-9][0-9]?))|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|)" + R"((?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|)" + R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)\]|)" + R"((?:(?:25[0-5]|)" + R"(2[0-4][0-9]|)" + R"([01]?[0-9][0-9]?)\.){3}(?:25[0-5]|)" + R"(2[0-4][0-9]|)" + R"([01]?[0-9][0-9]?)|)" + R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|)" + R"(%[0-9A-Fa-f]{2})*))(?::([0-9]*))?((?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)" + R"(%[0-9A-Fa-f]{2})*)*)|)" + R"(\/((?:(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)" + R"(%[0-9A-Fa-f]{2})+(?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)" + R"(%[0-9A-Fa-f]{2})*)*)?)|)" + R"(((?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)" + R"(%[0-9A-Fa-f]{2})+(?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)" + R"(%[0-9A-Fa-f]{2})*)*)|))"}; + + const static std::string query{R"((?:\?((?:[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9A-Fa-f]{2})*))?)"}; + const static std::string fragment{ + R"((?:\#((?:[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9A-Fa-f]{2})*))?)"}; + const static std::string uriFormat{scheme + hierPart + query + fragment}; + + const static REGEX_NAMESPACE::regex uriRegex{uriFormat}; + + if (!REGEX_NAMESPACE::regex_match(value, uriRegex)) { + throw std::invalid_argument(value + " is not a URI string according to RFC 3986."); + } +} + +} // namespace + +namespace nlohmann +{ +namespace json_schema +{ +/** + * Checks validity for built-ins by converting the definitions given as ABNF in the linked RFC from + * @see https://json-schema.org/understanding-json-schema/reference/string.html#built-in-formats + * into regular expressions using @see https://www.msweet.org/abnf/ and some manual editing. + * + * @see https://json-schema.org/latest/json-schema-validation.html + */ +void default_string_format_check(const std::string &format, const std::string &value) +{ + if (format == "date-time") { + rfc3339_date_time_check(value); + } else if (format == "date") { + rfc3339_date_check(value); + } else if (format == "time") { + rfc3339_time_check(value); + } else if (format == "uri") { + rfc3986_uri_check(value); + } else if (format == "email") { + if (!is_ascii(value)) { + throw std::invalid_argument(value + " contains non-ASCII values, not RFC 5321 compliant."); + } + if (!is_address(&*value.begin(), &*value.end())) { + throw std::invalid_argument(value + " is not a valid email according to RFC 5321."); + } + } else if (format == "idn-email") { + if (!is_address(&*value.begin(), &*value.end())) { + throw std::invalid_argument(value + " is not a valid idn-email according to RFC 6531."); + } + } else if (format == "hostname") { + static const REGEX_NAMESPACE::regex hostRegex{hostname}; + if (!REGEX_NAMESPACE::regex_match(value, hostRegex)) { + throw std::invalid_argument(value + " is not a valid hostname according to RFC 3986 Appendix A."); + } + } else if (format == "ipv4") { + const static REGEX_NAMESPACE::regex ipv4Regex{"^" + ipv4Address + "$"}; + if (!REGEX_NAMESPACE::regex_match(value, ipv4Regex)) { + throw std::invalid_argument(value + " is not an IPv4 string according to RFC 2673."); + } + } else if (format == "ipv6") { + static const REGEX_NAMESPACE::regex ipv6Regex{ipv6Address}; + if (!REGEX_NAMESPACE::regex_match(value, ipv6Regex)) { + throw std::invalid_argument(value + " is not an IPv6 string according to RFC 5954."); + } + } else if (format == "uuid") { + static const REGEX_NAMESPACE::regex uuidRegex{uuid}; + if (!REGEX_NAMESPACE::regex_match(value, uuidRegex)) { + throw std::invalid_argument(value + " is not an uuid string according to RFC 4122."); + } + } else if (format == "regex") { + try { + REGEX_NAMESPACE::regex re(value, std::regex::ECMAScript); + } catch (std::exception &exception) { + throw exception; + } + } else { + /* yet unsupported JSON schema draft 7 built-ins */ + static const std::vector jsonSchemaStringFormatBuiltIns{ + "date-time", "time", "date", "email", "idn-email", "hostname", "idn-hostname", "ipv4", "ipv6", "uri", + "uri-reference", "iri", "iri-reference", "uri-template", "json-pointer", "relative-json-pointer", "regex"}; + if (std::find(jsonSchemaStringFormatBuiltIns.begin(), jsonSchemaStringFormatBuiltIns.end(), format) != jsonSchemaStringFormatBuiltIns.end()) { + throw std::logic_error("JSON schema string format built-in " + format + " not yet supported. " + + "Please open an issue or use a custom format checker."); + } + + throw std::logic_error("Don't know how to validate " + format); + } +} +} // namespace json_schema +} // namespace nlohmann diff --git a/3rdparty/nlohmann_json/include/nlohmann/json.hpp b/3rdparty/nlohmann_json/include/nlohmann/json.hpp new file mode 100644 index 0000000000..8b72ea6539 --- /dev/null +++ b/3rdparty/nlohmann_json/include/nlohmann/json.hpp @@ -0,0 +1,24765 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file docs/README.md. * +\****************************************************************************/ + +#ifndef INCLUDE_NLOHMANN_JSON_HPP_ +#define INCLUDE_NLOHMANN_JSON_HPP_ + +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO +#include // random_access_iterator_tag +#include // unique_ptr +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // nullptr_t +#include // exception +#if JSON_DIAGNOSTICS + #include // accumulate +#endif +#include // runtime_error +#include // to_string +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // uint8_t +#include // string + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + + +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson +// SPDX-License-Identifier: MIT + +/* Hedley - https://nemequ.github.io/hedley + * Created by Evan Nemerson + */ + +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) +#if defined(JSON_HEDLEY_VERSION) + #undef JSON_HEDLEY_VERSION +#endif +#define JSON_HEDLEY_VERSION 15 + +#if defined(JSON_HEDLEY_STRINGIFY_EX) + #undef JSON_HEDLEY_STRINGIFY_EX +#endif +#define JSON_HEDLEY_STRINGIFY_EX(x) #x + +#if defined(JSON_HEDLEY_STRINGIFY) + #undef JSON_HEDLEY_STRINGIFY +#endif +#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) + +#if defined(JSON_HEDLEY_CONCAT_EX) + #undef JSON_HEDLEY_CONCAT_EX +#endif +#define JSON_HEDLEY_CONCAT_EX(a,b) a##b + +#if defined(JSON_HEDLEY_CONCAT) + #undef JSON_HEDLEY_CONCAT +#endif +#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) + +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + +#if defined(JSON_HEDLEY_VERSION_ENCODE) + #undef JSON_HEDLEY_VERSION_ENCODE +#endif +#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) + #undef JSON_HEDLEY_VERSION_DECODE_MAJOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) + #undef JSON_HEDLEY_VERSION_DECODE_MINOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) + #undef JSON_HEDLEY_VERSION_DECODE_REVISION +#endif +#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) + +#if defined(JSON_HEDLEY_GNUC_VERSION) + #undef JSON_HEDLEY_GNUC_VERSION +#endif +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) + #undef JSON_HEDLEY_GNUC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GNUC_VERSION) + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION) + #undef JSON_HEDLEY_MSVC_VERSION +#endif +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) + #undef JSON_HEDLEY_MSVC_VERSION_CHECK +#endif +#if !defined(JSON_HEDLEY_MSVC_VERSION) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION) + #undef JSON_HEDLEY_INTEL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_VERSION) + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION) + #undef JSON_HEDLEY_PGI_VERSION +#endif +#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) + #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) + #undef JSON_HEDLEY_PGI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PGI_VERSION) + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #undef JSON_HEDLEY_SUNPRO_VERSION +#endif +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) + #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION +#endif +#if defined(__EMSCRIPTEN__) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION) + #undef JSON_HEDLEY_ARM_VERSION +#endif +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) + #undef JSON_HEDLEY_ARM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_ARM_VERSION) + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION) + #undef JSON_HEDLEY_IBM_VERSION +#endif +#if defined(__ibmxl__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) + #undef JSON_HEDLEY_IBM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IBM_VERSION) + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_VERSION) + #undef JSON_HEDLEY_TI_VERSION +#endif +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) + #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif +#endif + +#if defined(JSON_HEDLEY_TI_VERSION_CHECK) + #undef JSON_HEDLEY_TI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_VERSION) + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION) + #undef JSON_HEDLEY_CRAY_VERSION +#endif +#if defined(_CRAYC) + #if defined(_RELEASE_PATCHLEVEL) + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) + #else + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) + #undef JSON_HEDLEY_CRAY_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_CRAY_VERSION) + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION) + #undef JSON_HEDLEY_IAR_VERSION +#endif +#if defined(__IAR_SYSTEMS_ICC__) + #if __VER__ > 1000 + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) + #else + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) + #undef JSON_HEDLEY_IAR_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IAR_VERSION) + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION) + #undef JSON_HEDLEY_TINYC_VERSION +#endif +#if defined(__TINYC__) + #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) + #undef JSON_HEDLEY_TINYC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION) + #undef JSON_HEDLEY_DMC_VERSION +#endif +#if defined(__DMC__) + #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) + #undef JSON_HEDLEY_DMC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_DMC_VERSION) + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #undef JSON_HEDLEY_COMPCERT_VERSION +#endif +#if defined(__COMPCERT_VERSION__) + #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) + #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION) + #undef JSON_HEDLEY_PELLES_VERSION +#endif +#if defined(__POCC__) + #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) + #undef JSON_HEDLEY_PELLES_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PELLES_VERSION) + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION) + #undef JSON_HEDLEY_GCC_VERSION +#endif +#if \ + defined(JSON_HEDLEY_GNUC_VERSION) && \ + !defined(__clang__) && \ + !defined(JSON_HEDLEY_INTEL_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ + !defined(JSON_HEDLEY_TI_VERSION) && \ + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_ATTRIBUTE +#endif +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#else +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE +#endif +#if \ + defined(__has_cpp_attribute) && \ + defined(__cplusplus) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS +#endif +#if !defined(__cplusplus) || !defined(__has_cpp_attribute) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#elif \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ + (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_BUILTIN) + #undef JSON_HEDLEY_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) +#else + #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) + #undef JSON_HEDLEY_GNUC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) + #undef JSON_HEDLEY_GCC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_FEATURE) + #undef JSON_HEDLEY_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) +#else + #define JSON_HEDLEY_HAS_FEATURE(feature) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) + #undef JSON_HEDLEY_GNUC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) + #undef JSON_HEDLEY_GCC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_EXTENSION) + #undef JSON_HEDLEY_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) +#else + #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) + #undef JSON_HEDLEY_GNUC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) + #undef JSON_HEDLEY_GCC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_WARNING) + #undef JSON_HEDLEY_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) +#else + #define JSON_HEDLEY_HAS_WARNING(warning) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) + #undef JSON_HEDLEY_GNUC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_WARNING) + #undef JSON_HEDLEY_GCC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__clang__) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ + (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) + #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_PRAGMA(value) __pragma(value) +#else + #define JSON_HEDLEY_PRAGMA(value) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) + #undef JSON_HEDLEY_DIAGNOSTIC_PUSH +#endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) + #undef JSON_HEDLEY_DIAGNOSTIC_POP +#endif +#if defined(__clang__) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) + #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) +#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_PUSH + #define JSON_HEDLEY_DIAGNOSTIC_POP +#endif + +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + +#if defined(JSON_HEDLEY_DEPRECATED) + #undef JSON_HEDLEY_DEPRECATED +#endif +#if defined(JSON_HEDLEY_DEPRECATED_FOR) + #undef JSON_HEDLEY_DEPRECATED_FOR +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) +#elif \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") +#else + #define JSON_HEDLEY_DEPRECATED(since) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) +#endif + +#if defined(JSON_HEDLEY_UNAVAILABLE) + #undef JSON_HEDLEY_UNAVAILABLE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) +#else + #define JSON_HEDLEY_UNAVAILABLE(available_since) +#endif + +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT +#endif +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) +#elif defined(_Check_return_) /* SAL */ + #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ +#else + #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) +#endif + +#if defined(JSON_HEDLEY_SENTINEL) + #undef JSON_HEDLEY_SENTINEL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) +#else + #define JSON_HEDLEY_SENTINEL(position) +#endif + +#if defined(JSON_HEDLEY_NO_RETURN) + #undef JSON_HEDLEY_NO_RETURN +#endif +#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NO_RETURN __noreturn +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define JSON_HEDLEY_NO_RETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus >= 201103L) + #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#else + #define JSON_HEDLEY_NO_RETURN +#endif + +#if defined(JSON_HEDLEY_NO_ESCAPE) + #undef JSON_HEDLEY_NO_ESCAPE +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) + #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) +#else + #define JSON_HEDLEY_NO_ESCAPE +#endif + +#if defined(JSON_HEDLEY_UNREACHABLE) + #undef JSON_HEDLEY_UNREACHABLE +#endif +#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) + #undef JSON_HEDLEY_UNREACHABLE_RETURN +#endif +#if defined(JSON_HEDLEY_ASSUME) + #undef JSON_HEDLEY_ASSUME +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_ASSUME(expr) __assume(expr) +#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) + #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #if defined(__cplusplus) + #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) + #else + #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) + #endif +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif +#else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif + +JSON_HEDLEY_DIAGNOSTIC_PUSH +#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") + #pragma clang diagnostic ignored "-Wpedantic" +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) + #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif +#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) + #if defined(__clang__) + #pragma clang diagnostic ignored "-Wvariadic-macros" + #elif defined(JSON_HEDLEY_GCC_VERSION) + #pragma GCC diagnostic ignored "-Wvariadic-macros" + #endif +#endif +#if defined(JSON_HEDLEY_NON_NULL) + #undef JSON_HEDLEY_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else + #define JSON_HEDLEY_NON_NULL(...) +#endif +JSON_HEDLEY_DIAGNOSTIC_POP + +#if defined(JSON_HEDLEY_PRINTF_FORMAT) + #undef JSON_HEDLEY_PRINTF_FORMAT +#endif +#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) +#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) +#else + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) +#endif + +#if defined(JSON_HEDLEY_CONSTEXPR) + #undef JSON_HEDLEY_CONSTEXPR +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) + #endif +#endif +#if !defined(JSON_HEDLEY_CONSTEXPR) + #define JSON_HEDLEY_CONSTEXPR +#endif + +#if defined(JSON_HEDLEY_PREDICT) + #undef JSON_HEDLEY_PREDICT +#endif +#if defined(JSON_HEDLEY_LIKELY) + #undef JSON_HEDLEY_LIKELY +#endif +#if defined(JSON_HEDLEY_UNLIKELY) + #undef JSON_HEDLEY_UNLIKELY +#endif +#if defined(JSON_HEDLEY_UNPREDICTABLE) + #undef JSON_HEDLEY_UNPREDICTABLE +#endif +#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) +#elif \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ + })) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ + })) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) +# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) +#endif +#if !defined(JSON_HEDLEY_UNPREDICTABLE) + #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) +#endif + +#if defined(JSON_HEDLEY_MALLOC) + #undef JSON_HEDLEY_MALLOC +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_MALLOC __declspec(restrict) +#else + #define JSON_HEDLEY_MALLOC +#endif + +#if defined(JSON_HEDLEY_PURE) + #undef JSON_HEDLEY_PURE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +#else +# define JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_CONST) + #undef JSON_HEDLEY_CONST +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_CONST __attribute__((__const__)) +#elif \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_CONST _Pragma("no_side_effect") +#else + #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_RESTRICT) + #undef JSON_HEDLEY_RESTRICT +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT restrict +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RESTRICT __restrict +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT _Restrict +#else + #define JSON_HEDLEY_RESTRICT +#endif + +#if defined(JSON_HEDLEY_INLINE) + #undef JSON_HEDLEY_INLINE +#endif +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define JSON_HEDLEY_INLINE inline +#elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) + #define JSON_HEDLEY_INLINE __inline__ +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_INLINE __inline +#else + #define JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_ALWAYS_INLINE) + #undef JSON_HEDLEY_ALWAYS_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +#else +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_NEVER_INLINE) + #undef JSON_HEDLEY_NEVER_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#else + #define JSON_HEDLEY_NEVER_INLINE +#endif + +#if defined(JSON_HEDLEY_PRIVATE) + #undef JSON_HEDLEY_PRIVATE +#endif +#if defined(JSON_HEDLEY_PUBLIC) + #undef JSON_HEDLEY_PUBLIC +#endif +#if defined(JSON_HEDLEY_IMPORT) + #undef JSON_HEDLEY_IMPORT +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) +#else +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern +#endif + +#if defined(JSON_HEDLEY_NO_THROW) + #undef JSON_HEDLEY_NO_THROW +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NO_THROW __declspec(nothrow) +#else + #define JSON_HEDLEY_NO_THROW +#endif + +#if defined(JSON_HEDLEY_FALL_THROUGH) + #undef JSON_HEDLEY_FALL_THROUGH +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) +#elif defined(__fallthrough) /* SAL */ + #define JSON_HEDLEY_FALL_THROUGH __fallthrough +#else + #define JSON_HEDLEY_FALL_THROUGH +#endif + +#if defined(JSON_HEDLEY_RETURNS_NON_NULL) + #undef JSON_HEDLEY_RETURNS_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) +#elif defined(_Ret_notnull_) /* SAL */ + #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ +#else + #define JSON_HEDLEY_RETURNS_NON_NULL +#endif + +#if defined(JSON_HEDLEY_ARRAY_PARAM) + #undef JSON_HEDLEY_ARRAY_PARAM +#endif +#if \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && \ + !defined(__cplusplus) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_ARRAY_PARAM(name) (name) +#else + #define JSON_HEDLEY_ARRAY_PARAM(name) +#endif + +#if defined(JSON_HEDLEY_IS_CONSTANT) + #undef JSON_HEDLEY_IS_CONSTANT +#endif +#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) + #undef JSON_HEDLEY_REQUIRE_CONSTEXPR +#endif +/* JSON_HEDLEY_IS_CONSTEXPR_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #undef JSON_HEDLEY_IS_CONSTEXPR_ +#endif +#if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) +#endif +#if !defined(__cplusplus) +# if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) +#endif +# elif \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) +#endif +# elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + defined(JSON_HEDLEY_INTEL_VERSION) || \ + defined(JSON_HEDLEY_TINYC_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ + defined(__clang__) +# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ + sizeof(void) != \ + sizeof(*( \ + 1 ? \ + ((void*) ((expr) * 0L) ) : \ +((struct { char v[sizeof(void) * 2]; } *) 1) \ + ) \ + ) \ + ) +# endif +#endif +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) +#else + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) (0) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) +#endif + +#if defined(JSON_HEDLEY_BEGIN_C_DECLS) + #undef JSON_HEDLEY_BEGIN_C_DECLS +#endif +#if defined(JSON_HEDLEY_END_C_DECLS) + #undef JSON_HEDLEY_END_C_DECLS +#endif +#if defined(JSON_HEDLEY_C_DECL) + #undef JSON_HEDLEY_C_DECL +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { + #define JSON_HEDLEY_END_C_DECLS } + #define JSON_HEDLEY_C_DECL extern "C" +#else + #define JSON_HEDLEY_BEGIN_C_DECLS + #define JSON_HEDLEY_END_C_DECLS + #define JSON_HEDLEY_C_DECL +#endif + +#if defined(JSON_HEDLEY_STATIC_ASSERT) + #undef JSON_HEDLEY_STATIC_ASSERT +#endif +#if \ + !defined(__cplusplus) && ( \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + defined(_Static_assert) \ + ) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) +#elif \ + (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) +#else +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) +#endif + +#if defined(JSON_HEDLEY_NULL) + #undef JSON_HEDLEY_NULL +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) + #elif defined(NULL) + #define JSON_HEDLEY_NULL NULL + #else + #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) + #endif +#elif defined(NULL) + #define JSON_HEDLEY_NULL NULL +#else + #define JSON_HEDLEY_NULL ((void*) 0) +#endif + +#if defined(JSON_HEDLEY_MESSAGE) + #undef JSON_HEDLEY_MESSAGE +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_MESSAGE(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(message msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) +#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_WARNING) + #undef JSON_HEDLEY_WARNING +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_WARNING(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(clang warning msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_REQUIRE) + #undef JSON_HEDLEY_REQUIRE +#endif +#if defined(JSON_HEDLEY_REQUIRE_MSG) + #undef JSON_HEDLEY_REQUIRE_MSG +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) +# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") +# define JSON_HEDLEY_REQUIRE(expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), #expr, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), msg, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) +# endif +#else +# define JSON_HEDLEY_REQUIRE(expr) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) +#endif + +#if defined(JSON_HEDLEY_FLAGS) + #undef JSON_HEDLEY_FLAGS +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) + #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS +#endif + +#if defined(JSON_HEDLEY_FLAGS_CAST) + #undef JSON_HEDLEY_FLAGS_CAST +#endif +#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) +# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("warning(disable:188)") \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) +#endif + +#if defined(JSON_HEDLEY_EMPTY_BASES) + #undef JSON_HEDLEY_EMPTY_BASES +#endif +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) +#else + #define JSON_HEDLEY_EMPTY_BASES +#endif + +/* Remaining macros are deprecated. */ + +#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK +#endif +#if defined(__clang__) + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) +#else + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) + #undef JSON_HEDLEY_CLANG_HAS_BUILTIN +#endif +#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) + +#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) + #undef JSON_HEDLEY_CLANG_HAS_FEATURE +#endif +#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) + +#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) + #undef JSON_HEDLEY_CLANG_HAS_EXTENSION +#endif +#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) + +#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) + #undef JSON_HEDLEY_CLANG_HAS_WARNING +#endif +#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) + +#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ + + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// #include + + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifndef JSON_HAS_STATIC_RTTI + #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 + #define JSON_HAS_STATIC_RTTI 1 + #else + #define JSON_HAS_STATIC_RTTI 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType, \ + class CustomBaseClass> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif + +#if JSON_HAS_THREE_WAY_COMPARISON + #include // partial_ordering +#endif + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +#if JSON_HAS_THREE_WAY_COMPARISON + inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* +#else + inline bool operator<(const value_t lhs, const value_t rhs) noexcept +#endif +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); +#if JSON_HAS_THREE_WAY_COMPARISON + if (l_index < order.size() && r_index < order.size()) + { + return order[l_index] <=> order[r_index]; // *NOPAD* + } + return std::partial_ordering::unordered; +#else + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +#endif +} + +// GCC selects the built-in operator< over an operator rewritten from +// a user-defined spaceship operator +// Clang, MSVC, and ICC select the rewritten candidate +// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) +#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief replace all occurrences of a substring by another string + +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f + +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** + +@since version 2.0.0 +*/ +template +inline void replace_substring(StringType& s, const StringType& f, + const StringType& t) +{ + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find first occurrence of f + pos != StringType::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find next occurrence of f + {} +} + +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +template +inline StringType escape(StringType s) +{ + replace_substring(s, StringType{"~"}, StringType{"~0"}); + replace_substring(s, StringType{"/"}, StringType{"~1"}); + return s; +} + +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +template +static void unescape(StringType& s) +{ + replace_substring(s, StringType{"~1"}, StringType{"/"}); + replace_substring(s, StringType{"~0"}, StringType{"~"}); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // size_t + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +inline constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#include // tuple +#include // char_traits + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // random_access_iterator_tag + +// #include + +// #include + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector + + // #include + + + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN + + /*! + @brief default JSONSerializer template argument + + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; + + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector, // cppcheck-suppress syntaxError + class CustomBaseClass = void> + class basic_json; + + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; + + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; + + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; + + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; + + NLOHMANN_JSON_NAMESPACE_END + +#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e. those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g. to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +///////////////// +// char_traits // +///////////////// + +// Primary template of char_traits calls std char_traits +template +struct char_traits : std::char_traits +{}; + +// Explicitly define char traits for unsigned char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = unsigned char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(EOF); + } +}; + +// Explicitly define char traits for signed char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = signed char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(EOF); + } +}; + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g. clang 3.5 or gcc 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to using it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template